diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 41f057f74..2ea0ba2a2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -150,8 +150,6 @@ void RasterizerOpenGL::DrawTriangles() { SyncFramebuffer(); SyncDrawState(); - SyncScissorTest(); - if (state.draw.shader_dirty) { SetShader(); state.draw.shader_dirty = false; @@ -228,6 +226,10 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { case PICA_REG_INDEX(scissor_test.mode): state.draw.shader_dirty = true; break; + case PICA_REG_INDEX(scissor_test.right): + case PICA_REG_INDEX(scissor_test.left): + SyncScissorTest(); + break; // Logic op case PICA_REG_INDEX(output_merger.logic_op): @@ -668,25 +670,15 @@ void RasterizerOpenGL::SyncDepthTest() { void RasterizerOpenGL::SyncScissorTest() { const auto& regs = Pica::g_state.regs; - GLsizei viewport_height = (GLsizei)Pica::float24::FromRawFloat24(regs.viewport_size_y).ToFloat32() * 2; - - GLsizei viewport_corner_y = -(GLsizei)static_cast(regs.viewport_corner.y) - + regs.framebuffer.GetHeight() - viewport_height; - - // OpenGL uses different y coordinates, so negate corner offset and flip origin - GLint scissor_bottom = viewport_height - (GLsizei)regs.scissor_test.bottom + viewport_corner_y; - - GLint scissor_top = viewport_height - (GLsizei)regs.scissor_test.top - 1; - if (uniform_block_data.data.scissor_right != regs.scissor_test.right || - uniform_block_data.data.scissor_bottom != scissor_bottom || + uniform_block_data.data.scissor_bottom != regs.scissor_test.bottom || uniform_block_data.data.scissor_left != regs.scissor_test.left + 1 || - uniform_block_data.data.scissor_top != scissor_top) { + uniform_block_data.data.scissor_top != regs.scissor_test.top + 1) { uniform_block_data.data.scissor_right = regs.scissor_test.right; - uniform_block_data.data.scissor_bottom = scissor_bottom; + uniform_block_data.data.scissor_bottom = regs.scissor_test.bottom; uniform_block_data.data.scissor_left = regs.scissor_test.left + 1; - uniform_block_data.data.scissor_top = scissor_top; + uniform_block_data.data.scissor_top = regs.scissor_test.top + 1; uniform_block_data.dirty = true; } } @@ -714,8 +706,6 @@ void RasterizerOpenGL::SyncDrawState() { GLsizei viewport_width = (GLsizei)Pica::float24::FromRawFloat24(regs.viewport_size_x).ToFloat32() * 2; GLsizei viewport_height = (GLsizei)Pica::float24::FromRawFloat24(regs.viewport_size_y).ToFloat32() * 2; - // OpenGL uses different y coordinates, so negate corner offset and flip origin - // TODO: Ensure viewport_corner.x should not be negated or origin flipped // TODO: Use floating-point viewports for accuracy if supported glViewport((GLsizei)regs.viewport_corner.x, (GLsizei)regs.viewport_corner.y, diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 5c7b01c2c..4db9f142d 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -354,12 +354,12 @@ void main() { // Append the scissor test if (config.scissor_test_mode == Regs::ScissorMode::Include || config.scissor_test_mode == Regs::ScissorMode::Exclude) { - out += "if (scissor_left <= scissor_right || scissor_top >= scissor_bottom) discard;\n"; + out += "if (scissor_left <= scissor_right || scissor_top <= scissor_bottom) discard;\n"; out += "if ("; // Negate the condition if we have to keep only the pixels outside the scissor box if (config.scissor_test_mode == Regs::ScissorMode::Include) out += "!"; - out += "(gl_FragCoord.x >= scissor_right && gl_FragCoord.x <= scissor_left && gl_FragCoord.y >= scissor_top && gl_FragCoord.y <= scissor_bottom)) discard;\n"; + out += "(gl_FragCoord.x >= scissor_right && gl_FragCoord.x <= scissor_left && gl_FragCoord.y >= scissor_bottom && gl_FragCoord.y <= scissor_top)) discard;\n"; } out += "vec4 combiner_buffer = vec4(0.0);\n";