mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #1461 from yuriks/imm-mode2
Immediate-mode improvements
This commit is contained in:
		
						commit
						a950188c11
					
				@ -75,12 +75,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
            GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
 | 
					            GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E):
 | 
				
			||||||
 | 
					            g_state.primitive_assembler.Reconfigure(regs.triangle_topology);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case PICA_REG_INDEX_WORKAROUND(restart_primitive, 0x25F):
 | 
				
			||||||
 | 
					            g_state.primitive_assembler.Reset();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232):
 | 
					        case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232):
 | 
				
			||||||
            if (regs.vs_default_attributes_setup.index == 15) {
 | 
					            g_state.immediate.current_attribute = 0;
 | 
				
			||||||
                // Reset immediate primitive state
 | 
					            default_attr_counter = 0;
 | 
				
			||||||
                g_state.immediate.primitive_assembler.Reconfigure(regs.triangle_topology);
 | 
					 | 
				
			||||||
                g_state.immediate.attribute_id = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Load default vertex input attributes
 | 
					        // Load default vertex input attributes
 | 
				
			||||||
@ -105,7 +110,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index];
 | 
					                Math::Vec4<float24> attribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // NOTE: The destination component order indeed is "backwards"
 | 
					                // NOTE: The destination component order indeed is "backwards"
 | 
				
			||||||
                attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
 | 
					                attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
 | 
				
			||||||
@ -119,26 +124,29 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // TODO: Verify that this actually modifies the register!
 | 
					                // TODO: Verify that this actually modifies the register!
 | 
				
			||||||
                if (setup.index < 15) {
 | 
					                if (setup.index < 15) {
 | 
				
			||||||
 | 
					                    g_state.vs.default_attributes[setup.index] = attribute;
 | 
				
			||||||
                    setup.index++;
 | 
					                    setup.index++;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    // Put each attribute into an immediate input buffer.
 | 
					                    // Put each attribute into an immediate input buffer.
 | 
				
			||||||
                    // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is
 | 
					                    // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is
 | 
				
			||||||
                    // sent to the primitive assembler.
 | 
					                    // sent to the primitive assembler.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    auto& immediate_input = g_state.immediate.input;
 | 
					                    auto& immediate_input = g_state.immediate.input_vertex;
 | 
				
			||||||
                    auto& immediate_attribute_id = g_state.immediate.attribute_id;
 | 
					                    auto& immediate_attribute_id = g_state.immediate.current_attribute;
 | 
				
			||||||
                    const auto& attribute_config = regs.vertex_attributes;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    immediate_input.attr[immediate_attribute_id++] = attribute;
 | 
					                    immediate_input.attr[immediate_attribute_id++] = attribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (immediate_attribute_id >= attribute_config.GetNumTotalAttributes()) {
 | 
					                    if (immediate_attribute_id >= regs.vs.num_input_attributes+1) {
 | 
				
			||||||
                        immediate_attribute_id = 0;
 | 
					                        immediate_attribute_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        Shader::UnitState<false> shader_unit;
 | 
					                        Shader::UnitState<false> shader_unit;
 | 
				
			||||||
                        Shader::Setup(shader_unit);
 | 
					                        Shader::Setup(shader_unit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (g_debug_context)
 | 
				
			||||||
 | 
					                            g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, static_cast<void*>(&immediate_input));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // Send to vertex shader
 | 
					                        // Send to vertex shader
 | 
				
			||||||
                        Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, attribute_config.GetNumTotalAttributes());
 | 
					                        Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, regs.vs.num_input_attributes+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // Send to renderer
 | 
					                        // Send to renderer
 | 
				
			||||||
                        using Pica::Shader::OutputVertex;
 | 
					                        using Pica::Shader::OutputVertex;
 | 
				
			||||||
@ -146,7 +154,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
                            VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
 | 
					                            VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        g_state.immediate.primitive_assembler.SubmitVertex(output, AddTriangle);
 | 
					                        g_state.primitive_assembler.SubmitVertex(output, AddTriangle);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -154,9 +162,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case PICA_REG_INDEX(gpu_mode):
 | 
					        case PICA_REG_INDEX(gpu_mode):
 | 
				
			||||||
            if (regs.gpu_mode == Regs::GPUMode::Configuring && regs.vs_default_attributes_setup.index == 15) {
 | 
					            if (regs.gpu_mode == Regs::GPUMode::Configuring) {
 | 
				
			||||||
                // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring
 | 
					                // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring
 | 
				
			||||||
                VideoCore::g_renderer->Rasterizer()->DrawTriangles();
 | 
					                VideoCore::g_renderer->Rasterizer()->DrawTriangles();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (g_debug_context) {
 | 
				
			||||||
 | 
					                    g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -241,7 +253,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
            DebugUtils::GeometryDumper geometry_dumper;
 | 
					            DebugUtils::GeometryDumper geometry_dumper;
 | 
				
			||||||
            PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value());
 | 
					            PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            PrimitiveAssembler<Shader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
 | 
					            PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (g_debug_context) {
 | 
					            if (g_debug_context) {
 | 
				
			||||||
                for (int i = 0; i < 3; ++i) {
 | 
					                for (int i = 0; i < 3; ++i) {
 | 
				
			||||||
@ -412,16 +424,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
                                                          range.second, range.first);
 | 
					                                                          range.second, range.first);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            VideoCore::g_renderer->Rasterizer()->DrawTriangles();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if PICA_DUMP_GEOMETRY
 | 
					#if PICA_DUMP_GEOMETRY
 | 
				
			||||||
            geometry_dumper.Dump();
 | 
					            geometry_dumper.Dump();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (g_debug_context) {
 | 
					 | 
				
			||||||
                g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -493,12 +493,25 @@ std::string Regs::GetCommandName(int index) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Init() {
 | 
					void Init() {
 | 
				
			||||||
 | 
					    g_state.Reset();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Shutdown() {
 | 
					void Shutdown() {
 | 
				
			||||||
    Shader::Shutdown();
 | 
					    Shader::Shutdown();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&g_state, 0, sizeof(State));
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void Zero(T& o) {
 | 
				
			||||||
 | 
					    memset(&o, 0, sizeof(o));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void State::Reset() {
 | 
				
			||||||
 | 
					    Zero(regs);
 | 
				
			||||||
 | 
					    Zero(vs);
 | 
				
			||||||
 | 
					    Zero(gs);
 | 
				
			||||||
 | 
					    Zero(cmd_list);
 | 
				
			||||||
 | 
					    Zero(immediate);
 | 
				
			||||||
 | 
					    primitive_assembler.Reconfigure(Regs::TriangleTopology::List);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1123,7 +1123,12 @@ struct Regs {
 | 
				
			|||||||
            BitField<24, 8, u32> w;
 | 
					            BitField<24, 8, u32> w;
 | 
				
			||||||
        } int_uniforms[4];
 | 
					        } int_uniforms[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        INSERT_PADDING_WORDS(0x5);
 | 
					        INSERT_PADDING_WORDS(0x4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            // Number of input attributes to shader unit - 1
 | 
				
			||||||
 | 
					            BitField<0, 4, u32> num_input_attributes;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Offset to shader program entry point (in words)
 | 
					        // Offset to shader program entry point (in words)
 | 
				
			||||||
        BitField<0, 16, u32> main_offset;
 | 
					        BitField<0, 16, u32> main_offset;
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,8 @@ namespace Pica {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Struct used to describe current Pica state
 | 
					/// Struct used to describe current Pica state
 | 
				
			||||||
struct State {
 | 
					struct State {
 | 
				
			||||||
 | 
					    void Reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Pica registers
 | 
					    /// Pica registers
 | 
				
			||||||
    Regs regs;
 | 
					    Regs regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,13 +48,14 @@ struct State {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Struct used to describe immediate mode rendering state
 | 
					    /// Struct used to describe immediate mode rendering state
 | 
				
			||||||
    struct ImmediateModeState {
 | 
					    struct ImmediateModeState {
 | 
				
			||||||
        Shader::InputVertex input;
 | 
					        // Used to buffer partial vertices for immediate-mode rendering.
 | 
				
			||||||
        // This is constructed with a dummy triangle topology
 | 
					        Shader::InputVertex input_vertex;
 | 
				
			||||||
        PrimitiveAssembler<Shader::OutputVertex> primitive_assembler;
 | 
					        // Index of the next attribute to be loaded into `input_vertex`.
 | 
				
			||||||
        int attribute_id = 0;
 | 
					        int current_attribute = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        ImmediateModeState() : primitive_assembler(Regs::TriangleTopology::List) {}
 | 
					 | 
				
			||||||
    } immediate;
 | 
					    } immediate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is constructed with a dummy triangle topology
 | 
				
			||||||
 | 
					    PrimitiveAssembler<Shader::OutputVertex> primitive_assembler;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern State g_state; ///< Current Pica state
 | 
					extern State g_state; ///< Current Pica state
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ struct PrimitiveAssembler {
 | 
				
			|||||||
                                               VertexType& v1,
 | 
					                                               VertexType& v1,
 | 
				
			||||||
                                               VertexType& v2)>;
 | 
					                                               VertexType& v2)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PrimitiveAssembler(Regs::TriangleTopology topology);
 | 
					    PrimitiveAssembler(Regs::TriangleTopology topology = Regs::TriangleTopology::List);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Queues a vertex, builds primitives from the vertex queue according to the given
 | 
					     * Queues a vertex, builds primitives from the vertex queue according to the given
 | 
				
			||||||
 | 
				
			|||||||
@ -190,6 +190,9 @@ void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::DrawTriangles() {
 | 
					void RasterizerOpenGL::DrawTriangles() {
 | 
				
			||||||
 | 
					    if (vertex_batch.empty())
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SyncFramebuffer();
 | 
					    SyncFramebuffer();
 | 
				
			||||||
    SyncDrawState();
 | 
					    SyncDrawState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user