diff options
| author | 2019-07-24 17:07:57 -0400 | |
|---|---|---|
| committer | 2019-07-24 17:07:57 -0400 | |
| commit | 9be9600bdcf0119e16d0cbbd7a50dcd2a6137efa (patch) | |
| tree | 7fa8532be550486ba4ef9f7b0a42970212aca175 | |
| parent | Fix README change mistake (#2754) (diff) | |
| parent | maxwell3d: Implement Conditional Rendering (diff) | |
| download | yuzu-9be9600bdcf0119e16d0cbbd7a50dcd2a6137efa.tar.gz yuzu-9be9600bdcf0119e16d0cbbd7a50dcd2a6137efa.tar.xz yuzu-9be9600bdcf0119e16d0cbbd7a50dcd2a6137efa.zip | |
Merge pull request #2704 from FernandoS27/conditional
maxwell3d: Implement Conditional Rendering
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 45 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 |
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 | ||
| 485 | void 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 | |||
| 480 | void Maxwell3D::ProcessSyncPoint() { | 524 | void 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 | |||
| 1226 | private: | 1263 | private: |
| 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); | |||
| 1357 | ASSERT_REG_POSITION(point_size, 0x546); | 1399 | ASSERT_REG_POSITION(point_size, 0x546); |
| 1358 | ASSERT_REG_POSITION(zeta_enable, 0x54E); | 1400 | ASSERT_REG_POSITION(zeta_enable, 0x54E); |
| 1359 | ASSERT_REG_POSITION(multisample_control, 0x54F); | 1401 | ASSERT_REG_POSITION(multisample_control, 0x54F); |
| 1402 | ASSERT_REG_POSITION(condition, 0x554); | ||
| 1360 | ASSERT_REG_POSITION(tsc, 0x557); | 1403 | ASSERT_REG_POSITION(tsc, 0x557); |
| 1361 | ASSERT_REG_POSITION(polygon_offset_factor, 0x55b); | 1404 | ASSERT_REG_POSITION(polygon_offset_factor, 0x55b); |
| 1362 | ASSERT_REG_POSITION(tic, 0x55D); | 1405 | ASSERT_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 | ||
| 597 | void RasterizerOpenGL::Clear() { | 597 | void 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(); |