mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	SWRasterizer: Move more framebuffer functions to file
This commit is contained in:
		
							parent
							
								
									1683cb0ec9
								
							
						
					
					
						commit
						426fda1d52
					
				
					 3 changed files with 105 additions and 100 deletions
				
			
		|  | @ -8,6 +8,7 @@ | |||
| #include "common/color.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/math_util.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hw/gpu.h" | ||||
| #include "core/memory.h" | ||||
|  | @ -255,5 +256,103 @@ u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u | |||
|     } | ||||
| } | ||||
| 
 | ||||
| Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, | ||||
|                                      const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor, | ||||
|                                      FramebufferRegs::BlendEquation equation) { | ||||
|     Math::Vec4<int> result; | ||||
| 
 | ||||
|     auto src_result = (src * srcfactor).Cast<int>(); | ||||
|     auto dst_result = (dest * destfactor).Cast<int>(); | ||||
| 
 | ||||
|     switch (equation) { | ||||
|     case FramebufferRegs::BlendEquation::Add: | ||||
|         result = (src_result + dst_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::Subtract: | ||||
|         result = (src_result - dst_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::ReverseSubtract: | ||||
|         result = (dst_result - src_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     // TODO: How do these two actually work?  OpenGL doesn't include the blend factors in the
 | ||||
|     //       min/max computations, but is this what the 3DS actually does?
 | ||||
|     case FramebufferRegs::BlendEquation::Min: | ||||
|         result.r() = std::min(src.r(), dest.r()); | ||||
|         result.g() = std::min(src.g(), dest.g()); | ||||
|         result.b() = std::min(src.b(), dest.b()); | ||||
|         result.a() = std::min(src.a(), dest.a()); | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::Max: | ||||
|         result.r() = std::max(src.r(), dest.r()); | ||||
|         result.g() = std::max(src.g(), dest.g()); | ||||
|         result.b() = std::max(src.b(), dest.b()); | ||||
|         result.a() = std::max(src.a(), dest.a()); | ||||
|         break; | ||||
| 
 | ||||
|     default: | ||||
|         LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", equation); | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| 
 | ||||
|     return Math::Vec4<u8>(MathUtil::Clamp(result.r(), 0, 255), MathUtil::Clamp(result.g(), 0, 255), | ||||
|                           MathUtil::Clamp(result.b(), 0, 255), MathUtil::Clamp(result.a(), 0, 255)); | ||||
| }; | ||||
| 
 | ||||
| u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) { | ||||
|     switch (op) { | ||||
|     case FramebufferRegs::LogicOp::Clear: | ||||
|         return 0; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::And: | ||||
|         return src & dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::AndReverse: | ||||
|         return src & ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Copy: | ||||
|         return src; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Set: | ||||
|         return 255; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::CopyInverted: | ||||
|         return ~src; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::NoOp: | ||||
|         return dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Invert: | ||||
|         return ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Nand: | ||||
|         return ~(src & dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Or: | ||||
|         return src | dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Nor: | ||||
|         return ~(src | dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Xor: | ||||
|         return src ^ dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Equiv: | ||||
|         return ~(src ^ dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::AndInverted: | ||||
|         return ~src & dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::OrReverse: | ||||
|         return src | ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::OrInverted: | ||||
|         return ~src | dest; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } // namespace Rasterizer
 | ||||
| } // namespace Pica
 | ||||
|  |  | |||
|  | @ -19,5 +19,11 @@ void SetDepth(int x, int y, u32 value); | |||
| void SetStencil(int x, int y, u8 value); | ||||
| u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref); | ||||
| 
 | ||||
| Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, | ||||
|                                      const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor, | ||||
|                                      FramebufferRegs::BlendEquation equation); | ||||
| 
 | ||||
| u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op); | ||||
| 
 | ||||
| } // namespace Rasterizer
 | ||||
| } // namespace Pica
 | ||||
|  |  | |||
|  | @ -31,106 +31,6 @@ | |||
| namespace Pica { | ||||
| namespace Rasterizer { | ||||
| 
 | ||||
| static Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, | ||||
|                                             const Math::Vec4<u8>& srcfactor, | ||||
|                                             const Math::Vec4<u8>& dest, | ||||
|                                             const Math::Vec4<u8>& destfactor, | ||||
|                                             FramebufferRegs::BlendEquation equation) { | ||||
|     Math::Vec4<int> result; | ||||
| 
 | ||||
|     auto src_result = (src * srcfactor).Cast<int>(); | ||||
|     auto dst_result = (dest * destfactor).Cast<int>(); | ||||
| 
 | ||||
|     switch (equation) { | ||||
|     case FramebufferRegs::BlendEquation::Add: | ||||
|         result = (src_result + dst_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::Subtract: | ||||
|         result = (src_result - dst_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::ReverseSubtract: | ||||
|         result = (dst_result - src_result) / 255; | ||||
|         break; | ||||
| 
 | ||||
|     // TODO: How do these two actually work?  OpenGL doesn't include the blend factors in the
 | ||||
|     //       min/max computations, but is this what the 3DS actually does?
 | ||||
|     case FramebufferRegs::BlendEquation::Min: | ||||
|         result.r() = std::min(src.r(), dest.r()); | ||||
|         result.g() = std::min(src.g(), dest.g()); | ||||
|         result.b() = std::min(src.b(), dest.b()); | ||||
|         result.a() = std::min(src.a(), dest.a()); | ||||
|         break; | ||||
| 
 | ||||
|     case FramebufferRegs::BlendEquation::Max: | ||||
|         result.r() = std::max(src.r(), dest.r()); | ||||
|         result.g() = std::max(src.g(), dest.g()); | ||||
|         result.b() = std::max(src.b(), dest.b()); | ||||
|         result.a() = std::max(src.a(), dest.a()); | ||||
|         break; | ||||
| 
 | ||||
|     default: | ||||
|         LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", equation); | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| 
 | ||||
|     return Math::Vec4<u8>(MathUtil::Clamp(result.r(), 0, 255), MathUtil::Clamp(result.g(), 0, 255), | ||||
|                           MathUtil::Clamp(result.b(), 0, 255), MathUtil::Clamp(result.a(), 0, 255)); | ||||
| }; | ||||
| 
 | ||||
| static u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) { | ||||
|     switch (op) { | ||||
|     case FramebufferRegs::LogicOp::Clear: | ||||
|         return 0; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::And: | ||||
|         return src & dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::AndReverse: | ||||
|         return src & ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Copy: | ||||
|         return src; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Set: | ||||
|         return 255; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::CopyInverted: | ||||
|         return ~src; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::NoOp: | ||||
|         return dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Invert: | ||||
|         return ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Nand: | ||||
|         return ~(src & dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Or: | ||||
|         return src | dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Nor: | ||||
|         return ~(src | dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Xor: | ||||
|         return src ^ dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::Equiv: | ||||
|         return ~(src ^ dest); | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::AndInverted: | ||||
|         return ~src & dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::OrReverse: | ||||
|         return src | ~dest; | ||||
| 
 | ||||
|     case FramebufferRegs::LogicOp::OrInverted: | ||||
|         return ~src | dest; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values
 | ||||
| struct Fix12P4 { | ||||
|     Fix12P4() {} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue