diff options
author | bunnei <bunneidev@gmail.com> | 2018-03-19 00:45:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-19 00:45:40 +0100 |
commit | 6317a0b2ca5cfd5997d60522554d6f1f6b94a979 (patch) | |
tree | d86384f4fed07fc791541e49b8ef0f7834461c35 /src/video_core/engines | |
parent | Merge pull request #246 from Subv/gpu_macro_calls (diff) | |
parent | GPU: Implement the BindStorageBuffer macro method in HLE. (diff) | |
download | yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar.gz yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar.bz2 yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar.lz yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar.xz yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.tar.zst yuzu-6317a0b2ca5cfd5997d60522554d6f1f6b94a979.zip |
Diffstat (limited to 'src/video_core/engines')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 57 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 19 |
2 files changed, 75 insertions, 1 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 49a138c1d..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<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = { {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}}, + {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}}, }; Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} @@ -83,6 +84,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; @@ -181,6 +201,26 @@ void Maxwell3D::SetShader(const std::vector<u32>& parameters) { ProcessCBBind(shader_stage); } +void Maxwell3D::BindStorageBuffer(const std::vector<u32>& 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<size_t>(stage)]; @@ -194,5 +234,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 diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 05820a21e..3e97d9045 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -166,7 +166,19 @@ public: u32 tex_cb_index; - INSERT_PADDING_WORDS(0x4B3); + INSERT_PADDING_WORDS(0x395); + + struct { + /// Compressed address of a buffer that holds information about bound SSBOs. + /// This address is usually bound to c0 in the shaders. + u32 buffer_address; + + GPUVAddr BufferAddress() const { + return static_cast<GPUVAddr>(buffer_address) << 8; + } + } ssbo_info; + + INSERT_PADDING_WORDS(0x11D); }; std::array<u32, NUM_REGS> reg_array; }; @@ -218,6 +230,9 @@ private: /// Handles a write to the QUERY_GET register. void ProcessQueryGet(); + /// Handles a write to the CB_DATA[i] register. + void ProcessCBData(u32 value); + /// Handles a write to the CB_BIND register. void ProcessCBBind(Regs::ShaderStage stage); @@ -226,6 +241,7 @@ private: /// Method call handlers void SetShader(const std::vector<u32>& parameters); + void BindStorageBuffer(const std::vector<u32>& parameters); struct MethodInfo { const char* name; @@ -249,6 +265,7 @@ ASSERT_REG_POSITION(shader_config[0], 0x800); ASSERT_REG_POSITION(const_buffer, 0x8E0); ASSERT_REG_POSITION(cb_bind[0], 0x904); ASSERT_REG_POSITION(tex_cb_index, 0x982); +ASSERT_REG_POSITION(ssbo_info, 0xD18); #undef ASSERT_REG_POSITION |