From c1bebdef5e11558d27dd9aa60525b47c20598491 Mon Sep 17 00:00:00 2001 From: Subv <subv2112@gmail.com> Date: Wed, 4 Jul 2018 10:26:46 -0500 Subject: [PATCH] GPU: Flip the triangle front face winding if the GPU is configured to not flip the triangles. OpenGL's default behavior is already correct when the GPU is configured to flip the triangles. This fixes 1-2 Switch's splash screen. --- src/video_core/engines/maxwell_3d.h | 22 ++++++++++++++++--- .../renderer_opengl/gl_rasterizer.cpp | 10 +++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 988a6433e0..cc1f90de63 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -478,7 +478,9 @@ public: u32 depth_write_enabled; - INSERT_PADDING_WORDS(0x8); + INSERT_PADDING_WORDS(0x7); + + u32 d3d_cull_mode; BitField<0, 3, ComparisonOp> depth_test_func; @@ -498,7 +500,13 @@ public: u32 enable[NumRenderTargets]; } blend; - INSERT_PADDING_WORDS(0x2D); + INSERT_PADDING_WORDS(0xB); + + union { + BitField<4, 1, u32> triangle_rast_flip; + } screen_y_control; + + INSERT_PADDING_WORDS(0x21); u32 vb_element_base; @@ -528,7 +536,12 @@ public: } } tic; - INSERT_PADDING_WORDS(0x22); + INSERT_PADDING_WORDS(0x21); + + union { + BitField<2, 1, u32> coord_origin; + BitField<3, 10, u32> enable; + } point_coord_replace; struct { u32 code_address_high; @@ -818,11 +831,14 @@ ASSERT_REG_POSITION(rt_control, 0x487); ASSERT_REG_POSITION(depth_test_enable, 0x4B3); ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); +ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2); ASSERT_REG_POSITION(depth_test_func, 0x4C3); ASSERT_REG_POSITION(blend, 0x4CF); +ASSERT_REG_POSITION(screen_y_control, 0x4EB); ASSERT_REG_POSITION(vb_element_base, 0x50D); ASSERT_REG_POSITION(tsc, 0x557); ASSERT_REG_POSITION(tic, 0x55D); +ASSERT_REG_POSITION(point_coord_replace, 0x581); ASSERT_REG_POSITION(code_address, 0x582); ASSERT_REG_POSITION(draw, 0x585); ASSERT_REG_POSITION(index_array, 0x5F2); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e516eb1adf..3c3657d9d3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -771,6 +771,16 @@ void RasterizerOpenGL::SyncCullMode() { if (state.cull.enabled) { state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face); + + // If the GPU is configured to flip the rasterized triangles, then we need to flip the + // notion of front and back. Note: We flip the triangles when the value of the register is 0 + // because OpenGL already does it for us. + if (regs.screen_y_control.triangle_rast_flip == 0) { + if (state.cull.front_face == GL_CCW) + state.cull.front_face = GL_CW; + else if (state.cull.front_face == GL_CW) + state.cull.front_face = GL_CCW; + } } }