mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #535 from bunnei/color-modifiers
Implement color/alpha modifiers
This commit is contained in:
		
						commit
						1576a318f2
					
				
					 3 changed files with 103 additions and 73 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue