summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-03-17 21:19:39 -0400
committerGravatar GitHub2018-03-17 21:19:39 -0400
commit29981fa2ebf790a9182c5a8d97084606852d2060 (patch)
tree371e67d6f7c303c7ddd9bbbbb090247bdc590a14 /src
parentMerge pull request #242 from Subv/set_shader (diff)
parentGPU: Renamed ShaderType to ShaderStage as that is less confusing. (diff)
downloadyuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.gz
yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.tar.xz
yuzu-29981fa2ebf790a9182c5a8d97084606852d2060.zip
Merge pull request #245 from Subv/set_shader2
GPU: Store shader constbuffer bindings in the GPU state.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp73
-rw-r--r--src/video_core/engines/maxwell_3d.h65
2 files changed, 115 insertions, 23 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 603a2edaf..db12fc702 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -15,6 +15,7 @@ const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers
15Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} 15Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
16 16
17void Maxwell3D::CallMethod(u32 method, const std::vector<u32>& parameters) { 17void Maxwell3D::CallMethod(u32 method, const std::vector<u32>& parameters) {
18 // TODO(Subv): Write an interpreter for the macros uploaded via registers 0x45 and 0x47
18 auto itr = method_handlers.find(method); 19 auto itr = method_handlers.find(method);
19 if (itr == method_handlers.end()) { 20 if (itr == method_handlers.end()) {
20 LOG_ERROR(HW_GPU, "Unhandled method call %08X", method); 21 LOG_ERROR(HW_GPU, "Unhandled method call %08X", method);
@@ -42,6 +43,26 @@ void Maxwell3D::WriteReg(u32 method, u32 value) {
42 ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value."); 43 ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value.");
43 break; 44 break;
44 } 45 }
46 case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): {
47 ProcessCBBind(Regs::ShaderStage::Vertex);
48 break;
49 }
50 case MAXWELL3D_REG_INDEX(cb_bind[1].raw_config): {
51 ProcessCBBind(Regs::ShaderStage::TesselationControl);
52 break;
53 }
54 case MAXWELL3D_REG_INDEX(cb_bind[2].raw_config): {
55 ProcessCBBind(Regs::ShaderStage::TesselationEval);
56 break;
57 }
58 case MAXWELL3D_REG_INDEX(cb_bind[3].raw_config): {
59 ProcessCBBind(Regs::ShaderStage::Geometry);
60 break;
61 }
62 case MAXWELL3D_REG_INDEX(cb_bind[4].raw_config): {
63 ProcessCBBind(Regs::ShaderStage::Fragment);
64 break;
65 }
45 case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): { 66 case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): {
46 DrawArrays(); 67 DrawArrays();
47 break; 68 break;
@@ -83,22 +104,54 @@ void Maxwell3D::SetShader(const std::vector<u32>& parameters) {
83 /** 104 /**
84 * Parameters description: 105 * Parameters description:
85 * [0] = Shader Program. 106 * [0] = Shader Program.
86 * [1] = Unknown. 107 * [1] = Unknown, presumably the shader id.
87 * [2] = Offset to the start of the shader, after the 0x30 bytes header. 108 * [2] = Offset to the start of the shader, after the 0x30 bytes header.
88 * [3] = Shader Type. 109 * [3] = Shader Stage.
89 * [4] = Shader End Address >> 8. 110 * [4] = Const Buffer Address >> 8.
90 */ 111 */
91 auto shader_program = static_cast<Regs::ShaderProgram>(parameters[0]); 112 auto shader_program = static_cast<Regs::ShaderProgram>(parameters[0]);
92 // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register. 113 // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register.
93 GPUVAddr begin_address = parameters[2]; 114 GPUVAddr address = parameters[2];
94 auto shader_type = static_cast<Regs::ShaderType>(parameters[3]); 115 auto shader_stage = static_cast<Regs::ShaderStage>(parameters[3]);
95 GPUVAddr end_address = parameters[4] << 8; 116 GPUVAddr cb_address = parameters[4] << 8;
96 117
97 auto& shader = state.shaders[static_cast<size_t>(shader_program)]; 118 auto& shader = state.shader_programs[static_cast<size_t>(shader_program)];
98 shader.program = shader_program; 119 shader.program = shader_program;
99 shader.type = shader_type; 120 shader.stage = shader_stage;
100 shader.begin_address = begin_address; 121 shader.address = address;
101 shader.end_address = end_address; 122
123 // Perform the same operations as the real macro code.
124 // TODO(Subv): Early exit if register 0xD1C + shader_program contains the same as params[1].
125 auto& shader_regs = regs.shader_config[static_cast<size_t>(shader_program)];
126 shader_regs.start_id = address;
127 // TODO(Subv): Write params[1] to register 0xD1C + shader_program.
128 // TODO(Subv): Write params[2] to register 0xD22 + shader_program.
129
130 // Note: This value is hardcoded in the macro's code.
131 static constexpr u32 DefaultCBSize = 0x10000;
132 regs.const_buffer.cb_size = DefaultCBSize;
133 regs.const_buffer.cb_address_high = cb_address >> 32;
134 regs.const_buffer.cb_address_low = cb_address & 0xFFFFFFFF;
135
136 // Write a hardcoded 0x11 to CB_BIND, this binds the current const buffer to buffer c1[] in the
137 // shader. It's likely that these are the constants for the shader.
138 regs.cb_bind[static_cast<size_t>(shader_stage)].valid.Assign(1);
139 regs.cb_bind[static_cast<size_t>(shader_stage)].index.Assign(1);
140
141 ProcessCBBind(shader_stage);
142}
143
144void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
145 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
146 auto& shader = state.shader_stages[static_cast<size_t>(stage)];
147 auto& bind_data = regs.cb_bind[static_cast<size_t>(stage)];
148
149 auto& buffer = shader.const_buffers[bind_data.index];
150
151 buffer.enabled = bind_data.valid.Value() != 0;
152 buffer.index = bind_data.index;
153 buffer.address = regs.const_buffer.BufferAddress();
154 buffer.size = regs.const_buffer.cb_size;
102} 155}
103 156
104} // namespace Engines 157} // namespace Engines
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index c979d4e61..98137f94b 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -35,8 +35,12 @@ public:
35 struct Regs { 35 struct Regs {
36 static constexpr size_t NUM_REGS = 0xE36; 36 static constexpr size_t NUM_REGS = 0xE36;
37 37
38 static constexpr size_t NumCBData = 16;
38 static constexpr size_t NumVertexArrays = 32; 39 static constexpr size_t NumVertexArrays = 32;
39 static constexpr size_t MaxShaderProgram = 6; 40 static constexpr size_t MaxShaderProgram = 6;
41 static constexpr size_t MaxShaderStage = 5;
42 // Maximum number of const buffers per shader stage.
43 static constexpr size_t MaxConstBuffers = 16;
40 44
41 enum class QueryMode : u32 { 45 enum class QueryMode : u32 {
42 Write = 0, 46 Write = 0,
@@ -52,7 +56,7 @@ public:
52 Fragment = 5, 56 Fragment = 5,
53 }; 57 };
54 58
55 enum class ShaderType : u32 { 59 enum class ShaderStage : u32 {
56 Vertex = 0, 60 Vertex = 0,
57 TesselationControl = 1, 61 TesselationControl = 1,
58 TesselationEval = 2, 62 TesselationEval = 2,
@@ -132,17 +136,37 @@ public:
132 u32 start_id; 136 u32 start_id;
133 INSERT_PADDING_WORDS(1); 137 INSERT_PADDING_WORDS(1);
134 u32 gpr_alloc; 138 u32 gpr_alloc;
135 ShaderType type; 139 ShaderStage type;
136 INSERT_PADDING_WORDS(9); 140 INSERT_PADDING_WORDS(9);
137 } shader_config[MaxShaderProgram]; 141 } shader_config[MaxShaderProgram];
138 142
139 INSERT_PADDING_WORDS(0x5D0); 143 INSERT_PADDING_WORDS(0x8C);
140 144
141 struct { 145 struct {
142 u32 shader_code_call; 146 u32 cb_size;
143 u32 shader_code_args; 147 u32 cb_address_high;
144 } shader_code; 148 u32 cb_address_low;
149 u32 cb_pos;
150 u32 cb_data[NumCBData];
151
152 GPUVAddr BufferAddress() const {
153 return static_cast<GPUVAddr>(
154 (static_cast<GPUVAddr>(cb_address_high) << 32) | cb_address_low);
155 }
156 } const_buffer;
157
145 INSERT_PADDING_WORDS(0x10); 158 INSERT_PADDING_WORDS(0x10);
159
160 struct {
161 union {
162 u32 raw_config;
163 BitField<0, 1, u32> valid;
164 BitField<4, 5, u32> index;
165 };
166 INSERT_PADDING_WORDS(7);
167 } cb_bind[MaxShaderStage];
168
169 INSERT_PADDING_WORDS(0x50A);
146 }; 170 };
147 std::array<u32, NUM_REGS> reg_array; 171 std::array<u32, NUM_REGS> reg_array;
148 }; 172 };
@@ -151,17 +175,28 @@ public:
151 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); 175 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
152 176
153 struct State { 177 struct State {
154 struct ShaderInfo { 178 struct ConstBufferInfo {
155 Regs::ShaderType type; 179 GPUVAddr address;
180 u32 index;
181 u32 size;
182 bool enabled;
183 };
184
185 struct ShaderProgramInfo {
186 Regs::ShaderStage stage;
156 Regs::ShaderProgram program; 187 Regs::ShaderProgram program;
157 GPUVAddr begin_address; 188 GPUVAddr address;
158 GPUVAddr end_address;
159 }; 189 };
160 190
161 std::array<ShaderInfo, Regs::MaxShaderProgram> shaders; 191 struct ShaderStageInfo {
192 std::array<ConstBufferInfo, Regs::MaxConstBuffers> const_buffers;
193 };
194
195 std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages;
196 std::array<ShaderProgramInfo, Regs::MaxShaderProgram> shader_programs;
162 }; 197 };
163 198
164 State state; 199 State state{};
165 200
166private: 201private:
167 MemoryManager& memory_manager; 202 MemoryManager& memory_manager;
@@ -169,6 +204,9 @@ private:
169 /// Handles a write to the QUERY_GET register. 204 /// Handles a write to the QUERY_GET register.
170 void ProcessQueryGet(); 205 void ProcessQueryGet();
171 206
207 /// Handles a write to the CB_BIND register.
208 void ProcessCBBind(Regs::ShaderStage stage);
209
172 /// Handles a write to the VERTEX_END_GL register, triggering a draw. 210 /// Handles a write to the VERTEX_END_GL register, triggering a draw.
173 void DrawArrays(); 211 void DrawArrays();
174 212
@@ -194,7 +232,8 @@ ASSERT_REG_POSITION(query, 0x6C0);
194ASSERT_REG_POSITION(vertex_array[0], 0x700); 232ASSERT_REG_POSITION(vertex_array[0], 0x700);
195ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); 233ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0);
196ASSERT_REG_POSITION(shader_config[0], 0x800); 234ASSERT_REG_POSITION(shader_config[0], 0x800);
197ASSERT_REG_POSITION(shader_code, 0xE24); 235ASSERT_REG_POSITION(const_buffer, 0x8E0);
236ASSERT_REG_POSITION(cb_bind[0], 0x904);
198 237
199#undef ASSERT_REG_POSITION 238#undef ASSERT_REG_POSITION
200 239