From 85d820b1b45396a593e30b7b267ac2001c4f82b7 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 18 Mar 2018 15:19:47 -0500 Subject: GPU: Handle writes to the CB_DATA method. Writing to this method will cause the written value to be stored in the currently-set ConstBuffer plus CB_POS. This method is usually used to upload uniforms or other shader-visible data. --- src/video_core/engines/maxwell_3d.cpp | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (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 49a138c1d..9985e0d50 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -83,6 +83,25 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value."); break; } + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { + ProcessCBData(value); + break; + } case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): { ProcessCBBind(Regs::ShaderStage::Vertex); break; @@ -194,5 +213,22 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { buffer.size = regs.const_buffer.cb_size; } +void Maxwell3D::ProcessCBData(u32 value) { + // Write the input value to the current const buffer at the current position. + GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); + ASSERT(buffer_address != 0); + + // Don't allow writing past the end of the buffer. + ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); + + VAddr address = + memory_manager.PhysicalToVirtualAddress(buffer_address + regs.const_buffer.cb_pos); + + Memory::Write32(address, value); + + // Increment the current buffer position. + regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; +} + } // namespace Engines } // namespace Tegra -- cgit v1.2.3 From 7b6868e908319b91785712410b481e9112621175 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 18 Mar 2018 15:22:06 -0500 Subject: GPU: Implement the BindStorageBuffer macro method in HLE. This macro binds the SSBO Info Buffer as the current ConstBuffer. This buffer is usually bound to c0 during shader execution. Games seem to use this macro instead of directly writing the address for some reason. --- src/video_core/engines/maxwell_3d.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (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 9985e0d50..3a4e88e4e 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -13,6 +13,7 @@ constexpr u32 MacroRegistersStart = 0xE00; const std::unordered_map Maxwell3D::method_handlers = { {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}}, + {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}}, }; Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} @@ -200,6 +201,26 @@ void Maxwell3D::SetShader(const std::vector& parameters) { ProcessCBBind(shader_stage); } +void Maxwell3D::BindStorageBuffer(const std::vector& parameters) { + /** + * Parameters description: + * [0] = Buffer offset >> 2 + */ + + u32 buffer_offset = parameters[0] << 2; + + // Perform the same operations as the real macro code. + // Note: This value is hardcoded in the macro's code. + static constexpr u32 DefaultCBSize = 0x5F00; + regs.const_buffer.cb_size = DefaultCBSize; + + GPUVAddr address = regs.ssbo_info.BufferAddress(); + regs.const_buffer.cb_address_high = address >> 32; + regs.const_buffer.cb_address_low = address & 0xFFFFFFFF; + + regs.const_buffer.cb_pos = buffer_offset; +} + 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)]; -- cgit v1.2.3