diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/command_processor.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/pica.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/pica.h | 7 | ||||
| -rw-r--r-- | src/video_core/pica_state.h | 15 | ||||
| -rw-r--r-- | src/video_core/primitive_assembly.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 |
6 files changed, 59 insertions, 29 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 4b59984ad..028b59348 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -75,12 +75,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 75 | GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); | 75 | GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); |
| 76 | break; | 76 | break; |
| 77 | 77 | ||
| 78 | case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E): | ||
| 79 | g_state.primitive_assembler.Reconfigure(regs.triangle_topology); | ||
| 80 | break; | ||
| 81 | |||
| 82 | case PICA_REG_INDEX_WORKAROUND(restart_primitive, 0x25F): | ||
| 83 | g_state.primitive_assembler.Reset(); | ||
| 84 | break; | ||
| 85 | |||
| 78 | case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232): | 86 | case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232): |
| 79 | if (regs.vs_default_attributes_setup.index == 15) { | 87 | g_state.immediate.current_attribute = 0; |
| 80 | // Reset immediate primitive state | 88 | default_attr_counter = 0; |
| 81 | g_state.immediate.primitive_assembler.Reconfigure(regs.triangle_topology); | ||
| 82 | g_state.immediate.attribute_id = 0; | ||
| 83 | } | ||
| 84 | break; | 89 | break; |
| 85 | 90 | ||
| 86 | // Load default vertex input attributes | 91 | // Load default vertex input attributes |
| @@ -105,7 +110,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 105 | break; | 110 | break; |
| 106 | } | 111 | } |
| 107 | 112 | ||
| 108 | Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index]; | 113 | Math::Vec4<float24> attribute; |
| 109 | 114 | ||
| 110 | // NOTE: The destination component order indeed is "backwards" | 115 | // NOTE: The destination component order indeed is "backwards" |
| 111 | attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8); | 116 | attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8); |
| @@ -119,26 +124,29 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 119 | 124 | ||
| 120 | // TODO: Verify that this actually modifies the register! | 125 | // TODO: Verify that this actually modifies the register! |
| 121 | if (setup.index < 15) { | 126 | if (setup.index < 15) { |
| 127 | g_state.vs.default_attributes[setup.index] = attribute; | ||
| 122 | setup.index++; | 128 | setup.index++; |
| 123 | } else { | 129 | } else { |
| 124 | // Put each attribute into an immediate input buffer. | 130 | // Put each attribute into an immediate input buffer. |
| 125 | // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is | 131 | // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is |
| 126 | // sent to the primitive assembler. | 132 | // sent to the primitive assembler. |
| 127 | 133 | ||
| 128 | auto& immediate_input = g_state.immediate.input; | 134 | auto& immediate_input = g_state.immediate.input_vertex; |
| 129 | auto& immediate_attribute_id = g_state.immediate.attribute_id; | 135 | auto& immediate_attribute_id = g_state.immediate.current_attribute; |
| 130 | const auto& attribute_config = regs.vertex_attributes; | ||
| 131 | 136 | ||
| 132 | immediate_input.attr[immediate_attribute_id++] = attribute; | 137 | immediate_input.attr[immediate_attribute_id++] = attribute; |
| 133 | 138 | ||
| 134 | if (immediate_attribute_id >= attribute_config.GetNumTotalAttributes()) { | 139 | if (immediate_attribute_id >= regs.vs.num_input_attributes+1) { |
| 135 | immediate_attribute_id = 0; | 140 | immediate_attribute_id = 0; |
| 136 | 141 | ||
| 137 | Shader::UnitState<false> shader_unit; | 142 | Shader::UnitState<false> shader_unit; |
| 138 | Shader::Setup(shader_unit); | 143 | Shader::Setup(shader_unit); |
| 139 | 144 | ||
| 145 | if (g_debug_context) | ||
| 146 | g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, static_cast<void*>(&immediate_input)); | ||
| 147 | |||
| 140 | // Send to vertex shader | 148 | // Send to vertex shader |
| 141 | Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, attribute_config.GetNumTotalAttributes()); | 149 | Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, regs.vs.num_input_attributes+1); |
| 142 | 150 | ||
| 143 | // Send to renderer | 151 | // Send to renderer |
| 144 | using Pica::Shader::OutputVertex; | 152 | using Pica::Shader::OutputVertex; |
| @@ -146,7 +154,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 146 | VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); | 154 | VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); |
| 147 | }; | 155 | }; |
| 148 | 156 | ||
| 149 | g_state.immediate.primitive_assembler.SubmitVertex(output, AddTriangle); | 157 | g_state.primitive_assembler.SubmitVertex(output, AddTriangle); |
| 150 | } | 158 | } |
| 151 | } | 159 | } |
| 152 | } | 160 | } |
| @@ -154,9 +162,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 154 | } | 162 | } |
| 155 | 163 | ||
| 156 | case PICA_REG_INDEX(gpu_mode): | 164 | case PICA_REG_INDEX(gpu_mode): |
| 157 | if (regs.gpu_mode == Regs::GPUMode::Configuring && regs.vs_default_attributes_setup.index == 15) { | 165 | if (regs.gpu_mode == Regs::GPUMode::Configuring) { |
| 158 | // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring | 166 | // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring |
| 159 | VideoCore::g_renderer->Rasterizer()->DrawTriangles(); | 167 | VideoCore::g_renderer->Rasterizer()->DrawTriangles(); |
| 168 | |||
| 169 | if (g_debug_context) { | ||
| 170 | g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); | ||
| 171 | } | ||
| 160 | } | 172 | } |
| 161 | break; | 173 | break; |
| 162 | 174 | ||
| @@ -241,7 +253,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 241 | DebugUtils::GeometryDumper geometry_dumper; | 253 | DebugUtils::GeometryDumper geometry_dumper; |
| 242 | PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value()); | 254 | PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value()); |
| 243 | #endif | 255 | #endif |
| 244 | PrimitiveAssembler<Shader::OutputVertex> primitive_assembler(regs.triangle_topology.Value()); | 256 | PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; |
| 245 | 257 | ||
| 246 | if (g_debug_context) { | 258 | if (g_debug_context) { |
| 247 | for (int i = 0; i < 3; ++i) { | 259 | for (int i = 0; i < 3; ++i) { |
| @@ -412,16 +424,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 412 | range.second, range.first); | 424 | range.second, range.first); |
| 413 | } | 425 | } |
| 414 | 426 | ||
| 415 | VideoCore::g_renderer->Rasterizer()->DrawTriangles(); | ||
| 416 | |||
| 417 | #if PICA_DUMP_GEOMETRY | 427 | #if PICA_DUMP_GEOMETRY |
| 418 | geometry_dumper.Dump(); | 428 | geometry_dumper.Dump(); |
| 419 | #endif | 429 | #endif |
| 420 | 430 | ||
| 421 | if (g_debug_context) { | ||
| 422 | g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); | ||
| 423 | } | ||
| 424 | |||
| 425 | break; | 431 | break; |
| 426 | } | 432 | } |
| 427 | 433 | ||
diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 32ad72674..ccbaf071b 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp | |||
| @@ -493,12 +493,25 @@ std::string Regs::GetCommandName(int index) { | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | void Init() { | 495 | void Init() { |
| 496 | g_state.Reset(); | ||
| 496 | } | 497 | } |
| 497 | 498 | ||
| 498 | void Shutdown() { | 499 | void Shutdown() { |
| 499 | Shader::Shutdown(); | 500 | Shader::Shutdown(); |
| 501 | } | ||
| 502 | |||
| 503 | template <typename T> | ||
| 504 | void Zero(T& o) { | ||
| 505 | memset(&o, 0, sizeof(o)); | ||
| 506 | } | ||
| 500 | 507 | ||
| 501 | memset(&g_state, 0, sizeof(State)); | 508 | void State::Reset() { |
| 509 | Zero(regs); | ||
| 510 | Zero(vs); | ||
| 511 | Zero(gs); | ||
| 512 | Zero(cmd_list); | ||
| 513 | Zero(immediate); | ||
| 514 | primitive_assembler.Reconfigure(Regs::TriangleTopology::List); | ||
| 502 | } | 515 | } |
| 503 | 516 | ||
| 504 | } | 517 | } |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 4b783ac6b..16f9e4006 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -1123,7 +1123,12 @@ struct Regs { | |||
| 1123 | BitField<24, 8, u32> w; | 1123 | BitField<24, 8, u32> w; |
| 1124 | } int_uniforms[4]; | 1124 | } int_uniforms[4]; |
| 1125 | 1125 | ||
| 1126 | INSERT_PADDING_WORDS(0x5); | 1126 | INSERT_PADDING_WORDS(0x4); |
| 1127 | |||
| 1128 | union { | ||
| 1129 | // Number of input attributes to shader unit - 1 | ||
| 1130 | BitField<0, 4, u32> num_input_attributes; | ||
| 1131 | }; | ||
| 1127 | 1132 | ||
| 1128 | // Offset to shader program entry point (in words) | 1133 | // Offset to shader program entry point (in words) |
| 1129 | BitField<0, 16, u32> main_offset; | 1134 | BitField<0, 16, u32> main_offset; |
diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index c7616bc55..323290054 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h | |||
| @@ -12,6 +12,8 @@ namespace Pica { | |||
| 12 | 12 | ||
| 13 | /// Struct used to describe current Pica state | 13 | /// Struct used to describe current Pica state |
| 14 | struct State { | 14 | struct State { |
| 15 | void Reset(); | ||
| 16 | |||
| 15 | /// Pica registers | 17 | /// Pica registers |
| 16 | Regs regs; | 18 | Regs regs; |
| 17 | 19 | ||
| @@ -46,13 +48,14 @@ struct State { | |||
| 46 | 48 | ||
| 47 | /// Struct used to describe immediate mode rendering state | 49 | /// Struct used to describe immediate mode rendering state |
| 48 | struct ImmediateModeState { | 50 | struct ImmediateModeState { |
| 49 | Shader::InputVertex input; | 51 | // Used to buffer partial vertices for immediate-mode rendering. |
| 50 | // This is constructed with a dummy triangle topology | 52 | Shader::InputVertex input_vertex; |
| 51 | PrimitiveAssembler<Shader::OutputVertex> primitive_assembler; | 53 | // Index of the next attribute to be loaded into `input_vertex`. |
| 52 | int attribute_id = 0; | 54 | int current_attribute = 0; |
| 53 | |||
| 54 | ImmediateModeState() : primitive_assembler(Regs::TriangleTopology::List) {} | ||
| 55 | } immediate; | 55 | } immediate; |
| 56 | |||
| 57 | // This is constructed with a dummy triangle topology | ||
| 58 | PrimitiveAssembler<Shader::OutputVertex> primitive_assembler; | ||
| 56 | }; | 59 | }; |
| 57 | 60 | ||
| 58 | extern State g_state; ///< Current Pica state | 61 | extern State g_state; ///< Current Pica state |
diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index cc6e5fde5..9396b4c85 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h | |||
| @@ -20,7 +20,7 @@ struct PrimitiveAssembler { | |||
| 20 | VertexType& v1, | 20 | VertexType& v1, |
| 21 | VertexType& v2)>; | 21 | VertexType& v2)>; |
| 22 | 22 | ||
| 23 | PrimitiveAssembler(Regs::TriangleTopology topology); | 23 | PrimitiveAssembler(Regs::TriangleTopology topology = Regs::TriangleTopology::List); |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * Queues a vertex, builds primitives from the vertex queue according to the given | 26 | * Queues a vertex, builds primitives from the vertex queue according to the given |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b3dc6aa19..1fadcf5ae 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -190,6 +190,9 @@ void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, | |||
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | void RasterizerOpenGL::DrawTriangles() { | 192 | void RasterizerOpenGL::DrawTriangles() { |
| 193 | if (vertex_batch.empty()) | ||
| 194 | return; | ||
| 195 | |||
| 193 | SyncFramebuffer(); | 196 | SyncFramebuffer(); |
| 194 | SyncDrawState(); | 197 | SyncDrawState(); |
| 195 | 198 | ||