diff options
| author | 2014-08-17 17:44:55 +0200 | |
|---|---|---|
| committer | 2014-08-25 22:03:19 +0200 | |
| commit | 2f1c129f6407fe2d5c8c3e57c6717d5668570de5 (patch) | |
| tree | 5d12dadd9ffe3b46b9b94a84b7688d6d3b8260fd /src | |
| parent | Pica/Rasterizer: Add texturing support. (diff) | |
| download | yuzu-2f1c129f6407fe2d5c8c3e57c6717d5668570de5.tar.gz yuzu-2f1c129f6407fe2d5c8c3e57c6717d5668570de5.tar.xz yuzu-2f1c129f6407fe2d5c8c3e57c6717d5668570de5.zip | |
Pica: Consolidate the primitive assembly code in PrimitiveAssembly and GeometryDumper.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/command_processor.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 12 | ||||
| -rw-r--r-- | src/video_core/primitive_assembly.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/primitive_assembly.h | 38 |
5 files changed, 74 insertions, 46 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 8da030601..9567a9849 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "clipper.h" | ||
| 5 | #include "command_processor.h" | 6 | #include "command_processor.h" |
| 6 | #include "math.h" | 7 | #include "math.h" |
| 7 | #include "pica.h" | 8 | #include "pica.h" |
| @@ -79,6 +80,8 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 79 | bool index_u16 = (bool)index_info.format; | 80 | bool index_u16 = (bool)index_info.format; |
| 80 | 81 | ||
| 81 | DebugUtils::GeometryDumper geometry_dumper; | 82 | DebugUtils::GeometryDumper geometry_dumper; |
| 83 | PrimitiveAssembler<VertexShader::OutputVertex> clipper_primitive_assembler(registers.triangle_topology.Value()); | ||
| 84 | PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(registers.triangle_topology.Value()); | ||
| 82 | 85 | ||
| 83 | for (int index = 0; index < registers.num_vertices; ++index) | 86 | for (int index = 0; index < registers.num_vertices; ++index) |
| 84 | { | 87 | { |
| @@ -108,16 +111,25 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 108 | } | 111 | } |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | // NOTE: For now, we simply assume that the first input attribute corresponds to the position. | 114 | // NOTE: When dumping geometry, we simply assume that the first input attribute |
| 112 | geometry_dumper.AddVertex({input.attr[0][0].ToFloat32(), input.attr[0][1].ToFloat32(), input.attr[0][2].ToFloat32()}, registers.triangle_topology); | 115 | // corresponds to the position for now. |
| 113 | 116 | DebugUtils::GeometryDumper::Vertex dumped_vertex = { | |
| 117 | input.attr[0][0].ToFloat32(), input.attr[0][1].ToFloat32(), input.attr[0][2].ToFloat32() | ||
| 118 | }; | ||
| 119 | using namespace std::placeholders; | ||
| 120 | dumping_primitive_assembler.SubmitVertex(dumped_vertex, | ||
| 121 | std::bind(&DebugUtils::GeometryDumper::AddTriangle, | ||
| 122 | &geometry_dumper, _1, _2, _3)); | ||
| 123 | |||
| 124 | // Send to vertex shader | ||
| 114 | VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes()); | 125 | VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes()); |
| 115 | 126 | ||
| 116 | if (is_indexed) { | 127 | if (is_indexed) { |
| 117 | // TODO: Add processed vertex to vertex cache! | 128 | // TODO: Add processed vertex to vertex cache! |
| 118 | } | 129 | } |
| 119 | 130 | ||
| 120 | PrimitiveAssembly::SubmitVertex(output); | 131 | // Send to triangle clipper |
| 132 | clipper_primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle); | ||
| 121 | } | 133 | } |
| 122 | geometry_dumper.Dump(); | 134 | geometry_dumper.Dump(); |
| 123 | break; | 135 | break; |
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index f7d9455be..48e6dd182 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -22,27 +22,17 @@ namespace Pica { | |||
| 22 | 22 | ||
| 23 | namespace DebugUtils { | 23 | namespace DebugUtils { |
| 24 | 24 | ||
| 25 | void GeometryDumper::AddVertex(std::array<float,3> pos, TriangleTopology topology) { | 25 | void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) { |
| 26 | vertices.push_back({pos[0], pos[1], pos[2]}); | 26 | vertices.push_back(v0); |
| 27 | vertices.push_back(v1); | ||
| 28 | vertices.push_back(v2); | ||
| 27 | 29 | ||
| 28 | int num_vertices = vertices.size(); | 30 | int num_vertices = vertices.size(); |
| 29 | 31 | faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); | |
| 30 | switch (topology) { | ||
| 31 | case TriangleTopology::List: | ||
| 32 | case TriangleTopology::ListIndexed: | ||
| 33 | if (0 == (num_vertices % 3)) | ||
| 34 | faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); | ||
| 35 | break; | ||
| 36 | |||
| 37 | default: | ||
| 38 | ERROR_LOG(GPU, "Unknown triangle topology %x", (int)topology); | ||
| 39 | exit(0); | ||
| 40 | break; | ||
| 41 | } | ||
| 42 | } | 32 | } |
| 43 | 33 | ||
| 44 | void GeometryDumper::Dump() { | 34 | void GeometryDumper::Dump() { |
| 45 | // NOTE: Permanently enabling this just trashes hard disks for no reason. | 35 | // NOTE: Permanently enabling this just trashes the hard disk for no reason. |
| 46 | // Hence, this is currently disabled. | 36 | // Hence, this is currently disabled. |
| 47 | return; | 37 | return; |
| 48 | 38 | ||
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 53c33c96e..8b1499bf2 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h | |||
| @@ -14,20 +14,18 @@ namespace Pica { | |||
| 14 | 14 | ||
| 15 | namespace DebugUtils { | 15 | namespace DebugUtils { |
| 16 | 16 | ||
| 17 | using TriangleTopology = Regs::TriangleTopology; | ||
| 18 | |||
| 19 | // Simple utility class for dumping geometry data to an OBJ file | 17 | // Simple utility class for dumping geometry data to an OBJ file |
| 20 | class GeometryDumper { | 18 | class GeometryDumper { |
| 21 | public: | 19 | public: |
| 22 | void AddVertex(std::array<float,3> pos, TriangleTopology topology); | ||
| 23 | |||
| 24 | void Dump(); | ||
| 25 | |||
| 26 | private: | ||
| 27 | struct Vertex { | 20 | struct Vertex { |
| 28 | std::array<float,3> pos; | 21 | std::array<float,3> pos; |
| 29 | }; | 22 | }; |
| 30 | 23 | ||
| 24 | void AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2); | ||
| 25 | |||
| 26 | void Dump(); | ||
| 27 | |||
| 28 | private: | ||
| 31 | struct Face { | 29 | struct Face { |
| 32 | int index[3]; | 30 | int index[3]; |
| 33 | }; | 31 | }; |
diff --git a/src/video_core/primitive_assembly.cpp b/src/video_core/primitive_assembly.cpp index 2354ffb99..dabf2d1a3 100644 --- a/src/video_core/primitive_assembly.cpp +++ b/src/video_core/primitive_assembly.cpp | |||
| @@ -2,21 +2,23 @@ | |||
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "clipper.h" | ||
| 6 | #include "pica.h" | 5 | #include "pica.h" |
| 7 | #include "primitive_assembly.h" | 6 | #include "primitive_assembly.h" |
| 8 | #include "vertex_shader.h" | 7 | #include "vertex_shader.h" |
| 9 | 8 | ||
| 10 | namespace Pica { | 9 | #include "video_core/debug_utils/debug_utils.h" |
| 11 | 10 | ||
| 12 | namespace PrimitiveAssembly { | 11 | namespace Pica { |
| 13 | 12 | ||
| 14 | static OutputVertex buffer[2]; | 13 | template<typename VertexType> |
| 15 | static int buffer_index = 0; // TODO: reset this on emulation restart | 14 | PrimitiveAssembler<VertexType>::PrimitiveAssembler(Regs::TriangleTopology topology) |
| 15 | : topology(topology), buffer_index(0) { | ||
| 16 | } | ||
| 16 | 17 | ||
| 17 | void SubmitVertex(OutputVertex& vtx) | 18 | template<typename VertexType> |
| 19 | void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) | ||
| 18 | { | 20 | { |
| 19 | switch (registers.triangle_topology) { | 21 | switch (topology) { |
| 20 | case Regs::TriangleTopology::List: | 22 | case Regs::TriangleTopology::List: |
| 21 | case Regs::TriangleTopology::ListIndexed: | 23 | case Regs::TriangleTopology::ListIndexed: |
| 22 | if (buffer_index < 2) { | 24 | if (buffer_index < 2) { |
| @@ -24,7 +26,7 @@ void SubmitVertex(OutputVertex& vtx) | |||
| 24 | } else { | 26 | } else { |
| 25 | buffer_index = 0; | 27 | buffer_index = 0; |
| 26 | 28 | ||
| 27 | Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); | 29 | triangle_handler(buffer[0], buffer[1], vtx); |
| 28 | } | 30 | } |
| 29 | break; | 31 | break; |
| 30 | 32 | ||
| @@ -32,7 +34,7 @@ void SubmitVertex(OutputVertex& vtx) | |||
| 32 | if (buffer_index == 2) { | 34 | if (buffer_index == 2) { |
| 33 | buffer_index = 0; | 35 | buffer_index = 0; |
| 34 | 36 | ||
| 35 | Clipper::ProcessTriangle(buffer[0], buffer[1], vtx); | 37 | triangle_handler(buffer[0], buffer[1], vtx); |
| 36 | 38 | ||
| 37 | buffer[1] = vtx; | 39 | buffer[1] = vtx; |
| 38 | } else { | 40 | } else { |
| @@ -41,11 +43,15 @@ void SubmitVertex(OutputVertex& vtx) | |||
| 41 | break; | 43 | break; |
| 42 | 44 | ||
| 43 | default: | 45 | default: |
| 44 | ERROR_LOG(GPU, "Unknown triangle mode %x:", (int)registers.triangle_topology.Value()); | 46 | ERROR_LOG(GPU, "Unknown triangle topology %x:", (int)topology); |
| 45 | break; | 47 | break; |
| 46 | } | 48 | } |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | } // namespace | 51 | // explicitly instantiate use cases |
| 52 | template | ||
| 53 | struct PrimitiveAssembler<VertexShader::OutputVertex>; | ||
| 54 | template | ||
| 55 | struct PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex>; | ||
| 50 | 56 | ||
| 51 | } // namespace | 57 | } // namespace |
diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index 2a2b0c170..ea2e2f61e 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h | |||
| @@ -4,18 +4,40 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | namespace Pica { | 7 | #include <functional> |
| 8 | 8 | ||
| 9 | namespace VertexShader { | 9 | #include "video_core/pica.h" |
| 10 | struct OutputVertex; | ||
| 11 | } | ||
| 12 | 10 | ||
| 13 | namespace PrimitiveAssembly { | 11 | #include "video_core/vertex_shader.h" |
| 14 | 12 | ||
| 15 | using VertexShader::OutputVertex; | 13 | namespace Pica { |
| 16 | 14 | ||
| 17 | void SubmitVertex(OutputVertex& vtx); | 15 | /* |
| 16 | * Utility class to build triangles from a series of vertices, | ||
| 17 | * according to a given triangle topology. | ||
| 18 | */ | ||
| 19 | template<typename VertexType> | ||
| 20 | struct PrimitiveAssembler { | ||
| 21 | using TriangleHandler = std::function<void(VertexType& v0, | ||
| 22 | VertexType& v1, | ||
| 23 | VertexType& v2)>; | ||
| 24 | |||
| 25 | PrimitiveAssembler(Regs::TriangleTopology topology); | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Queues a vertex, builds primitives from the vertex queue according to the given | ||
| 29 | * triangle topology, and calls triangle_handler for each generated primitive. | ||
| 30 | * NOTE: We could specify the triangle handler in the constructor, but this way we can | ||
| 31 | * keep event and handler code next to each other. | ||
| 32 | */ | ||
| 33 | void SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler); | ||
| 34 | |||
| 35 | private: | ||
| 36 | Regs::TriangleTopology topology; | ||
| 37 | |||
| 38 | int buffer_index; | ||
| 39 | VertexType buffer[2]; | ||
| 40 | }; | ||
| 18 | 41 | ||
| 19 | } // namespace | ||
| 20 | 42 | ||
| 21 | } // namespace | 43 | } // namespace |