summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2020-03-13 10:08:57 -0400
committerGravatar GitHub2020-03-13 10:08:57 -0400
commitb30b1f741dcbcb69672d065b0bec4f4a9e5f0993 (patch)
treeb8416dffe6beb924c574ef25755aad12db0a68fb /src
parentMerge pull request #3483 from namkazt/patch-1 (diff)
parentgl_rasterizer: Implement polygon modes and fill rectangles (diff)
downloadyuzu-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.h22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp40
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h11
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h13
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
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);
1422ASSERT_REG_POSITION(clear_color[0], 0x360); 1437ASSERT_REG_POSITION(clear_color[0], 0x360);
1423ASSERT_REG_POSITION(clear_depth, 0x364); 1438ASSERT_REG_POSITION(clear_depth, 0x364);
1424ASSERT_REG_POSITION(clear_stencil, 0x368); 1439ASSERT_REG_POSITION(clear_stencil, 0x368);
1440ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
1441ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
1425ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); 1442ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
1426ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); 1443ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
1427ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); 1444ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
@@ -1435,6 +1452,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
1435ASSERT_REG_POSITION(depth_bounds, 0x3E7); 1452ASSERT_REG_POSITION(depth_bounds, 0x3E7);
1436ASSERT_REG_POSITION(zeta, 0x3F8); 1453ASSERT_REG_POSITION(zeta, 0x3F8);
1437ASSERT_REG_POSITION(clear_flags, 0x43E); 1454ASSERT_REG_POSITION(clear_flags, 0x43E);
1455ASSERT_REG_POSITION(fill_rectangle, 0x44F);
1438ASSERT_REG_POSITION(vertex_attrib_format, 0x458); 1456ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
1439ASSERT_REG_POSITION(rt_control, 0x487); 1457ASSERT_REG_POSITION(rt_control, 0x487);
1440ASSERT_REG_POSITION(zeta_width, 0x48a); 1458ASSERT_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
1100void 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
1099void RasterizerOpenGL::SyncColorMask() { 1139void 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
97void 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
97void SetupDirtyDepthTest(Tables& tables) { 106void 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
491inline 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);