summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-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
6 files changed, 79 insertions, 0 deletions
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) {
SyncViewport();
SyncRasterizeEnable();
+ SyncPolygonModes();
SyncColorMask();
SyncFragmentColorClampState();
SyncMultiSampleState();
@@ -1096,6 +1097,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() {
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
}
+void RasterizerOpenGL::SyncPolygonModes() {
+ auto& gpu = system.GPU().Maxwell3D();
+ auto& flags = gpu.dirty.flags;
+ if (!flags[Dirty::PolygonModes]) {
+ return;
+ }
+ flags[Dirty::PolygonModes] = false;
+
+ if (gpu.regs.fill_rectangle) {
+ if (!GLAD_GL_NV_fill_rectangle) {
+ LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ return;
+ }
+
+ flags[Dirty::PolygonModeFront] = true;
+ flags[Dirty::PolygonModeBack] = true;
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV);
+ return;
+ }
+
+ if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) {
+ flags[Dirty::PolygonModeFront] = false;
+ flags[Dirty::PolygonModeBack] = false;
+ glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
+ return;
+ }
+
+ if (flags[Dirty::PolygonModeFront]) {
+ flags[Dirty::PolygonModeFront] = false;
+ glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
+ }
+
+ if (flags[Dirty::PolygonModeBack]) {
+ flags[Dirty::PolygonModeBack] = false;
+ glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back));
+ }
+}
+
void RasterizerOpenGL::SyncColorMask() {
auto& gpu = system.GPU().Maxwell3D();
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:
/// Syncs the rasterizer enable state to match the guest state
void SyncRasterizeEnable();
+ /// Syncs polygon modes to match the guest state
+ void SyncPolygonModes();
+
/// Syncs Color Mask
void SyncColorMask();
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) {
Shaders);
}
+void SetupDirtyPolygonModes(Tables& tables) {
+ tables[0][OFF(polygon_mode_front)] = PolygonModeFront;
+ tables[0][OFF(polygon_mode_back)] = PolygonModeBack;
+
+ tables[1][OFF(polygon_mode_front)] = PolygonModes;
+ tables[1][OFF(polygon_mode_back)] = PolygonModes;
+ tables[0][OFF(fill_rectangle)] = PolygonModes;
+}
+
void SetupDirtyDepthTest(Tables& tables) {
auto& table = tables[0];
table[OFF(depth_test_enable)] = DepthTest;
@@ -211,6 +220,7 @@ void StateTracker::Initialize() {
SetupDirtyVertexArrays(tables);
SetupDirtyVertexFormat(tables);
SetupDirtyShaders(tables);
+ SetupDirtyPolygonModes(tables);
SetupDirtyDepthTest(tables);
SetupDirtyStencilTest(tables);
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 {
Shaders,
ClipDistances,
+ PolygonModes,
+ PolygonModeFront,
+ PolygonModeBack,
+
ColorMask,
FrontFace,
CullTest,
@@ -111,6 +115,13 @@ public:
flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
}
+ void NotifyPolygonModes() {
+ auto& flags = system.GPU().Maxwell3D().dirty.flags;
+ flags[OpenGL::Dirty::PolygonModes] = true;
+ flags[OpenGL::Dirty::PolygonModeFront] = true;
+ flags[OpenGL::Dirty::PolygonModeBack] = true;
+ }
+
void NotifyViewport0() {
auto& flags = system.GPU().Maxwell3D().dirty.flags;
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) {
return GL_COPY;
}
+inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) {
+ switch (polygon_mode) {
+ case Maxwell::PolygonMode::Point:
+ return GL_POINT;
+ case Maxwell::PolygonMode::Line:
+ return GL_LINE;
+ case Maxwell::PolygonMode::Fill:
+ return GL_FILL;
+ }
+ UNREACHABLE_MSG("Invalid polygon mode={}", static_cast<int>(polygon_mode));
+ return GL_FILL;
+}
+
} // namespace MaxwellToGL
} // 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) {
// TODO: Signal state tracker about these changes
state_tracker.NotifyScreenDrawVertexArray();
+ state_tracker.NotifyPolygonModes();
state_tracker.NotifyViewport0();
state_tracker.NotifyScissor0();
state_tracker.NotifyColorMask0();
@@ -611,6 +612,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
glDisable(GL_ALPHA_TEST);
glDisablei(GL_BLEND, 0);
glDisablei(GL_SCISSOR_TEST, 0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);