Merge pull request #3491 from ReinUsesLisp/polygon-modes
gl_rasterizer: Implement polygon modes and fill rectangles
This commit is contained in:
		
						commit
						b30b1f741d
					
				| @ -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); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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(); | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei