mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Pica: Consolidate the primitive assembly code in PrimitiveAssembly and GeometryDumper.
This commit is contained in:
		
							parent
							
								
									9679d231df
								
							
						
					
					
						commit
						2f1c129f64
					
				
					 5 changed files with 73 additions and 45 deletions
				
			
		|  | @ -2,6 +2,7 @@ | |||
| // Licensed under GPLv2
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "clipper.h" | ||||
| #include "command_processor.h" | ||||
| #include "math.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; | ||||
| 
 | ||||
|             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) | ||||
|             { | ||||
|  | @ -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.
 | ||||
|                 geometry_dumper.AddVertex({input.attr[0][0].ToFloat32(), input.attr[0][1].ToFloat32(), input.attr[0][2].ToFloat32()}, registers.triangle_topology); | ||||
|                 // NOTE: When dumping geometry, we simply assume that the first input attribute
 | ||||
|                 //       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()); | ||||
| 
 | ||||
|                 if (is_indexed) { | ||||
|                     // TODO: Add processed vertex to vertex cache!
 | ||||
|                 } | ||||
| 
 | ||||
|                 PrimitiveAssembly::SubmitVertex(output); | ||||
|                 // Send to triangle clipper
 | ||||
|                 clipper_primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle); | ||||
|             } | ||||
|             geometry_dumper.Dump(); | ||||
|             break; | ||||
|  |  | |||
|  | @ -22,27 +22,17 @@ namespace Pica { | |||
| 
 | ||||
| namespace DebugUtils { | ||||
| 
 | ||||
| void GeometryDumper::AddVertex(std::array<float,3> pos, TriangleTopology topology) { | ||||
|     vertices.push_back({pos[0], pos[1], pos[2]}); | ||||
| void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) { | ||||
|     vertices.push_back(v0); | ||||
|     vertices.push_back(v1); | ||||
|     vertices.push_back(v2); | ||||
| 
 | ||||
|     int num_vertices = vertices.size(); | ||||
| 
 | ||||
|     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; | ||||
|     } | ||||
|     faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); | ||||
| } | ||||
| 
 | ||||
| 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.
 | ||||
|     return; | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,20 +14,18 @@ namespace Pica { | |||
| 
 | ||||
| namespace DebugUtils { | ||||
| 
 | ||||
| using TriangleTopology = Regs::TriangleTopology; | ||||
| 
 | ||||
| // Simple utility class for dumping geometry data to an OBJ file
 | ||||
| class GeometryDumper { | ||||
| public: | ||||
|     void AddVertex(std::array<float,3> pos, TriangleTopology topology); | ||||
| 
 | ||||
|     void Dump(); | ||||
| 
 | ||||
| private: | ||||
|     struct Vertex { | ||||
|         std::array<float,3> pos; | ||||
|     }; | ||||
| 
 | ||||
|     void AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2); | ||||
| 
 | ||||
|     void Dump(); | ||||
| 
 | ||||
| private: | ||||
|     struct Face { | ||||
|         int index[3]; | ||||
|     }; | ||||
|  |  | |||
|  | @ -2,21 +2,23 @@ | |||
| // Licensed under GPLv2
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "clipper.h" | ||||
| #include "pica.h" | ||||
| #include "primitive_assembly.h" | ||||
| #include "vertex_shader.h" | ||||
| 
 | ||||
| #include "video_core/debug_utils/debug_utils.h" | ||||
| 
 | ||||
| namespace Pica { | ||||
| 
 | ||||
| namespace PrimitiveAssembly { | ||||
| template<typename VertexType> | ||||
| PrimitiveAssembler<VertexType>::PrimitiveAssembler(Regs::TriangleTopology topology) | ||||
|     : topology(topology), buffer_index(0) { | ||||
| } | ||||
| 
 | ||||
| static OutputVertex buffer[2]; | ||||
| static int buffer_index = 0; // TODO: reset this on emulation restart
 | ||||
| 
 | ||||
| void SubmitVertex(OutputVertex& vtx) | ||||
| template<typename VertexType> | ||||
| void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) | ||||
| { | ||||
|     switch (registers.triangle_topology) { | ||||
|     switch (topology) { | ||||
|         case Regs::TriangleTopology::List: | ||||
|         case Regs::TriangleTopology::ListIndexed: | ||||
|             if (buffer_index < 2) { | ||||
|  | @ -24,7 +26,7 @@ void SubmitVertex(OutputVertex& vtx) | |||
|             } else { | ||||
|                 buffer_index = 0; | ||||
| 
 | ||||
|                 Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); | ||||
|                 triangle_handler(buffer[0], buffer[1], vtx); | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|  | @ -32,7 +34,7 @@ void SubmitVertex(OutputVertex& vtx) | |||
|             if (buffer_index == 2) { | ||||
|                 buffer_index = 0; | ||||
| 
 | ||||
|                 Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); | ||||
|                 triangle_handler(buffer[0], buffer[1], vtx); | ||||
| 
 | ||||
|                 buffer[1] = vtx; | ||||
|             } else { | ||||
|  | @ -41,11 +43,15 @@ void SubmitVertex(OutputVertex& vtx) | |||
|             break; | ||||
| 
 | ||||
|         default: | ||||
|             ERROR_LOG(GPU, "Unknown triangle mode %x:", (int)registers.triangle_topology.Value()); | ||||
|             ERROR_LOG(GPU, "Unknown triangle topology %x:", (int)topology); | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
| // explicitly instantiate use cases
 | ||||
| template | ||||
| struct PrimitiveAssembler<VertexShader::OutputVertex>; | ||||
| template | ||||
| struct PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex>; | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
|  | @ -4,18 +4,40 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <functional> | ||||
| 
 | ||||
| #include "video_core/pica.h" | ||||
| 
 | ||||
| #include "video_core/vertex_shader.h" | ||||
| 
 | ||||
| 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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue