Merge pull request #2083 from yuriks/opengl-scissor-cached-rect
OpenGL: Take cached viewport sub-rect into account for scissor
This commit is contained in:
		| @@ -211,6 +211,27 @@ void RasterizerOpenGL::DrawTriangles() { | ||||
|         uniform_block_data.dirty = true; | ||||
|     } | ||||
|  | ||||
|     // Scissor checks are window-, not viewport-relative, which means that if the cached texture | ||||
|     // sub-rect changes, the scissor bounds also need to be updated. | ||||
|     GLint scissor_x1 = rect.left + regs.scissor_test.x1 * color_surface->res_scale_width; | ||||
|     GLint scissor_y1 = rect.bottom + regs.scissor_test.y1 * color_surface->res_scale_height; | ||||
|     // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when | ||||
|     // scaling or doing multisampling. | ||||
|     GLint scissor_x2 = rect.left + (regs.scissor_test.x2 + 1) * color_surface->res_scale_width; | ||||
|     GLint scissor_y2 = rect.bottom + (regs.scissor_test.y2 + 1) * color_surface->res_scale_height; | ||||
|  | ||||
|     if (uniform_block_data.data.scissor_x1 != scissor_x1 || | ||||
|         uniform_block_data.data.scissor_x2 != scissor_x2 || | ||||
|         uniform_block_data.data.scissor_y1 != scissor_y1 || | ||||
|         uniform_block_data.data.scissor_y2 != scissor_y2) { | ||||
|  | ||||
|         uniform_block_data.data.scissor_x1 = scissor_x1; | ||||
|         uniform_block_data.data.scissor_x2 = scissor_x2; | ||||
|         uniform_block_data.data.scissor_y1 = scissor_y1; | ||||
|         uniform_block_data.data.scissor_y2 = scissor_y2; | ||||
|         uniform_block_data.dirty = true; | ||||
|     } | ||||
|  | ||||
|     // Sync and bind the texture surfaces | ||||
|     const auto pica_textures = regs.GetTextures(); | ||||
|     for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { | ||||
| @@ -374,10 +395,6 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | ||||
|     case PICA_REG_INDEX(scissor_test.mode): | ||||
|         shader_dirty = true; | ||||
|         break; | ||||
|     case PICA_REG_INDEX(scissor_test.x1): // and y1 | ||||
|     case PICA_REG_INDEX(scissor_test.x2): // and y2 | ||||
|         SyncScissorTest(); | ||||
|         break; | ||||
|  | ||||
|     // Logic op | ||||
|     case PICA_REG_INDEX(output_merger.logic_op): | ||||
| @@ -1061,7 +1078,6 @@ void RasterizerOpenGL::SetShader() { | ||||
|         SyncDepthOffset(); | ||||
|         SyncAlphaTest(); | ||||
|         SyncCombinerColor(); | ||||
|         SyncScissorTest(); | ||||
|         auto& tev_stages = Pica::g_state.regs.GetTevStages(); | ||||
|         for (int index = 0; index < tev_stages.size(); ++index) | ||||
|             SyncTevConstColor(index, tev_stages[index]); | ||||
| @@ -1236,22 +1252,6 @@ void RasterizerOpenGL::SyncDepthTest() { | ||||
|                                 : GL_ALWAYS; | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::SyncScissorTest() { | ||||
|     const auto& regs = Pica::g_state.regs; | ||||
|  | ||||
|     if (uniform_block_data.data.scissor_x1 != regs.scissor_test.x1 || | ||||
|         uniform_block_data.data.scissor_y1 != regs.scissor_test.y1 || | ||||
|         uniform_block_data.data.scissor_x2 != regs.scissor_test.x2 || | ||||
|         uniform_block_data.data.scissor_y2 != regs.scissor_test.y2) { | ||||
|  | ||||
|         uniform_block_data.data.scissor_x1 = regs.scissor_test.x1; | ||||
|         uniform_block_data.data.scissor_y1 = regs.scissor_test.y1; | ||||
|         uniform_block_data.data.scissor_x2 = regs.scissor_test.x2; | ||||
|         uniform_block_data.data.scissor_y2 = regs.scissor_test.y2; | ||||
|         uniform_block_data.dirty = true; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::SyncCombinerColor() { | ||||
|     auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); | ||||
|     if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { | ||||
|   | ||||
| @@ -393,9 +393,6 @@ private: | ||||
|     /// Syncs the depth test states to match the PICA register | ||||
|     void SyncDepthTest(); | ||||
|  | ||||
|     /// Syncs the scissor test state to match the PICA register | ||||
|     void SyncScissorTest(); | ||||
|  | ||||
|     /// Syncs the TEV combiner color buffer to match the PICA register | ||||
|     void SyncCombinerColor(); | ||||
|  | ||||
|   | ||||
| @@ -645,11 +645,10 @@ vec4 secondary_fragment_color = vec4(0.0); | ||||
|         // Negate the condition if we have to keep only the pixels outside the scissor box | ||||
|         if (state.scissor_test_mode == Regs::ScissorMode::Include) | ||||
|             out += "!"; | ||||
|         // x2,y2 have +1 added to cover the entire pixel area | ||||
|         out += "(gl_FragCoord.x >= scissor_x1 * framebuffer_scale.x && " | ||||
|                "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && " | ||||
|                "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && " | ||||
|                "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n"; | ||||
|         out += "(gl_FragCoord.x >= scissor_x1 && " | ||||
|                "gl_FragCoord.y >= scissor_y1 && " | ||||
|                "gl_FragCoord.x < scissor_x2 && " | ||||
|                "gl_FragCoord.y < scissor_y2)) discard;\n"; | ||||
|     } | ||||
|  | ||||
|     out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user