diff options
author | bunnei <bunneidev@gmail.com> | 2018-03-18 02:19:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-18 02:19:39 +0100 |
commit | 29981fa2ebf790a9182c5a8d97084606852d2060 (patch) | |
tree | 371e67d6f7c303c7ddd9bbbbb090247bdc590a14 /src/video_core/engines/maxwell_3d.cpp | |
parent | Merge pull request #242 from Subv/set_shader (diff) | |
parent | GPU: Renamed ShaderType to ShaderStage as that is less confusing. (diff) | |
download | yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.gz yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.bz2 yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.lz yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.xz yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.zst yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.zip |
Diffstat (limited to 'src/video_core/engines/maxwell_3d.cpp')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 73 |
1 files changed, 63 insertions, 10 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 603a2edaf..db12fc702 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<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} void Maxwell3D::CallMethod(u32 method, const std::vector<u32>& 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); @@ -42,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::ShaderStage::Vertex); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[1].raw_config): { + ProcessCBBind(Regs::ShaderStage::TesselationControl); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[2].raw_config): { + ProcessCBBind(Regs::ShaderStage::TesselationEval); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[3].raw_config): { + ProcessCBBind(Regs::ShaderStage::Geometry); + break; + } + case MAXWELL3D_REG_INDEX(cb_bind[4].raw_config): { + ProcessCBBind(Regs::ShaderStage::Fragment); + break; + } case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): { DrawArrays(); break; @@ -83,22 +104,54 @@ void Maxwell3D::SetShader(const std::vector<u32>& 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] = Shader End Address >> 8. + * [3] = Shader Stage. + * [4] = Const Buffer Address >> 8. */ auto shader_program = static_cast<Regs::ShaderProgram>(parameters[0]); // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register. - GPUVAddr begin_address = parameters[2]; - auto shader_type = static_cast<Regs::ShaderType>(parameters[3]); - GPUVAddr end_address = parameters[4] << 8; + GPUVAddr address = parameters[2]; + auto shader_stage = static_cast<Regs::ShaderStage>(parameters[3]); + GPUVAddr cb_address = parameters[4] << 8; - auto& shader = state.shaders[static_cast<size_t>(shader_program)]; + auto& shader = state.shader_programs[static_cast<size_t>(shader_program)]; shader.program = shader_program; - shader.type = shader_type; - shader.begin_address = begin_address; - shader.end_address = end_address; + shader.stage = shader_stage; + shader.address = 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<size_t>(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<size_t>(shader_stage)].valid.Assign(1); + regs.cb_bind[static_cast<size_t>(shader_stage)].index.Assign(1); + + ProcessCBBind(shader_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<size_t>(stage)]; + auto& bind_data = regs.cb_bind[static_cast<size_t>(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 |