mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	VideoCore: Extract swrast-specific data from OutputVertex
This commit is contained in:
		
							parent
							
								
									8ed9f9d49f
								
							
						
					
					
						commit
						dcdffabfe6
					
				
					 5 changed files with 64 additions and 58 deletions
				
			
		|  | @ -18,6 +18,8 @@ | ||||||
| #include "video_core/rasterizer.h" | #include "video_core/rasterizer.h" | ||||||
| #include "video_core/shader/shader.h" | #include "video_core/shader/shader.h" | ||||||
| 
 | 
 | ||||||
|  | using Pica::Rasterizer::Vertex; | ||||||
|  | 
 | ||||||
| namespace Pica { | namespace Pica { | ||||||
| 
 | 
 | ||||||
| namespace Clipper { | namespace Clipper { | ||||||
|  | @ -29,20 +31,20 @@ public: | ||||||
|                                                  float24::FromFloat32(0), float24::FromFloat32(0))) |                                                  float24::FromFloat32(0), float24::FromFloat32(0))) | ||||||
|         : coeffs(coeffs), bias(bias) {} |         : coeffs(coeffs), bias(bias) {} | ||||||
| 
 | 
 | ||||||
|     bool IsInside(const OutputVertex& vertex) const { |     bool IsInside(const Vertex& vertex) const { | ||||||
|         return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0); |         return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool IsOutSide(const OutputVertex& vertex) const { |     bool IsOutSide(const Vertex& vertex) const { | ||||||
|         return !IsInside(vertex); |         return !IsInside(vertex); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     OutputVertex GetIntersection(const OutputVertex& v0, const OutputVertex& v1) const { |     Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const { | ||||||
|         float24 dp = Math::Dot(v0.pos + bias, coeffs); |         float24 dp = Math::Dot(v0.pos + bias, coeffs); | ||||||
|         float24 dp_prev = Math::Dot(v1.pos + bias, coeffs); |         float24 dp_prev = Math::Dot(v1.pos + bias, coeffs); | ||||||
|         float24 factor = dp_prev / (dp_prev - dp); |         float24 factor = dp_prev / (dp_prev - dp); | ||||||
| 
 | 
 | ||||||
|         return OutputVertex::Lerp(factor, v0, v1); |         return Vertex::Lerp(factor, v0, v1); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -51,7 +53,7 @@ private: | ||||||
|     Math::Vec4<float24> bias; |     Math::Vec4<float24> bias; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void InitScreenCoordinates(OutputVertex& vtx) { | static void InitScreenCoordinates(Vertex& vtx) { | ||||||
|     struct { |     struct { | ||||||
|         float24 halfsize_x; |         float24 halfsize_x; | ||||||
|         float24 offset_x; |         float24 offset_x; | ||||||
|  | @ -91,8 +93,8 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | ||||||
|     // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a
 |     // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a
 | ||||||
|     // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9.
 |     // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9.
 | ||||||
|     static const size_t MAX_VERTICES = 9; |     static const size_t MAX_VERTICES = 9; | ||||||
|     static_vector<OutputVertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; |     static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; | ||||||
|     static_vector<OutputVertex, MAX_VERTICES> buffer_b; |     static_vector<Vertex, MAX_VERTICES> buffer_b; | ||||||
|     auto* output_list = &buffer_a; |     auto* output_list = &buffer_a; | ||||||
|     auto* input_list = &buffer_b; |     auto* input_list = &buffer_b; | ||||||
| 
 | 
 | ||||||
|  | @ -123,7 +125,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | ||||||
|         std::swap(input_list, output_list); |         std::swap(input_list, output_list); | ||||||
|         output_list->clear(); |         output_list->clear(); | ||||||
| 
 | 
 | ||||||
|         const OutputVertex* reference_vertex = &input_list->back(); |         const Vertex* reference_vertex = &input_list->back(); | ||||||
| 
 | 
 | ||||||
|         for (const auto& vertex : *input_list) { |         for (const auto& vertex : *input_list) { | ||||||
|             // NOTE: This algorithm changes vertex order in some cases!
 |             // NOTE: This algorithm changes vertex order in some cases!
 | ||||||
|  | @ -148,9 +150,9 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | ||||||
|     InitScreenCoordinates((*output_list)[1]); |     InitScreenCoordinates((*output_list)[1]); | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < output_list->size() - 2; i++) { |     for (size_t i = 0; i < output_list->size() - 2; i++) { | ||||||
|         OutputVertex& vtx0 = (*output_list)[0]; |         Vertex& vtx0 = (*output_list)[0]; | ||||||
|         OutputVertex& vtx1 = (*output_list)[i + 1]; |         Vertex& vtx1 = (*output_list)[i + 1]; | ||||||
|         OutputVertex& vtx2 = (*output_list)[i + 2]; |         Vertex& vtx2 = (*output_list)[i + 2]; | ||||||
| 
 | 
 | ||||||
|         InitScreenCoordinates(vtx2); |         InitScreenCoordinates(vtx2); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -307,8 +307,8 @@ MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 24 | ||||||
|  * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing |  * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing | ||||||
|  * culling via recursion. |  * culling via recursion. | ||||||
|  */ |  */ | ||||||
| static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Vertex& v2, | ||||||
|                                     const Shader::OutputVertex& v2, bool reversed = false) { |                                     bool reversed = false) { | ||||||
|     const auto& regs = g_state.regs; |     const auto& regs = g_state.regs; | ||||||
|     MICROPROFILE_SCOPE(GPU_Rasterization); |     MICROPROFILE_SCOPE(GPU_Rasterization); | ||||||
| 
 | 
 | ||||||
|  | @ -1276,8 +1276,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2) { | ||||||
|                      const Shader::OutputVertex& v2) { |  | ||||||
|     ProcessTriangleInternal(v0, v1, v2); |     ProcessTriangleInternal(v0, v1, v2); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,16 +4,44 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| namespace Pica { | #include "video_core/shader/shader.h" | ||||||
| 
 | 
 | ||||||
| namespace Shader { | namespace Pica { | ||||||
| struct OutputVertex; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| namespace Rasterizer { | namespace Rasterizer { | ||||||
| 
 | 
 | ||||||
| void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | struct Vertex : Shader::OutputVertex { | ||||||
|                      const Shader::OutputVertex& v2); |     Vertex(const OutputVertex& v) : OutputVertex(v) {} | ||||||
|  | 
 | ||||||
|  |     // Attributes used to store intermediate results
 | ||||||
|  |     // position after perspective divide
 | ||||||
|  |     Math::Vec3<float24> screenpos; | ||||||
|  | 
 | ||||||
|  |     // Linear interpolation
 | ||||||
|  |     // factor: 0=this, 1=vtx
 | ||||||
|  |     void Lerp(float24 factor, const Vertex& vtx) { | ||||||
|  |         pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); | ||||||
|  | 
 | ||||||
|  |         // TODO: Should perform perspective correct interpolation here...
 | ||||||
|  |         tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); | ||||||
|  |         tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor); | ||||||
|  |         tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); | ||||||
|  | 
 | ||||||
|  |         screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); | ||||||
|  | 
 | ||||||
|  |         color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Linear interpolation
 | ||||||
|  |     // factor: 0=v0, 1=v1
 | ||||||
|  |     static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) { | ||||||
|  |         Vertex ret = v0; | ||||||
|  |         ret.Lerp(factor, v1); | ||||||
|  |         return ret; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2); | ||||||
| 
 | 
 | ||||||
| } // namespace Rasterizer
 | } // namespace Rasterizer
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer | ||||||
|         OutputVertex ret{}; |         OutputVertex ret{}; | ||||||
|         std::array<float24, 24> vertex_slots; |         std::array<float24, 24> vertex_slots; | ||||||
|     }; |     }; | ||||||
|     static_assert(sizeof(vertex_slots) <= sizeof(ret), "Struct and array have different sizes."); |     static_assert(sizeof(vertex_slots) == sizeof(ret), "Struct and array have different sizes."); | ||||||
| 
 | 
 | ||||||
|     unsigned int num_attributes = regs.vs_output_total; |     unsigned int num_attributes = regs.vs_output_total; | ||||||
|     ASSERT(num_attributes <= 7); |     ASSERT(num_attributes <= 7); | ||||||
|  |  | ||||||
|  | @ -28,9 +28,6 @@ struct AttributeBuffer { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct OutputVertex { | struct OutputVertex { | ||||||
|     OutputVertex() = default; |  | ||||||
| 
 |  | ||||||
|     // VS output attributes
 |  | ||||||
|     Math::Vec4<float24> pos; |     Math::Vec4<float24> pos; | ||||||
|     Math::Vec4<float24> quat; |     Math::Vec4<float24> quat; | ||||||
|     Math::Vec4<float24> color; |     Math::Vec4<float24> color; | ||||||
|  | @ -42,42 +39,22 @@ struct OutputVertex { | ||||||
|     INSERT_PADDING_WORDS(1); |     INSERT_PADDING_WORDS(1); | ||||||
|     Math::Vec2<float24> tc2; |     Math::Vec2<float24> tc2; | ||||||
| 
 | 
 | ||||||
|     // Padding for optimal alignment
 |  | ||||||
|     INSERT_PADDING_WORDS(4); |  | ||||||
| 
 |  | ||||||
|     // Attributes used to store intermediate results
 |  | ||||||
| 
 |  | ||||||
|     // position after perspective divide
 |  | ||||||
|     Math::Vec3<float24> screenpos; |  | ||||||
|     INSERT_PADDING_WORDS(1); |  | ||||||
| 
 |  | ||||||
|     // Linear interpolation
 |  | ||||||
|     // factor: 0=this, 1=vtx
 |  | ||||||
|     void Lerp(float24 factor, const OutputVertex& vtx) { |  | ||||||
|         pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); |  | ||||||
| 
 |  | ||||||
|         // TODO: Should perform perspective correct interpolation here...
 |  | ||||||
|         tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); |  | ||||||
|         tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor); |  | ||||||
|         tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); |  | ||||||
| 
 |  | ||||||
|         screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); |  | ||||||
| 
 |  | ||||||
|         color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Linear interpolation
 |  | ||||||
|     // factor: 0=v0, 1=v1
 |  | ||||||
|     static OutputVertex Lerp(float24 factor, const OutputVertex& v0, const OutputVertex& v1) { |  | ||||||
|         OutputVertex ret = v0; |  | ||||||
|         ret.Lerp(factor, v1); |  | ||||||
|         return ret; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output); |     static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output); | ||||||
| }; | }; | ||||||
|  | #define ASSERT_POS(var, pos)                                                                       \ | ||||||
|  |     static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong "       \ | ||||||
|  |                                                                         "offset.") | ||||||
|  | ASSERT_POS(pos, Regs::VSOutputAttributes::POSITION_X); | ||||||
|  | ASSERT_POS(quat, Regs::VSOutputAttributes::QUATERNION_X); | ||||||
|  | ASSERT_POS(color, Regs::VSOutputAttributes::COLOR_R); | ||||||
|  | ASSERT_POS(tc0, Regs::VSOutputAttributes::TEXCOORD0_U); | ||||||
|  | ASSERT_POS(tc1, Regs::VSOutputAttributes::TEXCOORD1_U); | ||||||
|  | ASSERT_POS(tc0_w, Regs::VSOutputAttributes::TEXCOORD0_W); | ||||||
|  | ASSERT_POS(view, Regs::VSOutputAttributes::VIEW_X); | ||||||
|  | ASSERT_POS(tc2, Regs::VSOutputAttributes::TEXCOORD2_U); | ||||||
|  | #undef ASSERT_POS | ||||||
| static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | ||||||
| static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); | static_assert(sizeof(OutputVertex) == 24 * sizeof(float), "OutputVertex has invalid size"); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * This structure contains the state information that needs to be unique for a shader unit. The 3DS |  * This structure contains the state information that needs to be unique for a shader unit. The 3DS | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue