diff options
| author | 2018-03-18 15:22:06 -0500 | |
|---|---|---|
| committer | 2018-03-18 16:50:42 -0500 | |
| commit | 7b6868e908319b91785712410b481e9112621175 (patch) | |
| tree | d86384f4fed07fc791541e49b8ef0f7834461c35 /src/video_core | |
| parent | GPU: Handle writes to the CB_DATA method. (diff) | |
| download | yuzu-7b6868e908319b91785712410b481e9112621175.tar.gz yuzu-7b6868e908319b91785712410b481e9112621175.tar.xz yuzu-7b6868e908319b91785712410b481e9112621175.zip | |
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.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 16 |
2 files changed, 36 insertions, 1 deletions
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; | |||
| 13 | 13 | ||
| 14 | const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = { | 14 | const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = { |
| 15 | {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}}, | 15 | {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}}, |
| 16 | {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}}, | ||
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} | 19 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} |
| @@ -200,6 +201,26 @@ void Maxwell3D::SetShader(const std::vector<u32>& parameters) { | |||
| 200 | ProcessCBBind(shader_stage); | 201 | ProcessCBBind(shader_stage); |
| 201 | } | 202 | } |
| 202 | 203 | ||
| 204 | void Maxwell3D::BindStorageBuffer(const std::vector<u32>& parameters) { | ||
| 205 | /** | ||
| 206 | * Parameters description: | ||
| 207 | * [0] = Buffer offset >> 2 | ||
| 208 | */ | ||
| 209 | |||
| 210 | u32 buffer_offset = parameters[0] << 2; | ||
| 211 | |||
| 212 | // Perform the same operations as the real macro code. | ||
| 213 | // Note: This value is hardcoded in the macro's code. | ||
| 214 | static constexpr u32 DefaultCBSize = 0x5F00; | ||
| 215 | regs.const_buffer.cb_size = DefaultCBSize; | ||
| 216 | |||
| 217 | GPUVAddr address = regs.ssbo_info.BufferAddress(); | ||
| 218 | regs.const_buffer.cb_address_high = address >> 32; | ||
| 219 | regs.const_buffer.cb_address_low = address & 0xFFFFFFFF; | ||
| 220 | |||
| 221 | regs.const_buffer.cb_pos = buffer_offset; | ||
| 222 | } | ||
| 223 | |||
| 203 | void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { | 224 | void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { |
| 204 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. | 225 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. |
| 205 | auto& shader = state.shader_stages[static_cast<size_t>(stage)]; | 226 | auto& shader = state.shader_stages[static_cast<size_t>(stage)]; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 93b42b53c..3e97d9045 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -166,7 +166,19 @@ public: | |||
| 166 | 166 | ||
| 167 | u32 tex_cb_index; | 167 | u32 tex_cb_index; |
| 168 | 168 | ||
| 169 | INSERT_PADDING_WORDS(0x4B3); | 169 | INSERT_PADDING_WORDS(0x395); |
| 170 | |||
| 171 | struct { | ||
| 172 | /// Compressed address of a buffer that holds information about bound SSBOs. | ||
| 173 | /// This address is usually bound to c0 in the shaders. | ||
| 174 | u32 buffer_address; | ||
| 175 | |||
| 176 | GPUVAddr BufferAddress() const { | ||
| 177 | return static_cast<GPUVAddr>(buffer_address) << 8; | ||
| 178 | } | ||
| 179 | } ssbo_info; | ||
| 180 | |||
| 181 | INSERT_PADDING_WORDS(0x11D); | ||
| 170 | }; | 182 | }; |
| 171 | std::array<u32, NUM_REGS> reg_array; | 183 | std::array<u32, NUM_REGS> reg_array; |
| 172 | }; | 184 | }; |
| @@ -229,6 +241,7 @@ private: | |||
| 229 | 241 | ||
| 230 | /// Method call handlers | 242 | /// Method call handlers |
| 231 | void SetShader(const std::vector<u32>& parameters); | 243 | void SetShader(const std::vector<u32>& parameters); |
| 244 | void BindStorageBuffer(const std::vector<u32>& parameters); | ||
| 232 | 245 | ||
| 233 | struct MethodInfo { | 246 | struct MethodInfo { |
| 234 | const char* name; | 247 | const char* name; |
| @@ -252,6 +265,7 @@ ASSERT_REG_POSITION(shader_config[0], 0x800); | |||
| 252 | ASSERT_REG_POSITION(const_buffer, 0x8E0); | 265 | ASSERT_REG_POSITION(const_buffer, 0x8E0); |
| 253 | ASSERT_REG_POSITION(cb_bind[0], 0x904); | 266 | ASSERT_REG_POSITION(cb_bind[0], 0x904); |
| 254 | ASSERT_REG_POSITION(tex_cb_index, 0x982); | 267 | ASSERT_REG_POSITION(tex_cb_index, 0x982); |
| 268 | ASSERT_REG_POSITION(ssbo_info, 0xD18); | ||
| 255 | 269 | ||
| 256 | #undef ASSERT_REG_POSITION | 270 | #undef ASSERT_REG_POSITION |
| 257 | 271 | ||