mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	SWRasterizer: Move texturing functions to their own file
This commit is contained in:
		
							parent
							
								
									f9026e8a7a
								
							
						
					
					
						commit
						1683cb0ec9
					
				
					 4 changed files with 259 additions and 210 deletions
				
			
		|  | @ -17,6 +17,7 @@ set(SRCS | |||
|             swrasterizer/framebuffer.cpp | ||||
|             swrasterizer/rasterizer.cpp | ||||
|             swrasterizer/swrasterizer.cpp | ||||
|             swrasterizer/texturing.cpp | ||||
|             texture/etc1.cpp | ||||
|             texture/texture_decode.cpp | ||||
|             vertex_loader.cpp | ||||
|  | @ -55,6 +56,7 @@ set(HEADERS | |||
|             swrasterizer/framebuffer.h | ||||
|             swrasterizer/rasterizer.h | ||||
|             swrasterizer/swrasterizer.h | ||||
|             swrasterizer/texturing.h | ||||
|             texture/etc1.h | ||||
|             texture/texture_decode.h | ||||
|             utils.h | ||||
|  |  | |||
|  | @ -24,222 +24,13 @@ | |||
| #include "video_core/shader/shader.h" | ||||
| #include "video_core/swrasterizer/framebuffer.h" | ||||
| #include "video_core/swrasterizer/rasterizer.h" | ||||
| #include "video_core/swrasterizer/texturing.h" | ||||
| #include "video_core/texture/texture_decode.h" | ||||
| #include "video_core/utils.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
| namespace Rasterizer { | ||||
| 
 | ||||
| using TevStageConfig = TexturingRegs::TevStageConfig; | ||||
| 
 | ||||
| static int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size) { | ||||
|     switch (mode) { | ||||
|     case TexturingRegs::TextureConfig::ClampToEdge: | ||||
|         val = std::max(val, 0); | ||||
|         val = std::min(val, (int)size - 1); | ||||
|         return val; | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::ClampToBorder: | ||||
|         return val; | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::Repeat: | ||||
|         return (int)((unsigned)val % size); | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::MirroredRepeat: { | ||||
|         unsigned int coord = ((unsigned)val % (2 * size)); | ||||
|         if (coord >= size) | ||||
|             coord = 2 * size - 1 - coord; | ||||
|         return (int)coord; | ||||
|     } | ||||
| 
 | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x", (int)mode); | ||||
|         UNIMPLEMENTED(); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor, | ||||
|                                        const Math::Vec4<u8>& values) { | ||||
|     using ColorModifier = TevStageConfig::ColorModifier; | ||||
| 
 | ||||
|     switch (factor) { | ||||
|     case ColorModifier::SourceColor: | ||||
|         return values.rgb(); | ||||
| 
 | ||||
|     case ColorModifier::OneMinusSourceColor: | ||||
|         return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>(); | ||||
| 
 | ||||
|     case ColorModifier::SourceAlpha: | ||||
|         return values.aaa(); | ||||
| 
 | ||||
|     case ColorModifier::OneMinusSourceAlpha: | ||||
|         return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>(); | ||||
| 
 | ||||
|     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 u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>& values) { | ||||
|     using AlphaModifier = TevStageConfig::AlphaModifier; | ||||
| 
 | ||||
|     switch (factor) { | ||||
|     case AlphaModifier::SourceAlpha: | ||||
|         return values.a(); | ||||
| 
 | ||||
|     case AlphaModifier::OneMinusSourceAlpha: | ||||
|         return 255 - values.a(); | ||||
| 
 | ||||
|     case AlphaModifier::SourceRed: | ||||
|         return values.r(); | ||||
| 
 | ||||
|     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(); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> input[3]) { | ||||
|     using Operation = TevStageConfig::Operation; | ||||
| 
 | ||||
|     switch (op) { | ||||
|     case Operation::Replace: | ||||
|         return input[0]; | ||||
| 
 | ||||
|     case Operation::Modulate: | ||||
|         return ((input[0] * input[1]) / 255).Cast<u8>(); | ||||
| 
 | ||||
|     case Operation::Add: { | ||||
|         auto result = input[0] + input[1]; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::AddSigned: { | ||||
|         // TODO(bunnei): Verify that the color conversion from (float) 0.5f to
 | ||||
|         // (byte) 128 is correct
 | ||||
|         auto result = | ||||
|             input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128); | ||||
|         result.r() = MathUtil::Clamp<int>(result.r(), 0, 255); | ||||
|         result.g() = MathUtil::Clamp<int>(result.g(), 0, 255); | ||||
|         result.b() = MathUtil::Clamp<int>(result.b(), 0, 255); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::Lerp: | ||||
|         return ((input[0] * input[2] + | ||||
|                  input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / | ||||
|                 255) | ||||
|             .Cast<u8>(); | ||||
| 
 | ||||
|     case Operation::Subtract: { | ||||
|         auto result = input[0].Cast<int>() - input[1].Cast<int>(); | ||||
|         result.r() = std::max(0, result.r()); | ||||
|         result.g() = std::max(0, result.g()); | ||||
|         result.b() = std::max(0, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::MultiplyThenAdd: { | ||||
|         auto result = (input[0] * input[1] + 255 * input[2].Cast<int>()) / 255; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::AddThenMultiply: { | ||||
|         auto result = input[0] + input[1]; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         result = (result * input[2].Cast<int>()) / 255; | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
|     case Operation::Dot3_RGB: { | ||||
|         // Not fully accurate.  Worst case scenario seems to yield a +/-3 error.  Some HW results
 | ||||
|         // indicate that the per-component computation can't have a higher precision than 1/256,
 | ||||
|         // while dot3_rgb((0x80,g0,b0), (0x7F,g1,b1)) and dot3_rgb((0x80,g0,b0), (0x80,g1,b1)) give
 | ||||
|         // different results.
 | ||||
|         int result = ((input[0].r() * 2 - 255) * (input[1].r() * 2 - 255) + 128) / 256 + | ||||
|                      ((input[0].g() * 2 - 255) * (input[1].g() * 2 - 255) + 128) / 256 + | ||||
|                      ((input[0].b() * 2 - 255) * (input[1].b() * 2 - 255) + 128) / 256; | ||||
|         result = std::max(0, std::min(255, result)); | ||||
|         return {(u8)result, (u8)result, (u8)result}; | ||||
|     } | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown color combiner operation %d", (int)op); | ||||
|         UNIMPLEMENTED(); | ||||
|         return {0, 0, 0}; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static u8 AlphaCombine(TevStageConfig::Operation op, const std::array<u8, 3>& input) { | ||||
|     switch (op) { | ||||
|         using Operation = TevStageConfig::Operation; | ||||
|     case Operation::Replace: | ||||
|         return input[0]; | ||||
| 
 | ||||
|     case Operation::Modulate: | ||||
|         return input[0] * input[1] / 255; | ||||
| 
 | ||||
|     case Operation::Add: | ||||
|         return std::min(255, input[0] + input[1]); | ||||
| 
 | ||||
|     case Operation::AddSigned: { | ||||
|         // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct
 | ||||
|         auto result = static_cast<int>(input[0]) + static_cast<int>(input[1]) - 128; | ||||
|         return static_cast<u8>(MathUtil::Clamp<int>(result, 0, 255)); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::Lerp: | ||||
|         return (input[0] * input[2] + input[1] * (255 - input[2])) / 255; | ||||
| 
 | ||||
|     case Operation::Subtract: | ||||
|         return std::max(0, (int)input[0] - (int)input[1]); | ||||
| 
 | ||||
|     case Operation::MultiplyThenAdd: | ||||
|         return std::min(255, (input[0] * input[1] + 255 * input[2]) / 255); | ||||
| 
 | ||||
|     case Operation::AddThenMultiply: | ||||
|         return (std::min(255, (input[0] + input[1])) * input[2]) / 255; | ||||
| 
 | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d", (int)op); | ||||
|         UNIMPLEMENTED(); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, | ||||
|                                             const Math::Vec4<u8>& srcfactor, | ||||
|                                             const Math::Vec4<u8>& dest, | ||||
|  |  | |||
							
								
								
									
										228
									
								
								src/video_core/swrasterizer/texturing.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								src/video_core/swrasterizer/texturing.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,228 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <algorithm> | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/math_util.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "video_core/regs_texturing.h" | ||||
| #include "video_core/swrasterizer/texturing.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
| namespace Rasterizer { | ||||
| 
 | ||||
| using TevStageConfig = TexturingRegs::TevStageConfig; | ||||
| 
 | ||||
| int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size) { | ||||
|     switch (mode) { | ||||
|     case TexturingRegs::TextureConfig::ClampToEdge: | ||||
|         val = std::max(val, 0); | ||||
|         val = std::min(val, (int)size - 1); | ||||
|         return val; | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::ClampToBorder: | ||||
|         return val; | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::Repeat: | ||||
|         return (int)((unsigned)val % size); | ||||
| 
 | ||||
|     case TexturingRegs::TextureConfig::MirroredRepeat: { | ||||
|         unsigned int coord = ((unsigned)val % (2 * size)); | ||||
|         if (coord >= size) | ||||
|             coord = 2 * size - 1 - coord; | ||||
|         return (int)coord; | ||||
|     } | ||||
| 
 | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x", (int)mode); | ||||
|         UNIMPLEMENTED(); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor, | ||||
|                                 const Math::Vec4<u8>& values) { | ||||
|     using ColorModifier = TevStageConfig::ColorModifier; | ||||
| 
 | ||||
|     switch (factor) { | ||||
|     case ColorModifier::SourceColor: | ||||
|         return values.rgb(); | ||||
| 
 | ||||
|     case ColorModifier::OneMinusSourceColor: | ||||
|         return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>(); | ||||
| 
 | ||||
|     case ColorModifier::SourceAlpha: | ||||
|         return values.aaa(); | ||||
| 
 | ||||
|     case ColorModifier::OneMinusSourceAlpha: | ||||
|         return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>(); | ||||
| 
 | ||||
|     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>(); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>& values) { | ||||
|     using AlphaModifier = TevStageConfig::AlphaModifier; | ||||
| 
 | ||||
|     switch (factor) { | ||||
|     case AlphaModifier::SourceAlpha: | ||||
|         return values.a(); | ||||
| 
 | ||||
|     case AlphaModifier::OneMinusSourceAlpha: | ||||
|         return 255 - values.a(); | ||||
| 
 | ||||
|     case AlphaModifier::SourceRed: | ||||
|         return values.r(); | ||||
| 
 | ||||
|     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(); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> input[3]) { | ||||
|     using Operation = TevStageConfig::Operation; | ||||
| 
 | ||||
|     switch (op) { | ||||
|     case Operation::Replace: | ||||
|         return input[0]; | ||||
| 
 | ||||
|     case Operation::Modulate: | ||||
|         return ((input[0] * input[1]) / 255).Cast<u8>(); | ||||
| 
 | ||||
|     case Operation::Add: { | ||||
|         auto result = input[0] + input[1]; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::AddSigned: { | ||||
|         // TODO(bunnei): Verify that the color conversion from (float) 0.5f to
 | ||||
|         // (byte) 128 is correct
 | ||||
|         auto result = | ||||
|             input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128); | ||||
|         result.r() = MathUtil::Clamp<int>(result.r(), 0, 255); | ||||
|         result.g() = MathUtil::Clamp<int>(result.g(), 0, 255); | ||||
|         result.b() = MathUtil::Clamp<int>(result.b(), 0, 255); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::Lerp: | ||||
|         return ((input[0] * input[2] + | ||||
|                  input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / | ||||
|                 255) | ||||
|             .Cast<u8>(); | ||||
| 
 | ||||
|     case Operation::Subtract: { | ||||
|         auto result = input[0].Cast<int>() - input[1].Cast<int>(); | ||||
|         result.r() = std::max(0, result.r()); | ||||
|         result.g() = std::max(0, result.g()); | ||||
|         result.b() = std::max(0, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::MultiplyThenAdd: { | ||||
|         auto result = (input[0] * input[1] + 255 * input[2].Cast<int>()) / 255; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::AddThenMultiply: { | ||||
|         auto result = input[0] + input[1]; | ||||
|         result.r() = std::min(255, result.r()); | ||||
|         result.g() = std::min(255, result.g()); | ||||
|         result.b() = std::min(255, result.b()); | ||||
|         result = (result * input[2].Cast<int>()) / 255; | ||||
|         return result.Cast<u8>(); | ||||
|     } | ||||
|     case Operation::Dot3_RGB: { | ||||
|         // Not fully accurate.  Worst case scenario seems to yield a +/-3 error.  Some HW results
 | ||||
|         // indicate that the per-component computation can't have a higher precision than 1/256,
 | ||||
|         // while dot3_rgb((0x80,g0,b0), (0x7F,g1,b1)) and dot3_rgb((0x80,g0,b0), (0x80,g1,b1)) give
 | ||||
|         // different results.
 | ||||
|         int result = ((input[0].r() * 2 - 255) * (input[1].r() * 2 - 255) + 128) / 256 + | ||||
|                      ((input[0].g() * 2 - 255) * (input[1].g() * 2 - 255) + 128) / 256 + | ||||
|                      ((input[0].b() * 2 - 255) * (input[1].b() * 2 - 255) + 128) / 256; | ||||
|         result = std::max(0, std::min(255, result)); | ||||
|         return {(u8)result, (u8)result, (u8)result}; | ||||
|     } | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown color combiner operation %d", (int)op); | ||||
|         UNIMPLEMENTED(); | ||||
|         return {0, 0, 0}; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| u8 AlphaCombine(TevStageConfig::Operation op, const std::array<u8, 3>& input) { | ||||
|     switch (op) { | ||||
|         using Operation = TevStageConfig::Operation; | ||||
|     case Operation::Replace: | ||||
|         return input[0]; | ||||
| 
 | ||||
|     case Operation::Modulate: | ||||
|         return input[0] * input[1] / 255; | ||||
| 
 | ||||
|     case Operation::Add: | ||||
|         return std::min(255, input[0] + input[1]); | ||||
| 
 | ||||
|     case Operation::AddSigned: { | ||||
|         // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct
 | ||||
|         auto result = static_cast<int>(input[0]) + static_cast<int>(input[1]) - 128; | ||||
|         return static_cast<u8>(MathUtil::Clamp<int>(result, 0, 255)); | ||||
|     } | ||||
| 
 | ||||
|     case Operation::Lerp: | ||||
|         return (input[0] * input[2] + input[1] * (255 - input[2])) / 255; | ||||
| 
 | ||||
|     case Operation::Subtract: | ||||
|         return std::max(0, (int)input[0] - (int)input[1]); | ||||
| 
 | ||||
|     case Operation::MultiplyThenAdd: | ||||
|         return std::min(255, (input[0] * input[1] + 255 * input[2]) / 255); | ||||
| 
 | ||||
|     case Operation::AddThenMultiply: | ||||
|         return (std::min(255, (input[0] + input[1])) * input[2]) / 255; | ||||
| 
 | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d", (int)op); | ||||
|         UNIMPLEMENTED(); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } // namespace Rasterizer
 | ||||
| } // namespace Pica
 | ||||
							
								
								
									
										28
									
								
								src/video_core/swrasterizer/texturing.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/video_core/swrasterizer/texturing.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "video_core/regs_texturing.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
| namespace Rasterizer { | ||||
| 
 | ||||
| int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size); | ||||
| 
 | ||||
| Math::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor, | ||||
|                                 const Math::Vec4<u8>& values); | ||||
| 
 | ||||
| u8 GetAlphaModifier(TexturingRegs::TevStageConfig::AlphaModifier factor, | ||||
|                     const Math::Vec4<u8>& values); | ||||
| 
 | ||||
| Math::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op, | ||||
|                             const Math::Vec3<u8> input[3]); | ||||
| 
 | ||||
| u8 AlphaCombine(TexturingRegs::TevStageConfig::Operation op, const std::array<u8, 3>& input); | ||||
| 
 | ||||
| } // namespace Rasterizer
 | ||||
| } // namespace Pica
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue