summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp25
-rw-r--r--src/video_core/engines/maxwell_3d.h23
2 files changed, 41 insertions, 7 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index ce536e29b..ba63b44b4 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -98,6 +98,8 @@ void Maxwell3D::InitializeRegisterDefaults() {
98 regs.framebuffer_srgb = 1; 98 regs.framebuffer_srgb = 1;
99 regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise; 99 regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
100 100
101 shadow_state = regs;
102
101 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true; 103 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
102 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true; 104 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
103 mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; 105 mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
@@ -160,8 +162,17 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
160 ASSERT_MSG(method < Regs::NUM_REGS, 162 ASSERT_MSG(method < Regs::NUM_REGS,
161 "Invalid Maxwell3D register, increase the size of the Regs structure"); 163 "Invalid Maxwell3D register, increase the size of the Regs structure");
162 164
163 if (regs.reg_array[method] != method_call.argument) { 165 u32 arg = method_call.argument;
164 regs.reg_array[method] = method_call.argument; 166 // Keep track of the register value in shadow_state when requested.
167 if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Track ||
168 shadow_state.shadow_ram_control == Regs::ShadowRamControl::TrackWithFilter) {
169 shadow_state.reg_array[method] = arg;
170 } else if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Replay) {
171 arg = shadow_state.reg_array[method];
172 }
173
174 if (regs.reg_array[method] != arg) {
175 regs.reg_array[method] = arg;
165 176
166 for (const auto& table : dirty.tables) { 177 for (const auto& table : dirty.tables) {
167 dirty.flags[table[method]] = true; 178 dirty.flags[table[method]] = true;
@@ -169,12 +180,16 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
169 } 180 }
170 181
171 switch (method) { 182 switch (method) {
183 case MAXWELL3D_REG_INDEX(shadow_ram_control): {
184 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_call.argument);
185 break;
186 }
172 case MAXWELL3D_REG_INDEX(macros.data): { 187 case MAXWELL3D_REG_INDEX(macros.data): {
173 ProcessMacroUpload(method_call.argument); 188 ProcessMacroUpload(arg);
174 break; 189 break;
175 } 190 }
176 case MAXWELL3D_REG_INDEX(macros.bind): { 191 case MAXWELL3D_REG_INDEX(macros.bind): {
177 ProcessMacroBind(method_call.argument); 192 ProcessMacroBind(arg);
178 break; 193 break;
179 } 194 }
180 case MAXWELL3D_REG_INDEX(firmware[4]): { 195 case MAXWELL3D_REG_INDEX(firmware[4]): {
@@ -250,7 +265,7 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
250 } 265 }
251 case MAXWELL3D_REG_INDEX(data_upload): { 266 case MAXWELL3D_REG_INDEX(data_upload): {
252 const bool is_last_call = method_call.IsLastCall(); 267 const bool is_last_call = method_call.IsLastCall();
253 upload_state.ProcessData(method_call.argument, is_last_call); 268 upload_state.ProcessData(arg, is_last_call);
254 if (is_last_call) { 269 if (is_last_call) {
255 OnMemoryWrite(); 270 OnMemoryWrite();
256 } 271 }
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 8a9e9992e..d24c9f657 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -531,6 +531,17 @@ public:
531 Fill = 0x1b02, 531 Fill = 0x1b02,
532 }; 532 };
533 533
534 enum class ShadowRamControl : u32 {
535 // write value to shadow ram
536 Track = 0,
537 // write value to shadow ram ( with validation ??? )
538 TrackWithFilter = 1,
539 // only write to real hw register
540 Passthrough = 2,
541 // write value from shadow ram to real hw register
542 Replay = 3,
543 };
544
534 struct RenderTargetConfig { 545 struct RenderTargetConfig {
535 u32 address_high; 546 u32 address_high;
536 u32 address_low; 547 u32 address_low;
@@ -674,7 +685,9 @@ public:
674 u32 bind; 685 u32 bind;
675 } macros; 686 } macros;
676 687
677 INSERT_UNION_PADDING_WORDS(0x17); 688 ShadowRamControl shadow_ram_control;
689
690 INSERT_UNION_PADDING_WORDS(0x16);
678 691
679 Upload::Registers upload; 692 Upload::Registers upload;
680 struct { 693 struct {
@@ -1263,7 +1276,12 @@ public:
1263 }; 1276 };
1264 std::array<u32, NUM_REGS> reg_array; 1277 std::array<u32, NUM_REGS> reg_array;
1265 }; 1278 };
1266 } regs{}; 1279 };
1280
1281 Regs regs{};
1282
1283 /// Store temporary hw register values, used by some calls to restore state after a operation
1284 Regs shadow_state;
1267 1285
1268 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); 1286 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
1269 static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable"); 1287 static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
@@ -1458,6 +1476,7 @@ private:
1458 "Field " #field_name " has invalid position") 1476 "Field " #field_name " has invalid position")
1459 1477
1460ASSERT_REG_POSITION(macros, 0x45); 1478ASSERT_REG_POSITION(macros, 0x45);
1479ASSERT_REG_POSITION(shadow_ram_control, 0x49);
1461ASSERT_REG_POSITION(upload, 0x60); 1480ASSERT_REG_POSITION(upload, 0x60);
1462ASSERT_REG_POSITION(exec_upload, 0x6C); 1481ASSERT_REG_POSITION(exec_upload, 0x6C);
1463ASSERT_REG_POSITION(data_upload, 0x6D); 1482ASSERT_REG_POSITION(data_upload, 0x6D);