diff options
| -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:              FractionalEven = 2,          }; +        enum class PolygonMode : u32 { +            Point = 0x1b00, +            Line = 0x1b01, +            Fill = 0x1b02, +        }; +          struct RenderTargetConfig {              u32 address_high;              u32 address_low; @@ -705,7 +711,12 @@ public:                  s32 clear_stencil; -                INSERT_UNION_PADDING_WORDS(0x7); +                INSERT_UNION_PADDING_WORDS(0x2); + +                PolygonMode polygon_mode_front; +                PolygonMode polygon_mode_back; + +                INSERT_UNION_PADDING_WORDS(0x3);                  u32 polygon_offset_point_enable;                  u32 polygon_offset_line_enable; @@ -764,7 +775,11 @@ public:                      BitField<12, 4, u32> viewport;                  } clear_flags; -                INSERT_UNION_PADDING_WORDS(0x19); +                INSERT_UNION_PADDING_WORDS(0x10); + +                u32 fill_rectangle; + +                INSERT_UNION_PADDING_WORDS(0x8);                  std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; @@ -1422,6 +1437,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F);  ASSERT_REG_POSITION(clear_color[0], 0x360);  ASSERT_REG_POSITION(clear_depth, 0x364);  ASSERT_REG_POSITION(clear_stencil, 0x368); +ASSERT_REG_POSITION(polygon_mode_front, 0x36B); +ASSERT_REG_POSITION(polygon_mode_back, 0x36C);  ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);  ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);  ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); @@ -1435,6 +1452,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);  ASSERT_REG_POSITION(depth_bounds, 0x3E7);  ASSERT_REG_POSITION(zeta, 0x3F8);  ASSERT_REG_POSITION(clear_flags, 0x43E); +ASSERT_REG_POSITION(fill_rectangle, 0x44F);  ASSERT_REG_POSITION(vertex_attrib_format, 0x458);  ASSERT_REG_POSITION(rt_control, 0x487);  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) {      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); | 
