diff options
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 20 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 27 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 9784ee069..4b15ed2f2 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -84,7 +84,7 @@ 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] = Const Buffer Address >> 8. @@ -100,6 +100,24 @@ void Maxwell3D::SetShader(const std::vector<u32>& parameters) { shader.type = shader_type; shader.address = address; shader.cb_address = cb_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_type)].valid.Assign(1); + regs.cb_bind[static_cast<size_t>(shader_type)].index.Assign(1); } } // namespace Engines diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 47df43c97..6eb98080d 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -35,8 +35,10 @@ public: struct Regs { static constexpr size_t NUM_REGS = 0xE36; + static constexpr size_t NumCBData = 16; static constexpr size_t NumVertexArrays = 32; static constexpr size_t MaxShaderProgram = 6; + static constexpr size_t MaxShaderType = 5; enum class QueryMode : u32 { Write = 0, @@ -136,7 +138,27 @@ public: INSERT_PADDING_WORDS(9); } shader_config[MaxShaderProgram]; - INSERT_PADDING_WORDS(0x5D0); + INSERT_PADDING_WORDS(0x8C); + + struct { + u32 cb_size; + u32 cb_address_high; + u32 cb_address_low; + u32 cb_pos; + u32 cb_data[NumCBData]; + } const_buffer; + + INSERT_PADDING_WORDS(0x74); + + struct { + union { + BitField<0, 1, u32> valid; + BitField<4, 5, u32> index; + }; + INSERT_PADDING_WORDS(7); + } cb_bind[MaxShaderType]; + + INSERT_PADDING_WORDS(0x494); struct { u32 set_shader_call; @@ -161,7 +183,7 @@ public: std::array<ShaderInfo, Regs::MaxShaderProgram> shaders; }; - State state; + State state{}; private: MemoryManager& memory_manager; @@ -194,6 +216,7 @@ ASSERT_REG_POSITION(query, 0x6C0); ASSERT_REG_POSITION(vertex_array[0], 0x700); ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); ASSERT_REG_POSITION(shader_config[0], 0x800); +ASSERT_REG_POSITION(const_buffer, 0x8E0); ASSERT_REG_POSITION(set_shader, 0xE24); #undef ASSERT_REG_POSITION |