mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	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:
		
						commit
						4b14e17b18
					
				@ -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";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user