diff options
| author | 2020-03-13 10:08:57 -0400 | |
|---|---|---|
| committer | 2020-03-13 10:08:57 -0400 | |
| commit | b30b1f741dcbcb69672d065b0bec4f4a9e5f0993 (patch) | |
| tree | b8416dffe6beb924c574ef25755aad12db0a68fb /src | |
| parent | Merge pull request #3483 from namkazt/patch-1 (diff) | |
| parent | gl_rasterizer: Implement polygon modes and fill rectangles (diff) | |
| download | yuzu-b30b1f741dcbcb69672d065b0bec4f4a9e5f0993.tar.gz yuzu-b30b1f741dcbcb69672d065b0bec4f4a9e5f0993.tar.xz yuzu-b30b1f741dcbcb69672d065b0bec4f4a9e5f0993.zip | |
Merge pull request #3491 from ReinUsesLisp/polygon-modes
gl_rasterizer: Implement polygon modes and fill rectangles
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 40 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 2 |
7 files changed, 99 insertions, 2 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 491cff370..ed7fc8fdd 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -524,6 +524,12 @@ public: | |||
| 524 | FractionalEven = 2, | 524 | FractionalEven = 2, |
| 525 | }; | 525 | }; |
| 526 | 526 | ||
| 527 | enum class PolygonMode : u32 { | ||
| 528 | Point = 0x1b00, | ||
| 529 | Line = 0x1b01, | ||
| 530 | Fill = 0x1b02, | ||
| 531 | }; | ||
| 532 | |||
| 527 | struct RenderTargetConfig { | 533 | struct RenderTargetConfig { |
| 528 | u32 address_high; | 534 | u32 address_high; |
| 529 | u32 address_low; | 535 | u32 address_low; |
| @@ -705,7 +711,12 @@ public: | |||
| 705 | 711 | ||
| 706 | s32 clear_stencil; | 712 | s32 clear_stencil; |
| 707 | 713 | ||
| 708 | INSERT_UNION_PADDING_WORDS(0x7); | 714 | INSERT_UNION_PADDING_WORDS(0x2); |
| 715 | |||
| 716 | PolygonMode polygon_mode_front; | ||
| 717 | PolygonMode polygon_mode_back; | ||
| 718 | |||
| 719 | INSERT_UNION_PADDING_WORDS(0x3); | ||
| 709 | 720 | ||
| 710 | u32 polygon_offset_point_enable; | 721 | u32 polygon_offset_point_enable; |
| 711 | u32 polygon_offset_line_enable; | 722 | u32 polygon_offset_line_enable; |
| @@ -764,7 +775,11 @@ public: | |||
| 764 | BitField<12, 4, u32> viewport; | 775 | BitField<12, 4, u32> viewport; |
| 765 | } clear_flags; | 776 | } clear_flags; |
| 766 | 777 | ||
| 767 | INSERT_UNION_PADDING_WORDS(0x19); | 778 | INSERT_UNION_PADDING_WORDS(0x10); |
| 779 | |||
| 780 | u32 fill_rectangle; | ||
| 781 | |||
| 782 | INSERT_UNION_PADDING_WORDS(0x8); | ||
| 768 | 783 | ||
| 769 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; | 784 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; |
| 770 | 785 | ||
| @@ -1422,6 +1437,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F); | |||
| 1422 | ASSERT_REG_POSITION(clear_color[0], 0x360); | 1437 | ASSERT_REG_POSITION(clear_color[0], 0x360); |
| 1423 | ASSERT_REG_POSITION(clear_depth, 0x364); | 1438 | ASSERT_REG_POSITION(clear_depth, 0x364); |
| 1424 | ASSERT_REG_POSITION(clear_stencil, 0x368); | 1439 | ASSERT_REG_POSITION(clear_stencil, 0x368); |
| 1440 | ASSERT_REG_POSITION(polygon_mode_front, 0x36B); | ||
| 1441 | ASSERT_REG_POSITION(polygon_mode_back, 0x36C); | ||
| 1425 | ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); | 1442 | ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); |
| 1426 | ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); | 1443 | ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); |
| 1427 | ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); | 1444 | ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); |
| @@ -1435,6 +1452,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); | |||
| 1435 | ASSERT_REG_POSITION(depth_bounds, 0x3E7); | 1452 | ASSERT_REG_POSITION(depth_bounds, 0x3E7); |
| 1436 | ASSERT_REG_POSITION(zeta, 0x3F8); | 1453 | ASSERT_REG_POSITION(zeta, 0x3F8); |
| 1437 | ASSERT_REG_POSITION(clear_flags, 0x43E); | 1454 | ASSERT_REG_POSITION(clear_flags, 0x43E); |
| 1455 | ASSERT_REG_POSITION(fill_rectangle, 0x44F); | ||
| 1438 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); | 1456 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); |
| 1439 | ASSERT_REG_POSITION(rt_control, 0x487); | 1457 | ASSERT_REG_POSITION(rt_control, 0x487); |
| 1440 | ASSERT_REG_POSITION(zeta_width, 0x48a); | 1458 | ASSERT_REG_POSITION(zeta_width, 0x48a); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4e4138573..8e48a6482 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -487,6 +487,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 487 | 487 | ||
| 488 | SyncViewport(); | 488 | SyncViewport(); |
| 489 | SyncRasterizeEnable(); | 489 | SyncRasterizeEnable(); |
| 490 | SyncPolygonModes(); | ||
| 490 | SyncColorMask(); | 491 | SyncColorMask(); |
| 491 | SyncFragmentColorClampState(); | 492 | SyncFragmentColorClampState(); |
| 492 | SyncMultiSampleState(); | 493 | SyncMultiSampleState(); |
| @@ -1096,6 +1097,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() { | |||
| 1096 | oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); | 1097 | oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); |
| 1097 | } | 1098 | } |
| 1098 | 1099 | ||
| 1100 | void RasterizerOpenGL::SyncPolygonModes() { | ||
| 1101 | auto& gpu = system.GPU().Maxwell3D(); | ||
| 1102 | auto& flags = gpu.dirty.flags; | ||
| 1103 | if (!flags[Dirty::PolygonModes]) { | ||
| 1104 | return; | ||
| 1105 | } | ||
| 1106 | flags[Dirty::PolygonModes] = false; | ||
| 1107 | |||
| 1108 | if (gpu.regs.fill_rectangle) { | ||
| 1109 | if (!GLAD_GL_NV_fill_rectangle) { | ||
| 1110 | LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); | ||
| 1111 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
| 1112 | return; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | flags[Dirty::PolygonModeFront] = true; | ||
| 1116 | flags[Dirty::PolygonModeBack] = true; | ||
| 1117 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV); | ||
| 1118 | return; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) { | ||
| 1122 | flags[Dirty::PolygonModeFront] = false; | ||
| 1123 | flags[Dirty::PolygonModeBack] = false; | ||
| 1124 | glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); | ||
| 1125 | return; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | if (flags[Dirty::PolygonModeFront]) { | ||
| 1129 | flags[Dirty::PolygonModeFront] = false; | ||
| 1130 | glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | if (flags[Dirty::PolygonModeBack]) { | ||
| 1134 | flags[Dirty::PolygonModeBack] = false; | ||
| 1135 | glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back)); | ||
| 1136 | } | ||
| 1137 | } | ||
| 1138 | |||
| 1099 | void RasterizerOpenGL::SyncColorMask() { | 1139 | void RasterizerOpenGL::SyncColorMask() { |
| 1100 | auto& gpu = system.GPU().Maxwell3D(); | 1140 | auto& gpu = system.GPU().Maxwell3D(); |
| 1101 | auto& flags = gpu.dirty.flags; | 1141 | auto& flags = gpu.dirty.flags; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b24c6661b..e5681d6df 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -178,6 +178,9 @@ private: | |||
| 178 | /// Syncs the rasterizer enable state to match the guest state | 178 | /// Syncs the rasterizer enable state to match the guest state |
| 179 | void SyncRasterizeEnable(); | 179 | void SyncRasterizeEnable(); |
| 180 | 180 | ||
| 181 | /// Syncs polygon modes to match the guest state | ||
| 182 | void SyncPolygonModes(); | ||
| 183 | |||
| 181 | /// Syncs Color Mask | 184 | /// Syncs Color Mask |
| 182 | void SyncColorMask(); | 185 | void SyncColorMask(); |
| 183 | 186 | ||
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 1e43c9ec0..3f3bdf812 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
| @@ -94,6 +94,15 @@ void SetupDirtyShaders(Tables& tables) { | |||
| 94 | Shaders); | 94 | Shaders); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | void SetupDirtyPolygonModes(Tables& tables) { | ||
| 98 | tables[0][OFF(polygon_mode_front)] = PolygonModeFront; | ||
| 99 | tables[0][OFF(polygon_mode_back)] = PolygonModeBack; | ||
| 100 | |||
| 101 | tables[1][OFF(polygon_mode_front)] = PolygonModes; | ||
| 102 | tables[1][OFF(polygon_mode_back)] = PolygonModes; | ||
| 103 | tables[0][OFF(fill_rectangle)] = PolygonModes; | ||
| 104 | } | ||
| 105 | |||
| 97 | void SetupDirtyDepthTest(Tables& tables) { | 106 | void SetupDirtyDepthTest(Tables& tables) { |
| 98 | auto& table = tables[0]; | 107 | auto& table = tables[0]; |
| 99 | table[OFF(depth_test_enable)] = DepthTest; | 108 | table[OFF(depth_test_enable)] = DepthTest; |
| @@ -211,6 +220,7 @@ void StateTracker::Initialize() { | |||
| 211 | SetupDirtyVertexArrays(tables); | 220 | SetupDirtyVertexArrays(tables); |
| 212 | SetupDirtyVertexFormat(tables); | 221 | SetupDirtyVertexFormat(tables); |
| 213 | SetupDirtyShaders(tables); | 222 | SetupDirtyShaders(tables); |
| 223 | SetupDirtyPolygonModes(tables); | ||
| 214 | SetupDirtyDepthTest(tables); | 224 | SetupDirtyDepthTest(tables); |
| 215 | SetupDirtyStencilTest(tables); | 225 | SetupDirtyStencilTest(tables); |
| 216 | SetupDirtyAlphaTest(tables); | 226 | SetupDirtyAlphaTest(tables); |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index e08482911..b882d75c3 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h | |||
| @@ -59,6 +59,10 @@ enum : u8 { | |||
| 59 | Shaders, | 59 | Shaders, |
| 60 | ClipDistances, | 60 | ClipDistances, |
| 61 | 61 | ||
| 62 | PolygonModes, | ||
| 63 | PolygonModeFront, | ||
| 64 | PolygonModeBack, | ||
| 65 | |||
| 62 | ColorMask, | 66 | ColorMask, |
| 63 | FrontFace, | 67 | FrontFace, |
| 64 | CullTest, | 68 | CullTest, |
| @@ -111,6 +115,13 @@ public: | |||
| 111 | flags[OpenGL::Dirty::VertexInstance0 + 1] = true; | 115 | flags[OpenGL::Dirty::VertexInstance0 + 1] = true; |
| 112 | } | 116 | } |
| 113 | 117 | ||
| 118 | void NotifyPolygonModes() { | ||
| 119 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 120 | flags[OpenGL::Dirty::PolygonModes] = true; | ||
| 121 | flags[OpenGL::Dirty::PolygonModeFront] = true; | ||
| 122 | flags[OpenGL::Dirty::PolygonModeBack] = true; | ||
| 123 | } | ||
| 124 | |||
| 114 | void NotifyViewport0() { | 125 | void NotifyViewport0() { |
| 115 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | 126 | auto& flags = system.GPU().Maxwell3D().dirty.flags; |
| 116 | flags[OpenGL::Dirty::Viewports] = true; | 127 | flags[OpenGL::Dirty::Viewports] = true; |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 494e38e7a..89f0e04ef 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -488,5 +488,18 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) { | |||
| 488 | return GL_COPY; | 488 | return GL_COPY; |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) { | ||
| 492 | switch (polygon_mode) { | ||
| 493 | case Maxwell::PolygonMode::Point: | ||
| 494 | return GL_POINT; | ||
| 495 | case Maxwell::PolygonMode::Line: | ||
| 496 | return GL_LINE; | ||
| 497 | case Maxwell::PolygonMode::Fill: | ||
| 498 | return GL_FILL; | ||
| 499 | } | ||
| 500 | UNREACHABLE_MSG("Invalid polygon mode={}", static_cast<int>(polygon_mode)); | ||
| 501 | return GL_FILL; | ||
| 502 | } | ||
| 503 | |||
| 491 | } // namespace MaxwellToGL | 504 | } // namespace MaxwellToGL |
| 492 | } // namespace OpenGL | 505 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index c05677cd9..12333e8c9 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 576 | 576 | ||
| 577 | // TODO: Signal state tracker about these changes | 577 | // TODO: Signal state tracker about these changes |
| 578 | state_tracker.NotifyScreenDrawVertexArray(); | 578 | state_tracker.NotifyScreenDrawVertexArray(); |
| 579 | state_tracker.NotifyPolygonModes(); | ||
| 579 | state_tracker.NotifyViewport0(); | 580 | state_tracker.NotifyViewport0(); |
| 580 | state_tracker.NotifyScissor0(); | 581 | state_tracker.NotifyScissor0(); |
| 581 | state_tracker.NotifyColorMask0(); | 582 | state_tracker.NotifyColorMask0(); |
| @@ -611,6 +612,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 611 | glDisable(GL_ALPHA_TEST); | 612 | glDisable(GL_ALPHA_TEST); |
| 612 | glDisablei(GL_BLEND, 0); | 613 | glDisablei(GL_BLEND, 0); |
| 613 | glDisablei(GL_SCISSOR_TEST, 0); | 614 | glDisablei(GL_SCISSOR_TEST, 0); |
| 615 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
| 614 | glCullFace(GL_BACK); | 616 | glCullFace(GL_BACK); |
| 615 | glFrontFace(GL_CW); | 617 | glFrontFace(GL_CW); |
| 616 | glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 618 | glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |