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.
This commit is contained in:
Subv
2018-03-18 15:22:06 -05:00
parent 85d820b1b4
commit 7b6868e908
2 changed files with 36 additions and 1 deletions

View File

@ -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) {}
@ -200,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)];