mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	OpenGL: Take cached viewport sub-rect into account for scissor
Fixes #1938
This commit is contained in:
		
							parent
							
								
									0c8df1046f
								
							
						
					
					
						commit
						01667d9a35
					
				
					 3 changed files with 25 additions and 29 deletions
				
			
		|  | @ -211,6 +211,27 @@ void RasterizerOpenGL::DrawTriangles() { | ||||||
|         uniform_block_data.dirty = true; |         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
 |     // Sync and bind the texture surfaces
 | ||||||
|     const auto pica_textures = regs.GetTextures(); |     const auto pica_textures = regs.GetTextures(); | ||||||
|     for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { |     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): |     case PICA_REG_INDEX(scissor_test.mode): | ||||||
|         shader_dirty = true; |         shader_dirty = true; | ||||||
|         break; |         break; | ||||||
|     case PICA_REG_INDEX(scissor_test.x1): // and y1
 |  | ||||||
|     case PICA_REG_INDEX(scissor_test.x2): // and y2
 |  | ||||||
|         SyncScissorTest(); |  | ||||||
|         break; |  | ||||||
| 
 | 
 | ||||||
|     // Logic op
 |     // Logic op
 | ||||||
|     case PICA_REG_INDEX(output_merger.logic_op): |     case PICA_REG_INDEX(output_merger.logic_op): | ||||||
|  | @ -1061,7 +1078,6 @@ void RasterizerOpenGL::SetShader() { | ||||||
|         SyncDepthOffset(); |         SyncDepthOffset(); | ||||||
|         SyncAlphaTest(); |         SyncAlphaTest(); | ||||||
|         SyncCombinerColor(); |         SyncCombinerColor(); | ||||||
|         SyncScissorTest(); |  | ||||||
|         auto& tev_stages = Pica::g_state.regs.GetTevStages(); |         auto& tev_stages = Pica::g_state.regs.GetTevStages(); | ||||||
|         for (int index = 0; index < tev_stages.size(); ++index) |         for (int index = 0; index < tev_stages.size(); ++index) | ||||||
|             SyncTevConstColor(index, tev_stages[index]); |             SyncTevConstColor(index, tev_stages[index]); | ||||||
|  | @ -1236,22 +1252,6 @@ void RasterizerOpenGL::SyncDepthTest() { | ||||||
|                                 : GL_ALWAYS; |                                 : 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() { | void RasterizerOpenGL::SyncCombinerColor() { | ||||||
|     auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); |     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) { |     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
 |     /// Syncs the depth test states to match the PICA register
 | ||||||
|     void SyncDepthTest(); |     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
 |     /// Syncs the TEV combiner color buffer to match the PICA register
 | ||||||
|     void SyncCombinerColor(); |     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
 |         // Negate the condition if we have to keep only the pixels outside the scissor box
 | ||||||
|         if (state.scissor_test_mode == Regs::ScissorMode::Include) |         if (state.scissor_test_mode == Regs::ScissorMode::Include) | ||||||
|             out += "!"; |             out += "!"; | ||||||
|         // x2,y2 have +1 added to cover the entire pixel area
 |         out += "(gl_FragCoord.x >= scissor_x1 && " | ||||||
|         out += "(gl_FragCoord.x >= scissor_x1 * framebuffer_scale.x && " |                "gl_FragCoord.y >= scissor_y1 && " | ||||||
|                "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && " |                "gl_FragCoord.x < scissor_x2 && " | ||||||
|                "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && " |                "gl_FragCoord.y < scissor_y2)) discard;\n"; | ||||||
|                "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n"; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; |     out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue