From 579000e747413b9af3860c0b92e143d4ddc44e36 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 17 Mar 2018 13:55:42 -0500 Subject: GPU: Corrected the parameter documentation for the SetShader macro call. Register 0xE24 is actually a macro that sets some shader parameters in the register structure. Macros are uploaded to the GPU at startup and have their own ISA, we'll probably write an interpreter for this in the future. --- src/video_core/engines/maxwell_3d.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/video_core/engines/maxwell_3d.cpp') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 603a2edaf..9784ee069 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -15,6 +15,7 @@ const std::unordered_map Maxwell3D::method_handlers Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} void Maxwell3D::CallMethod(u32 method, const std::vector& parameters) { + // TODO(Subv): Write an interpreter for the macros uploaded via registers 0x45 and 0x47 auto itr = method_handlers.find(method); if (itr == method_handlers.end()) { LOG_ERROR(HW_GPU, "Unhandled method call %08X", method); @@ -86,19 +87,19 @@ void Maxwell3D::SetShader(const std::vector& parameters) { * [1] = Unknown. * [2] = Offset to the start of the shader, after the 0x30 bytes header. * [3] = Shader Type. - * [4] = Shader End Address >> 8. + * [4] = Const Buffer Address >> 8. */ auto shader_program = static_cast(parameters[0]); // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register. - GPUVAddr begin_address = parameters[2]; + GPUVAddr address = parameters[2]; auto shader_type = static_cast(parameters[3]); - GPUVAddr end_address = parameters[4] << 8; + GPUVAddr cb_address = parameters[4] << 8; auto& shader = state.shaders[static_cast(shader_program)]; shader.program = shader_program; shader.type = shader_type; - shader.begin_address = begin_address; - shader.end_address = end_address; + shader.address = address; + shader.cb_address = cb_address; } } // namespace Engines -- cgit v1.2.3 From 1d9d9c16e8d05837e7f80c533190da27fb298d8b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 17 Mar 2018 16:17:45 -0500 Subject: GPU: Make the SetShader macro call do the same as the real macro's code. It'll now set the CB_SIZE, CB_ADDRESS and CB_BIND registers when it's called. Presumably this SetShader function is binding the constant shader uniforms to buffer 1 (c1[]). --- src/video_core/engines/maxwell_3d.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/video_core/engines/maxwell_3d.cpp') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 9784ee069..4b15ed2f2 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -84,7 +84,7 @@ void Maxwell3D::SetShader(const std::vector& parameters) { /** * Parameters description: * [0] = Shader Program. - * [1] = Unknown. + * [1] = Unknown, presumably the shader id. * [2] = Offset to the start of the shader, after the 0x30 bytes header. * [3] = Shader Type. * [4] = Const Buffer Address >> 8. @@ -100,6 +100,24 @@ void Maxwell3D::SetShader(const std::vector& parameters) { shader.type = shader_type; shader.address = address; shader.cb_address = cb_address; + + // Perform the same operations as the real macro code. + // TODO(Subv): Early exit if register 0xD1C + shader_program contains the same as params[1]. + auto& shader_regs = regs.shader_config[static_cast(shader_program)]; + shader_regs.start_id = address; + // TODO(Subv): Write params[1] to register 0xD1C + shader_program. + // TODO(Subv): Write params[2] to register 0xD22 + shader_program. + + // Note: This value is hardcoded in the macro's code. + static constexpr u32 DefaultCBSize = 0x10000; + regs.const_buffer.cb_size = DefaultCBSize; + regs.const_buffer.cb_address_high = cb_address >> 32; + regs.const_buffer.cb_address_low = cb_address & 0xFFFFFFFF; + + // Write a hardcoded 0x11 to CB_BIND, this binds the current const buffer to buffer c1[] in the + // shader. It's likely that these are the constants for the shader. + regs.cb_bind[static_cast(shader_type)].valid.Assign(1); + regs.cb_bind[static_cast(shader_type)].index.Assign(1); } } // namespace Engines -- cgit v1.2.3 From 88698c156ffe567885f154c80270db962d29e82b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 17 Mar 2018 17:06:23 -0500 Subject: GPU: Store shader constbuffer bindings in the GPU state. --- src/video_core/engines/maxwell_3d.cpp | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'src/video_core/engines/maxwell_3d.cpp') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 4b15ed2f2..50153eff3 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -43,6 +43,26 @@ void Maxwell3D::WriteReg(u32 method, u32 value) { ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value."); break; } + case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): { + ProcessCBBind(Regs::ShaderType::Vertex); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[1].raw_config): { + ProcessCBBind(Regs::ShaderType::TesselationControl); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[2].raw_config): { + ProcessCBBind(Regs::ShaderType::TesselationEval); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[3].raw_config): { + ProcessCBBind(Regs::ShaderType::Geometry); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[4].raw_config): { + ProcessCBBind(Regs::ShaderType::Fragment); + break; + } case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): { DrawArrays(); break; @@ -95,11 +115,10 @@ void Maxwell3D::SetShader(const std::vector& parameters) { auto shader_type = static_cast(parameters[3]); GPUVAddr cb_address = parameters[4] << 8; - auto& shader = state.shaders[static_cast(shader_program)]; + auto& shader = state.shader_programs[static_cast(shader_program)]; shader.program = shader_program; shader.type = shader_type; shader.address = address; - shader.cb_address = cb_address; // Perform the same operations as the real macro code. // TODO(Subv): Early exit if register 0xD1C + shader_program contains the same as params[1]. @@ -118,6 +137,21 @@ void Maxwell3D::SetShader(const std::vector& parameters) { // shader. It's likely that these are the constants for the shader. regs.cb_bind[static_cast(shader_type)].valid.Assign(1); regs.cb_bind[static_cast(shader_type)].index.Assign(1); + + ProcessCBBind(shader_type); +} + +void Maxwell3D::ProcessCBBind(Regs::ShaderType stage) { + // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. + auto& shader = state.shader_stages[static_cast(stage)]; + auto& bind_data = regs.cb_bind[static_cast(stage)]; + + auto& buffer = shader.const_buffers[bind_data.index]; + + buffer.enabled = bind_data.valid.Value() != 0; + buffer.index = bind_data.index; + buffer.address = regs.const_buffer.BufferAddress(); + buffer.size = regs.const_buffer.cb_size; } } // namespace Engines -- cgit v1.2.3 From ccb8da15129bc04017eb5da2ee67f6cdce22e320 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 17 Mar 2018 17:08:26 -0500 Subject: GPU: Renamed ShaderType to ShaderStage as that is less confusing. --- src/video_core/engines/maxwell_3d.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/video_core/engines/maxwell_3d.cpp') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 50153eff3..db12fc702 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -44,23 +44,23 @@ void Maxwell3D::WriteReg(u32 method, u32 value) { break; } case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): { - ProcessCBBind(Regs::ShaderType::Vertex); + ProcessCBBind(Regs::ShaderStage::Vertex); break; } case MAXWELL3D_REG_INDEX(cb_bind[1].raw_config): { - ProcessCBBind(Regs::ShaderType::TesselationControl); + ProcessCBBind(Regs::ShaderStage::TesselationControl); break; } case MAXWELL3D_REG_INDEX(cb_bind[2].raw_config): { - ProcessCBBind(Regs::ShaderType::TesselationEval); + ProcessCBBind(Regs::ShaderStage::TesselationEval); break; } case MAXWELL3D_REG_INDEX(cb_bind[3].raw_config): { - ProcessCBBind(Regs::ShaderType::Geometry); + ProcessCBBind(Regs::ShaderStage::Geometry); break; } case MAXWELL3D_REG_INDEX(cb_bind[4].raw_config): { - ProcessCBBind(Regs::ShaderType::Fragment); + ProcessCBBind(Regs::ShaderStage::Fragment); break; } case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): { @@ -106,18 +106,18 @@ void Maxwell3D::SetShader(const std::vector& parameters) { * [0] = Shader Program. * [1] = Unknown, presumably the shader id. * [2] = Offset to the start of the shader, after the 0x30 bytes header. - * [3] = Shader Type. + * [3] = Shader Stage. * [4] = Const Buffer Address >> 8. */ auto shader_program = static_cast(parameters[0]); // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register. GPUVAddr address = parameters[2]; - auto shader_type = static_cast(parameters[3]); + auto shader_stage = static_cast(parameters[3]); GPUVAddr cb_address = parameters[4] << 8; auto& shader = state.shader_programs[static_cast(shader_program)]; shader.program = shader_program; - shader.type = shader_type; + shader.stage = shader_stage; shader.address = address; // Perform the same operations as the real macro code. @@ -135,13 +135,13 @@ void Maxwell3D::SetShader(const std::vector& parameters) { // Write a hardcoded 0x11 to CB_BIND, this binds the current const buffer to buffer c1[] in the // shader. It's likely that these are the constants for the shader. - regs.cb_bind[static_cast(shader_type)].valid.Assign(1); - regs.cb_bind[static_cast(shader_type)].index.Assign(1); + regs.cb_bind[static_cast(shader_stage)].valid.Assign(1); + regs.cb_bind[static_cast(shader_stage)].index.Assign(1); - ProcessCBBind(shader_type); + ProcessCBBind(shader_stage); } -void Maxwell3D::ProcessCBBind(Regs::ShaderType stage) { +void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. auto& shader = state.shader_stages[static_cast(stage)]; auto& bind_data = regs.cb_bind[static_cast(stage)]; -- cgit v1.2.3