summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp44
-rw-r--r--src/video_core/engines/maxwell_3d.h45
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp13
3 files changed, 100 insertions, 2 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index fe9fc0278..74c46ec04 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -385,6 +385,10 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
385 ProcessQueryGet(); 385 ProcessQueryGet();
386 break; 386 break;
387 } 387 }
388 case MAXWELL3D_REG_INDEX(condition.mode): {
389 ProcessQueryCondition();
390 break;
391 }
388 case MAXWELL3D_REG_INDEX(sync_info): { 392 case MAXWELL3D_REG_INDEX(sync_info): {
389 ProcessSyncPoint(); 393 ProcessSyncPoint();
390 break; 394 break;
@@ -438,6 +442,7 @@ void Maxwell3D::ProcessQueryGet() {
438 result = regs.query.query_sequence; 442 result = regs.query.query_sequence;
439 break; 443 break;
440 default: 444 default:
445 result = 1;
441 UNIMPLEMENTED_MSG("Unimplemented query select type {}", 446 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
442 static_cast<u32>(regs.query.query_get.select.Value())); 447 static_cast<u32>(regs.query.query_get.select.Value()));
443 } 448 }
@@ -477,6 +482,45 @@ void Maxwell3D::ProcessQueryGet() {
477 } 482 }
478} 483}
479 484
485void Maxwell3D::ProcessQueryCondition() {
486 const GPUVAddr condition_address{regs.condition.Address()};
487 switch (regs.condition.mode) {
488 case Regs::ConditionMode::Always: {
489 execute_on = true;
490 break;
491 }
492 case Regs::ConditionMode::Never: {
493 execute_on = false;
494 break;
495 }
496 case Regs::ConditionMode::ResNonZero: {
497 Regs::QueryCompare cmp;
498 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
499 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
500 break;
501 }
502 case Regs::ConditionMode::Equal: {
503 Regs::QueryCompare cmp;
504 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
505 execute_on =
506 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
507 break;
508 }
509 case Regs::ConditionMode::NotEqual: {
510 Regs::QueryCompare cmp;
511 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
512 execute_on =
513 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
514 break;
515 }
516 default: {
517 UNIMPLEMENTED_MSG("Uninplemented Condition Mode!");
518 execute_on = true;
519 break;
520 }
521 }
522}
523
480void Maxwell3D::ProcessSyncPoint() { 524void Maxwell3D::ProcessSyncPoint() {
481 const u32 sync_point = regs.sync_info.sync_point.Value(); 525 const u32 sync_point = regs.sync_info.sync_point.Value();
482 const u32 increment = regs.sync_info.increment.Value(); 526 const u32 increment = regs.sync_info.increment.Value();
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index ac300bf76..1ee982b76 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -90,6 +90,20 @@ public:
90 90
91 enum class QuerySelect : u32 { 91 enum class QuerySelect : u32 {
92 Zero = 0, 92 Zero = 0,
93 TimeElapsed = 2,
94 TransformFeedbackPrimitivesGenerated = 11,
95 PrimitivesGenerated = 18,
96 SamplesPassed = 21,
97 TransformFeedbackUnknown = 26,
98 };
99
100 struct QueryCompare {
101 u32 initial_sequence;
102 u32 initial_mode;
103 u32 unknown1;
104 u32 unknown2;
105 u32 current_sequence;
106 u32 current_mode;
93 }; 107 };
94 108
95 enum class QuerySyncCondition : u32 { 109 enum class QuerySyncCondition : u32 {
@@ -97,6 +111,14 @@ public:
97 GreaterThan = 1, 111 GreaterThan = 1,
98 }; 112 };
99 113
114 enum class ConditionMode : u32 {
115 Never = 0,
116 Always = 1,
117 ResNonZero = 2,
118 Equal = 3,
119 NotEqual = 4,
120 };
121
100 enum class ShaderProgram : u32 { 122 enum class ShaderProgram : u32 {
101 VertexA = 0, 123 VertexA = 0,
102 VertexB = 1, 124 VertexB = 1,
@@ -815,7 +837,18 @@ public:
815 BitField<4, 1, u32> alpha_to_one; 837 BitField<4, 1, u32> alpha_to_one;
816 } multisample_control; 838 } multisample_control;
817 839
818 INSERT_PADDING_WORDS(0x7); 840 INSERT_PADDING_WORDS(0x4);
841
842 struct {
843 u32 address_high;
844 u32 address_low;
845 ConditionMode mode;
846
847 GPUVAddr Address() const {
848 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
849 address_low);
850 }
851 } condition;
819 852
820 struct { 853 struct {
821 u32 tsc_address_high; 854 u32 tsc_address_high;
@@ -1223,6 +1256,10 @@ public:
1223 return macro_memory; 1256 return macro_memory;
1224 } 1257 }
1225 1258
1259 bool ShouldExecute() const {
1260 return execute_on;
1261 }
1262
1226private: 1263private:
1227 void InitializeRegisterDefaults(); 1264 void InitializeRegisterDefaults();
1228 1265
@@ -1257,6 +1294,8 @@ private:
1257 1294
1258 Upload::State upload_state; 1295 Upload::State upload_state;
1259 1296
1297 bool execute_on{true};
1298
1260 /// Retrieves information about a specific TIC entry from the TIC buffer. 1299 /// Retrieves information about a specific TIC entry from the TIC buffer.
1261 Texture::TICEntry GetTICEntry(u32 tic_index) const; 1300 Texture::TICEntry GetTICEntry(u32 tic_index) const;
1262 1301
@@ -1284,6 +1323,9 @@ private:
1284 /// Handles a write to the QUERY_GET register. 1323 /// Handles a write to the QUERY_GET register.
1285 void ProcessQueryGet(); 1324 void ProcessQueryGet();
1286 1325
1326 // Handles Conditional Rendering
1327 void ProcessQueryCondition();
1328
1287 /// Handles writes to syncing register. 1329 /// Handles writes to syncing register.
1288 void ProcessSyncPoint(); 1330 void ProcessSyncPoint();
1289 1331
@@ -1357,6 +1399,7 @@ ASSERT_REG_POSITION(clip_distance_enabled, 0x544);
1357ASSERT_REG_POSITION(point_size, 0x546); 1399ASSERT_REG_POSITION(point_size, 0x546);
1358ASSERT_REG_POSITION(zeta_enable, 0x54E); 1400ASSERT_REG_POSITION(zeta_enable, 0x54E);
1359ASSERT_REG_POSITION(multisample_control, 0x54F); 1401ASSERT_REG_POSITION(multisample_control, 0x54F);
1402ASSERT_REG_POSITION(condition, 0x554);
1360ASSERT_REG_POSITION(tsc, 0x557); 1403ASSERT_REG_POSITION(tsc, 0x557);
1361ASSERT_REG_POSITION(polygon_offset_factor, 0x55b); 1404ASSERT_REG_POSITION(polygon_offset_factor, 0x55b);
1362ASSERT_REG_POSITION(tic, 0x55D); 1405ASSERT_REG_POSITION(tic, 0x55D);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index c59e687b6..c28ae795c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -595,7 +595,13 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, boo
595} 595}
596 596
597void RasterizerOpenGL::Clear() { 597void RasterizerOpenGL::Clear() {
598 const auto& regs = system.GPU().Maxwell3D().regs; 598 const auto& maxwell3d = system.GPU().Maxwell3D();
599
600 if (!maxwell3d.ShouldExecute()) {
601 return;
602 }
603
604 const auto& regs = maxwell3d.regs;
599 bool use_color{}; 605 bool use_color{};
600 bool use_depth{}; 606 bool use_depth{};
601 bool use_stencil{}; 607 bool use_stencil{};
@@ -697,6 +703,11 @@ void RasterizerOpenGL::DrawArrays() {
697 703
698 MICROPROFILE_SCOPE(OpenGL_Drawing); 704 MICROPROFILE_SCOPE(OpenGL_Drawing);
699 auto& gpu = system.GPU().Maxwell3D(); 705 auto& gpu = system.GPU().Maxwell3D();
706
707 if (!gpu.ShouldExecute()) {
708 return;
709 }
710
700 const auto& regs = gpu.regs; 711 const auto& regs = gpu.regs;
701 712
702 SyncColorMask(); 713 SyncColorMask();