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 8755b8af4..20a6282ad 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -249,6 +249,10 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
249 ProcessQueryGet(); 249 ProcessQueryGet();
250 break; 250 break;
251 } 251 }
252 case MAXWELL3D_REG_INDEX(condition.mode): {
253 ProcessQueryCondition();
254 break;
255 }
252 case MAXWELL3D_REG_INDEX(sync_info): { 256 case MAXWELL3D_REG_INDEX(sync_info): {
253 ProcessSyncPoint(); 257 ProcessSyncPoint();
254 break; 258 break;
@@ -302,6 +306,7 @@ void Maxwell3D::ProcessQueryGet() {
302 result = regs.query.query_sequence; 306 result = regs.query.query_sequence;
303 break; 307 break;
304 default: 308 default:
309 result = 1;
305 UNIMPLEMENTED_MSG("Unimplemented query select type {}", 310 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
306 static_cast<u32>(regs.query.query_get.select.Value())); 311 static_cast<u32>(regs.query.query_get.select.Value()));
307 } 312 }
@@ -342,6 +347,45 @@ void Maxwell3D::ProcessQueryGet() {
342 } 347 }
343} 348}
344 349
350void Maxwell3D::ProcessQueryCondition() {
351 const GPUVAddr condition_address{regs.condition.Address()};
352 switch (regs.condition.mode) {
353 case Regs::ConditionMode::Always: {
354 execute_on = true;
355 break;
356 }
357 case Regs::ConditionMode::Never: {
358 execute_on = false;
359 break;
360 }
361 case Regs::ConditionMode::ResNonZero: {
362 Regs::QueryCompare cmp;
363 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
364 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
365 break;
366 }
367 case Regs::ConditionMode::Equal: {
368 Regs::QueryCompare cmp;
369 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
370 execute_on =
371 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
372 break;
373 }
374 case Regs::ConditionMode::NotEqual: {
375 Regs::QueryCompare cmp;
376 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp));
377 execute_on =
378 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
379 break;
380 }
381 default: {
382 UNIMPLEMENTED_MSG("Uninplemented Condition Mode!");
383 execute_on = true;
384 break;
385 }
386 }
387}
388
345void Maxwell3D::ProcessSyncPoint() { 389void Maxwell3D::ProcessSyncPoint() {
346 const u32 sync_point = regs.sync_info.sync_point.Value(); 390 const u32 sync_point = regs.sync_info.sync_point.Value();
347 const u32 increment = regs.sync_info.increment.Value(); 391 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 8d15c8a48..1e3e72bfd 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;
@@ -1169,6 +1202,10 @@ public:
1169 return macro_memory; 1202 return macro_memory;
1170 } 1203 }
1171 1204
1205 bool ShouldExecute() const {
1206 return execute_on;
1207 }
1208
1172private: 1209private:
1173 void InitializeRegisterDefaults(); 1210 void InitializeRegisterDefaults();
1174 1211
@@ -1194,6 +1231,8 @@ private:
1194 1231
1195 Upload::State upload_state; 1232 Upload::State upload_state;
1196 1233
1234 bool execute_on{true};
1235
1197 /// Retrieves information about a specific TIC entry from the TIC buffer. 1236 /// Retrieves information about a specific TIC entry from the TIC buffer.
1198 Texture::TICEntry GetTICEntry(u32 tic_index) const; 1237 Texture::TICEntry GetTICEntry(u32 tic_index) const;
1199 1238
@@ -1219,6 +1258,9 @@ private:
1219 /// Handles a write to the QUERY_GET register. 1258 /// Handles a write to the QUERY_GET register.
1220 void ProcessQueryGet(); 1259 void ProcessQueryGet();
1221 1260
1261 // Handles Conditional Rendering
1262 void ProcessQueryCondition();
1263
1222 /// Handles writes to syncing register. 1264 /// Handles writes to syncing register.
1223 void ProcessSyncPoint(); 1265 void ProcessSyncPoint();
1224 1266
@@ -1290,6 +1332,7 @@ ASSERT_REG_POSITION(clip_distance_enabled, 0x544);
1290ASSERT_REG_POSITION(point_size, 0x546); 1332ASSERT_REG_POSITION(point_size, 0x546);
1291ASSERT_REG_POSITION(zeta_enable, 0x54E); 1333ASSERT_REG_POSITION(zeta_enable, 0x54E);
1292ASSERT_REG_POSITION(multisample_control, 0x54F); 1334ASSERT_REG_POSITION(multisample_control, 0x54F);
1335ASSERT_REG_POSITION(condition, 0x554);
1293ASSERT_REG_POSITION(tsc, 0x557); 1336ASSERT_REG_POSITION(tsc, 0x557);
1294ASSERT_REG_POSITION(polygon_offset_factor, 0x55b); 1337ASSERT_REG_POSITION(polygon_offset_factor, 0x55b);
1295ASSERT_REG_POSITION(tic, 0x55D); 1338ASSERT_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 0bb5c068c..6851a64fa 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -520,7 +520,13 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
520} 520}
521 521
522void RasterizerOpenGL::Clear() { 522void RasterizerOpenGL::Clear() {
523 const auto& regs = system.GPU().Maxwell3D().regs; 523 const auto& maxwell3d = system.GPU().Maxwell3D();
524
525 if (!maxwell3d.ShouldExecute()) {
526 return;
527 }
528
529 const auto& regs = maxwell3d.regs;
524 bool use_color{}; 530 bool use_color{};
525 bool use_depth{}; 531 bool use_depth{};
526 bool use_stencil{}; 532 bool use_stencil{};
@@ -616,6 +622,11 @@ void RasterizerOpenGL::DrawArrays() {
616 622
617 MICROPROFILE_SCOPE(OpenGL_Drawing); 623 MICROPROFILE_SCOPE(OpenGL_Drawing);
618 auto& gpu = system.GPU().Maxwell3D(); 624 auto& gpu = system.GPU().Maxwell3D();
625
626 if (!gpu.ShouldExecute()) {
627 return;
628 }
629
619 const auto& regs = gpu.regs; 630 const auto& regs = gpu.regs;
620 631
621 SyncColorMask(); 632 SyncColorMask();