mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #535 from bunnei/color-modifiers
Implement color/alpha modifiers
This commit is contained in:
		
						commit
						1576a318f2
					
				@ -457,27 +457,41 @@ public:
 | 
				
			|||||||
    const T& b() const { return z; }
 | 
					    const T& b() const { return z; }
 | 
				
			||||||
    const T& a() const { return w; }
 | 
					    const T& a() const { return w; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // swizzlers - create a subvector of specific components
 | 
					    // Swizzlers - Create a subvector of specific components
 | 
				
			||||||
    // e.g. Vec2 uv() { return Vec2(x,y); }
 | 
					    // e.g. Vec2 uv() { return Vec2(x,y); }
 | 
				
			||||||
    // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx)
 | 
					
 | 
				
			||||||
 | 
					    // _DEFINE_SWIZZLER2 defines a single such function
 | 
				
			||||||
 | 
					    // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) 
 | 
				
			||||||
 | 
					    // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx)
 | 
				
			||||||
#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); }
 | 
					#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); }
 | 
				
			||||||
#define DEFINE_SWIZZLER2(a, b, a2, b2) \
 | 
					#define DEFINE_SWIZZLER2_COMP1(a, a2) \
 | 
				
			||||||
 | 
					    _DEFINE_SWIZZLER2(a, a, a##a); \
 | 
				
			||||||
 | 
					    _DEFINE_SWIZZLER2(a, a, a2##a2)
 | 
				
			||||||
 | 
					#define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \
 | 
				
			||||||
    _DEFINE_SWIZZLER2(a, b, a##b); \
 | 
					    _DEFINE_SWIZZLER2(a, b, a##b); \
 | 
				
			||||||
    _DEFINE_SWIZZLER2(a, b, a2##b2); \
 | 
					    _DEFINE_SWIZZLER2(a, b, a2##b2); \
 | 
				
			||||||
    _DEFINE_SWIZZLER2(b, a, b##a); \
 | 
					    _DEFINE_SWIZZLER2(b, a, b##a); \
 | 
				
			||||||
    _DEFINE_SWIZZLER2(b, a, b2##a2)
 | 
					    _DEFINE_SWIZZLER2(b, a, b2##a2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DEFINE_SWIZZLER2(x, y, r, g);
 | 
					    DEFINE_SWIZZLER2_COMP2(x, y, r, g);
 | 
				
			||||||
    DEFINE_SWIZZLER2(x, z, r, b);
 | 
					    DEFINE_SWIZZLER2_COMP2(x, z, r, b);
 | 
				
			||||||
    DEFINE_SWIZZLER2(x, w, r, a);
 | 
					    DEFINE_SWIZZLER2_COMP2(x, w, r, a);
 | 
				
			||||||
    DEFINE_SWIZZLER2(y, z, g, b);
 | 
					    DEFINE_SWIZZLER2_COMP2(y, z, g, b);
 | 
				
			||||||
    DEFINE_SWIZZLER2(y, w, g, a);
 | 
					    DEFINE_SWIZZLER2_COMP2(y, w, g, a);
 | 
				
			||||||
    DEFINE_SWIZZLER2(z, w, b, a);
 | 
					    DEFINE_SWIZZLER2_COMP2(z, w, b, a);
 | 
				
			||||||
#undef DEFINE_SWIZZLER2
 | 
					    DEFINE_SWIZZLER2_COMP1(x, r);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER2_COMP1(y, g);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER2_COMP1(z, b);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER2_COMP1(w, a);
 | 
				
			||||||
 | 
					#undef DEFINE_SWIZZLER2_COMP1
 | 
				
			||||||
 | 
					#undef DEFINE_SWIZZLER2_COMP2
 | 
				
			||||||
#undef _DEFINE_SWIZZLER2
 | 
					#undef _DEFINE_SWIZZLER2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); }
 | 
					#define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); }
 | 
				
			||||||
#define DEFINE_SWIZZLER3(a, b, c, a2, b2, c2) \
 | 
					#define DEFINE_SWIZZLER3_COMP1(a, a2) \
 | 
				
			||||||
 | 
					    _DEFINE_SWIZZLER3(a, a, a, a##a##a); \
 | 
				
			||||||
 | 
					    _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
 | 
				
			||||||
 | 
					#define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \
 | 
				
			||||||
    _DEFINE_SWIZZLER3(a, b, c, a##b##c); \
 | 
					    _DEFINE_SWIZZLER3(a, b, c, a##b##c); \
 | 
				
			||||||
    _DEFINE_SWIZZLER3(a, c, b, a##c##b); \
 | 
					    _DEFINE_SWIZZLER3(a, c, b, a##c##b); \
 | 
				
			||||||
    _DEFINE_SWIZZLER3(b, a, c, b##a##c); \
 | 
					    _DEFINE_SWIZZLER3(b, a, c, b##a##c); \
 | 
				
			||||||
@ -491,11 +505,16 @@ public:
 | 
				
			|||||||
    _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \
 | 
					    _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \
 | 
				
			||||||
    _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2)
 | 
					    _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DEFINE_SWIZZLER3(x, y, z, r, g, b);
 | 
					    DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b);
 | 
				
			||||||
    DEFINE_SWIZZLER3(x, y, w, r, g, a);
 | 
					    DEFINE_SWIZZLER3_COMP3(x, y, w, r, g, a);
 | 
				
			||||||
    DEFINE_SWIZZLER3(x, z, w, r, b, a);
 | 
					    DEFINE_SWIZZLER3_COMP3(x, z, w, r, b, a);
 | 
				
			||||||
    DEFINE_SWIZZLER3(y, z, w, g, b, a);
 | 
					    DEFINE_SWIZZLER3_COMP3(y, z, w, g, b, a);
 | 
				
			||||||
#undef DEFINE_SWIZZLER3
 | 
					    DEFINE_SWIZZLER3_COMP1(x, r);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER3_COMP1(y, g);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER3_COMP1(z, b);
 | 
				
			||||||
 | 
					    DEFINE_SWIZZLER3_COMP1(w, a);
 | 
				
			||||||
 | 
					#undef DEFINE_SWIZZLER3_COMP1
 | 
				
			||||||
 | 
					#undef DEFINE_SWIZZLER3_COMP3
 | 
				
			||||||
#undef _DEFINE_SWIZZLER3
 | 
					#undef _DEFINE_SWIZZLER3
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -233,19 +233,29 @@ struct Regs {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        enum class ColorModifier : u32 {
 | 
					        enum class ColorModifier : u32 {
 | 
				
			||||||
            SourceColor         = 0,
 | 
					            SourceColor         = 0x0,
 | 
				
			||||||
            OneMinusSourceColor = 1,
 | 
					            OneMinusSourceColor = 0x1,
 | 
				
			||||||
            SourceAlpha         = 2,
 | 
					            SourceAlpha         = 0x2,
 | 
				
			||||||
            OneMinusSourceAlpha = 3,
 | 
					            OneMinusSourceAlpha = 0x3,
 | 
				
			||||||
 | 
					            SourceRed           = 0x4,
 | 
				
			||||||
 | 
					            OneMinusSourceRed   = 0x5,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Other values seem to be non-standard extensions
 | 
					            SourceGreen         = 0x8,
 | 
				
			||||||
 | 
					            OneMinusSourceGreen = 0x9,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SourceBlue          = 0xc,
 | 
				
			||||||
 | 
					            OneMinusSourceBlue  = 0xd,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        enum class AlphaModifier : u32 {
 | 
					        enum class AlphaModifier : u32 {
 | 
				
			||||||
            SourceAlpha         = 0,
 | 
					            SourceAlpha         = 0x0,
 | 
				
			||||||
            OneMinusSourceAlpha = 1,
 | 
					            OneMinusSourceAlpha = 0x1,
 | 
				
			||||||
 | 
					            SourceRed           = 0x2,
 | 
				
			||||||
            // Other values seem to be non-standard extensions
 | 
					            OneMinusSourceRed   = 0x3,
 | 
				
			||||||
 | 
					            SourceGreen         = 0x4,
 | 
				
			||||||
 | 
					            OneMinusSourceGreen = 0x5,
 | 
				
			||||||
 | 
					            SourceBlue          = 0x6,
 | 
				
			||||||
 | 
					            OneMinusSourceBlue  = 0x7,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        enum class Operation : u32 {
 | 
					        enum class Operation : u32 {
 | 
				
			||||||
 | 
				
			|||||||
@ -260,7 +260,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
                using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
 | 
					                using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
 | 
				
			||||||
                using Operation = Regs::TevStageConfig::Operation;
 | 
					                using Operation = Regs::TevStageConfig::Operation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto GetColorSource = [&](Source source) -> Math::Vec4<u8> {
 | 
					                auto GetSource = [&](Source source) -> Math::Vec4<u8> {
 | 
				
			||||||
                    switch (source) {
 | 
					                    switch (source) {
 | 
				
			||||||
                    case Source::PrimaryColor:
 | 
					                    case Source::PrimaryColor:
 | 
				
			||||||
                        return primary_color;
 | 
					                        return primary_color;
 | 
				
			||||||
@ -287,36 +287,8 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto GetAlphaSource = [&](Source source) -> u8 {
 | 
					 | 
				
			||||||
                    switch (source) {
 | 
					 | 
				
			||||||
                    case Source::PrimaryColor:
 | 
					 | 
				
			||||||
                        return primary_color.a();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case Source::Texture0:
 | 
					 | 
				
			||||||
                        return texture_color[0].a();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case Source::Texture1:
 | 
					 | 
				
			||||||
                        return texture_color[1].a();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case Source::Texture2:
 | 
					 | 
				
			||||||
                        return texture_color[2].a();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case Source::Constant:
 | 
					 | 
				
			||||||
                        return tev_stage.const_a;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case Source::Previous:
 | 
					 | 
				
			||||||
                        return combiner_output.a();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    default:
 | 
					 | 
				
			||||||
                        LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source);
 | 
					 | 
				
			||||||
                        _dbg_assert_(HW_GPU, 0);
 | 
					 | 
				
			||||||
                        return 0;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> {
 | 
					                static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> {
 | 
				
			||||||
                    switch (factor)
 | 
					                    switch (factor) {
 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                    case ColorModifier::SourceColor:
 | 
					                    case ColorModifier::SourceColor:
 | 
				
			||||||
                        return values.rgb();
 | 
					                        return values.rgb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -324,27 +296,56 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
                        return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
 | 
					                        return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    case ColorModifier::SourceAlpha:
 | 
					                    case ColorModifier::SourceAlpha:
 | 
				
			||||||
                        return { values.a(), values.a(), values.a() };
 | 
					                        return values.aaa();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    default:
 | 
					                    case ColorModifier::OneMinusSourceAlpha:
 | 
				
			||||||
                        LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor);
 | 
					                        return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
 | 
				
			||||||
                        _dbg_assert_(HW_GPU, 0);
 | 
					
 | 
				
			||||||
                        return {};
 | 
					                    case ColorModifier::SourceRed:
 | 
				
			||||||
 | 
					                        return values.rrr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case ColorModifier::OneMinusSourceRed:
 | 
				
			||||||
 | 
					                        return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case ColorModifier::SourceGreen:
 | 
				
			||||||
 | 
					                        return values.ggg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case ColorModifier::OneMinusSourceGreen:
 | 
				
			||||||
 | 
					                        return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case ColorModifier::SourceBlue:
 | 
				
			||||||
 | 
					                        return values.bbb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case ColorModifier::OneMinusSourceBlue:
 | 
				
			||||||
 | 
					                        return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                static auto GetAlphaModifier = [](AlphaModifier factor, u8 value) -> u8 {
 | 
					                static auto GetAlphaModifier = [](AlphaModifier factor, const Math::Vec4<u8>& values) -> u8 {
 | 
				
			||||||
                    switch (factor) {
 | 
					                    switch (factor) {
 | 
				
			||||||
                    case AlphaModifier::SourceAlpha:
 | 
					                    case AlphaModifier::SourceAlpha:
 | 
				
			||||||
                        return value;
 | 
					                        return values.a();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    case AlphaModifier::OneMinusSourceAlpha:
 | 
					                    case AlphaModifier::OneMinusSourceAlpha:
 | 
				
			||||||
                        return 255 - value;
 | 
					                        return 255 - values.a();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    default:
 | 
					                    case AlphaModifier::SourceRed:
 | 
				
			||||||
                        LOG_ERROR(HW_GPU, "Unknown alpha factor %d\n", (int)factor);
 | 
					                        return values.r();
 | 
				
			||||||
                        _dbg_assert_(HW_GPU, 0);
 | 
					
 | 
				
			||||||
                        return 0;
 | 
					                    case AlphaModifier::OneMinusSourceRed:
 | 
				
			||||||
 | 
					                        return 255 - values.r();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case AlphaModifier::SourceGreen:
 | 
				
			||||||
 | 
					                        return values.g();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case AlphaModifier::OneMinusSourceGreen:
 | 
				
			||||||
 | 
					                        return 255 - values.g();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case AlphaModifier::SourceBlue:
 | 
				
			||||||
 | 
					                        return values.b();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case AlphaModifier::OneMinusSourceBlue:
 | 
				
			||||||
 | 
					                        return 255 - values.b();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -414,17 +415,17 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
                //       combiner_output.rgb(), but instead store it in a temporary variable until
 | 
					                //       combiner_output.rgb(), but instead store it in a temporary variable until
 | 
				
			||||||
                //       alpha combining has been done.
 | 
					                //       alpha combining has been done.
 | 
				
			||||||
                Math::Vec3<u8> color_result[3] = {
 | 
					                Math::Vec3<u8> color_result[3] = {
 | 
				
			||||||
                    GetColorModifier(tev_stage.color_modifier1, GetColorSource(tev_stage.color_source1)),
 | 
					                    GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)),
 | 
				
			||||||
                    GetColorModifier(tev_stage.color_modifier2, GetColorSource(tev_stage.color_source2)),
 | 
					                    GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)),
 | 
				
			||||||
                    GetColorModifier(tev_stage.color_modifier3, GetColorSource(tev_stage.color_source3))
 | 
					                    GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3))
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                auto color_output = ColorCombine(tev_stage.color_op, color_result);
 | 
					                auto color_output = ColorCombine(tev_stage.color_op, color_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // alpha combiner
 | 
					                // alpha combiner
 | 
				
			||||||
                std::array<u8,3> alpha_result = {
 | 
					                std::array<u8,3> alpha_result = {
 | 
				
			||||||
                    GetAlphaModifier(tev_stage.alpha_modifier1, GetAlphaSource(tev_stage.alpha_source1)),
 | 
					                    GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)),
 | 
				
			||||||
                    GetAlphaModifier(tev_stage.alpha_modifier2, GetAlphaSource(tev_stage.alpha_source2)),
 | 
					                    GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)),
 | 
				
			||||||
                    GetAlphaModifier(tev_stage.alpha_modifier3, GetAlphaSource(tev_stage.alpha_source3))
 | 
					                    GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3))
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result);
 | 
					                auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user