mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Pica: Consolidate the primitive assembly code in PrimitiveAssembly and GeometryDumper.
This commit is contained in:
		
							parent
							
								
									9679d231df
								
							
						
					
					
						commit
						2f1c129f64
					
				| @ -2,6 +2,7 @@ | |||||||
| // Licensed under GPLv2
 | // Licensed under GPLv2
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
|  | #include "clipper.h" | ||||||
| #include "command_processor.h" | #include "command_processor.h" | ||||||
| #include "math.h" | #include "math.h" | ||||||
| #include "pica.h" | #include "pica.h" | ||||||
| @ -79,6 +80,8 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||||||
|             bool index_u16 = (bool)index_info.format; |             bool index_u16 = (bool)index_info.format; | ||||||
| 
 | 
 | ||||||
|             DebugUtils::GeometryDumper geometry_dumper; |             DebugUtils::GeometryDumper geometry_dumper; | ||||||
|  |             PrimitiveAssembler<VertexShader::OutputVertex> clipper_primitive_assembler(registers.triangle_topology.Value()); | ||||||
|  |             PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(registers.triangle_topology.Value()); | ||||||
| 
 | 
 | ||||||
|             for (int index = 0; index < registers.num_vertices; ++index) |             for (int index = 0; index < registers.num_vertices; ++index) | ||||||
|             { |             { | ||||||
| @ -108,16 +111,25 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // NOTE: For now, we simply assume that the first input attribute corresponds to the position.
 |                 // NOTE: When dumping geometry, we simply assume that the first input attribute
 | ||||||
|                 geometry_dumper.AddVertex({input.attr[0][0].ToFloat32(), input.attr[0][1].ToFloat32(), input.attr[0][2].ToFloat32()}, registers.triangle_topology); |                 //       corresponds to the position for now.
 | ||||||
|  |                 DebugUtils::GeometryDumper::Vertex dumped_vertex = { | ||||||
|  |                     input.attr[0][0].ToFloat32(), input.attr[0][1].ToFloat32(), input.attr[0][2].ToFloat32() | ||||||
|  |                 }; | ||||||
|  |                 using namespace std::placeholders; | ||||||
|  |                 dumping_primitive_assembler.SubmitVertex(dumped_vertex, | ||||||
|  |                                                          std::bind(&DebugUtils::GeometryDumper::AddTriangle, | ||||||
|  |                                                                    &geometry_dumper, _1, _2, _3)); | ||||||
| 
 | 
 | ||||||
|  |                 // Send to vertex shader
 | ||||||
|                 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes()); |                 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes()); | ||||||
| 
 | 
 | ||||||
|                 if (is_indexed) { |                 if (is_indexed) { | ||||||
|                     // TODO: Add processed vertex to vertex cache!
 |                     // TODO: Add processed vertex to vertex cache!
 | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 PrimitiveAssembly::SubmitVertex(output); |                 // Send to triangle clipper
 | ||||||
|  |                 clipper_primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle); | ||||||
|             } |             } | ||||||
|             geometry_dumper.Dump(); |             geometry_dumper.Dump(); | ||||||
|             break; |             break; | ||||||
|  | |||||||
| @ -22,27 +22,17 @@ namespace Pica { | |||||||
| 
 | 
 | ||||||
| namespace DebugUtils { | namespace DebugUtils { | ||||||
| 
 | 
 | ||||||
| void GeometryDumper::AddVertex(std::array<float,3> pos, TriangleTopology topology) { | void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) { | ||||||
|     vertices.push_back({pos[0], pos[1], pos[2]}); |     vertices.push_back(v0); | ||||||
|  |     vertices.push_back(v1); | ||||||
|  |     vertices.push_back(v2); | ||||||
| 
 | 
 | ||||||
|     int num_vertices = vertices.size(); |     int num_vertices = vertices.size(); | ||||||
| 
 |     faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); | ||||||
|     switch (topology) { |  | ||||||
|     case TriangleTopology::List: |  | ||||||
|     case TriangleTopology::ListIndexed: |  | ||||||
|         if (0 == (num_vertices % 3)) |  | ||||||
|             faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     default: |  | ||||||
|         ERROR_LOG(GPU, "Unknown triangle topology %x", (int)topology); |  | ||||||
|         exit(0); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GeometryDumper::Dump() { | void GeometryDumper::Dump() { | ||||||
|     // NOTE: Permanently enabling this just trashes hard disks for no reason.
 |     // NOTE: Permanently enabling this just trashes the hard disk for no reason.
 | ||||||
|     //       Hence, this is currently disabled.
 |     //       Hence, this is currently disabled.
 | ||||||
|     return; |     return; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,20 +14,18 @@ namespace Pica { | |||||||
| 
 | 
 | ||||||
| namespace DebugUtils { | namespace DebugUtils { | ||||||
| 
 | 
 | ||||||
| using TriangleTopology = Regs::TriangleTopology; |  | ||||||
| 
 |  | ||||||
| // Simple utility class for dumping geometry data to an OBJ file
 | // Simple utility class for dumping geometry data to an OBJ file
 | ||||||
| class GeometryDumper { | class GeometryDumper { | ||||||
| public: | public: | ||||||
|     void AddVertex(std::array<float,3> pos, TriangleTopology topology); |  | ||||||
| 
 |  | ||||||
|     void Dump(); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     struct Vertex { |     struct Vertex { | ||||||
|         std::array<float,3> pos; |         std::array<float,3> pos; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     void AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2); | ||||||
|  | 
 | ||||||
|  |     void Dump(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|     struct Face { |     struct Face { | ||||||
|         int index[3]; |         int index[3]; | ||||||
|     }; |     }; | ||||||
|  | |||||||
| @ -2,21 +2,23 @@ | |||||||
| // Licensed under GPLv2
 | // Licensed under GPLv2
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "clipper.h" |  | ||||||
| #include "pica.h" | #include "pica.h" | ||||||
| #include "primitive_assembly.h" | #include "primitive_assembly.h" | ||||||
| #include "vertex_shader.h" | #include "vertex_shader.h" | ||||||
| 
 | 
 | ||||||
|  | #include "video_core/debug_utils/debug_utils.h" | ||||||
|  | 
 | ||||||
| namespace Pica { | namespace Pica { | ||||||
| 
 | 
 | ||||||
| namespace PrimitiveAssembly { | template<typename VertexType> | ||||||
|  | PrimitiveAssembler<VertexType>::PrimitiveAssembler(Regs::TriangleTopology topology) | ||||||
|  |     : topology(topology), buffer_index(0) { | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| static OutputVertex buffer[2]; | template<typename VertexType> | ||||||
| static int buffer_index = 0; // TODO: reset this on emulation restart
 | void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) | ||||||
| 
 |  | ||||||
| void SubmitVertex(OutputVertex& vtx) |  | ||||||
| { | { | ||||||
|     switch (registers.triangle_topology) { |     switch (topology) { | ||||||
|         case Regs::TriangleTopology::List: |         case Regs::TriangleTopology::List: | ||||||
|         case Regs::TriangleTopology::ListIndexed: |         case Regs::TriangleTopology::ListIndexed: | ||||||
|             if (buffer_index < 2) { |             if (buffer_index < 2) { | ||||||
| @ -24,7 +26,7 @@ void SubmitVertex(OutputVertex& vtx) | |||||||
|             } else { |             } else { | ||||||
|                 buffer_index = 0; |                 buffer_index = 0; | ||||||
| 
 | 
 | ||||||
|                 Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); |                 triangle_handler(buffer[0], buffer[1], vtx); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
| @ -32,7 +34,7 @@ void SubmitVertex(OutputVertex& vtx) | |||||||
|             if (buffer_index == 2) { |             if (buffer_index == 2) { | ||||||
|                 buffer_index = 0; |                 buffer_index = 0; | ||||||
| 
 | 
 | ||||||
|                 Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); |                 triangle_handler(buffer[0], buffer[1], vtx); | ||||||
| 
 | 
 | ||||||
|                 buffer[1] = vtx; |                 buffer[1] = vtx; | ||||||
|             } else { |             } else { | ||||||
| @ -41,11 +43,15 @@ void SubmitVertex(OutputVertex& vtx) | |||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         default: |         default: | ||||||
|             ERROR_LOG(GPU, "Unknown triangle mode %x:", (int)registers.triangle_topology.Value()); |             ERROR_LOG(GPU, "Unknown triangle topology %x:", (int)topology); | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace
 | // explicitly instantiate use cases
 | ||||||
|  | template | ||||||
|  | struct PrimitiveAssembler<VertexShader::OutputVertex>; | ||||||
|  | template | ||||||
|  | struct PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex>; | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  | |||||||
| @ -4,18 +4,40 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <functional> | ||||||
|  | 
 | ||||||
|  | #include "video_core/pica.h" | ||||||
|  | 
 | ||||||
|  | #include "video_core/vertex_shader.h" | ||||||
|  | 
 | ||||||
| namespace Pica { | namespace Pica { | ||||||
| 
 | 
 | ||||||
| namespace VertexShader { | /*
 | ||||||
|     struct OutputVertex; |  * Utility class to build triangles from a series of vertices, | ||||||
| } |  * according to a given triangle topology. | ||||||
|  |  */ | ||||||
|  | template<typename VertexType> | ||||||
|  | struct PrimitiveAssembler { | ||||||
|  |     using TriangleHandler = std::function<void(VertexType& v0, | ||||||
|  |                                                VertexType& v1, | ||||||
|  |                                                VertexType& v2)>; | ||||||
| 
 | 
 | ||||||
| namespace PrimitiveAssembly { |     PrimitiveAssembler(Regs::TriangleTopology topology); | ||||||
| 
 | 
 | ||||||
| using VertexShader::OutputVertex; |     /*
 | ||||||
|  |      * Queues a vertex, builds primitives from the vertex queue according to the given | ||||||
|  |      * triangle topology, and calls triangle_handler for each generated primitive. | ||||||
|  |      * NOTE: We could specify the triangle handler in the constructor, but this way we can | ||||||
|  |      * keep event and handler code next to each other. | ||||||
|  |      */ | ||||||
|  |     void SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     Regs::TriangleTopology topology; | ||||||
|  | 
 | ||||||
|  |     int buffer_index; | ||||||
|  |     VertexType buffer[2]; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| void SubmitVertex(OutputVertex& vtx); |  | ||||||
| 
 |  | ||||||
| } // namespace
 |  | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Tony Wasserka
						Tony Wasserka