mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	PICA: Scissor fixes and cleanups
This commit is contained in:
		
							parent
							
								
									f9be06b15f
								
							
						
					
					
						commit
						f0b9bc14b6
					
				@ -128,22 +128,14 @@ struct Regs {
 | 
			
		||||
        BitField<0, 2, ScissorMode> mode;
 | 
			
		||||
 | 
			
		||||
        union {
 | 
			
		||||
            BitField< 0, 16, u32> right;
 | 
			
		||||
            BitField<16, 16, u32> bottom;
 | 
			
		||||
            BitField< 0, 16, u32> x1;
 | 
			
		||||
            BitField<16, 16, u32> y1;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        union {
 | 
			
		||||
            BitField< 0, 16, u32> left_minus_1;
 | 
			
		||||
            BitField<16, 16, u32> top_minus_1;
 | 
			
		||||
            BitField< 0, 16, u32> x2;
 | 
			
		||||
            BitField<16, 16, u32> y2;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        u32 GetTop() const {
 | 
			
		||||
            return top_minus_1 + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        u32 GetLeft() const {
 | 
			
		||||
            return left_minus_1 + 1;
 | 
			
		||||
        }
 | 
			
		||||
    } scissor_test;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
 | 
			
		||||
@ -344,17 +344,18 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
 | 
			
		||||
    u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y});
 | 
			
		||||
 | 
			
		||||
    // Convert the scissor box coordinates to 12.4 fixed point
 | 
			
		||||
    u16 scissor_left = (u16)(regs.scissor_test.GetLeft() << 4);
 | 
			
		||||
    u16 scissor_top = (u16)(regs.scissor_test.GetTop() << 4);
 | 
			
		||||
    u16 scissor_right = (u16)(regs.scissor_test.right << 4);
 | 
			
		||||
    u16 scissor_bottom = (u16)(regs.scissor_test.bottom << 4);
 | 
			
		||||
    u16 scissor_x1 = (u16)( regs.scissor_test.x1      << 4);
 | 
			
		||||
    u16 scissor_y1 = (u16)( regs.scissor_test.y1      << 4);
 | 
			
		||||
    // x2,y2 have +1 added to cover the entire sub-pixel area
 | 
			
		||||
    u16 scissor_x2 = (u16)((regs.scissor_test.x2 + 1) << 4);
 | 
			
		||||
    u16 scissor_y2 = (u16)((regs.scissor_test.y2 + 1) << 4);
 | 
			
		||||
 | 
			
		||||
    if (regs.scissor_test.mode == Regs::ScissorMode::Include) {
 | 
			
		||||
        // Calculate the new bounds
 | 
			
		||||
        min_x = std::max(min_x, scissor_right);
 | 
			
		||||
        min_y = std::max(min_y, scissor_bottom);
 | 
			
		||||
        max_x = std::min(max_x, scissor_left);
 | 
			
		||||
        max_y = std::min(max_y, scissor_top);
 | 
			
		||||
        min_x = std::max(min_x, scissor_x1);
 | 
			
		||||
        min_y = std::max(min_y, scissor_y1);
 | 
			
		||||
        max_x = std::min(max_x, scissor_x2);
 | 
			
		||||
        max_y = std::min(max_y, scissor_y2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    min_x &= Fix12P4::IntMask();
 | 
			
		||||
@ -397,10 +398,10 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
 | 
			
		||||
        for (u16 x = min_x + 8; x < max_x; x += 0x10) {
 | 
			
		||||
 | 
			
		||||
            // Do not process the pixel if it's inside the scissor box and the scissor mode is set to Exclude
 | 
			
		||||
            if (regs.scissor_test.mode == Regs::ScissorMode::Exclude &&
 | 
			
		||||
                x >= scissor_right && x <= scissor_left &&
 | 
			
		||||
                y >= scissor_bottom && y <= scissor_top) {
 | 
			
		||||
                continue;
 | 
			
		||||
            if (regs.scissor_test.mode == Regs::ScissorMode::Exclude) {
 | 
			
		||||
                if (x >= scissor_x1 && x < scissor_x2 &&
 | 
			
		||||
                    y >= scissor_y1 && y < scissor_y2)
 | 
			
		||||
                    continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Calculate the barycentric coordinates w0, w1 and w2
 | 
			
		||||
 | 
			
		||||
@ -357,8 +357,8 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
 | 
			
		||||
    case PICA_REG_INDEX(scissor_test.mode):
 | 
			
		||||
        shader_dirty = true;
 | 
			
		||||
        break;
 | 
			
		||||
    case PICA_REG_INDEX(scissor_test.right):
 | 
			
		||||
    case PICA_REG_INDEX(scissor_test.left_minus_1):
 | 
			
		||||
    case PICA_REG_INDEX(scissor_test.x1): // and y1
 | 
			
		||||
    case PICA_REG_INDEX(scissor_test.x2): // and y2
 | 
			
		||||
        SyncScissorTest();
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@ -1179,15 +1179,15 @@ void RasterizerOpenGL::SyncDepthTest() {
 | 
			
		||||
void RasterizerOpenGL::SyncScissorTest() {
 | 
			
		||||
    const auto& regs = Pica::g_state.regs;
 | 
			
		||||
 | 
			
		||||
    if (uniform_block_data.data.scissor_right != regs.scissor_test.right ||
 | 
			
		||||
        uniform_block_data.data.scissor_bottom != regs.scissor_test.bottom ||
 | 
			
		||||
        uniform_block_data.data.scissor_left != regs.scissor_test.GetLeft() ||
 | 
			
		||||
        uniform_block_data.data.scissor_top != regs.scissor_test.GetTop()) {
 | 
			
		||||
    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_right = regs.scissor_test.right;
 | 
			
		||||
        uniform_block_data.data.scissor_bottom = regs.scissor_test.bottom;
 | 
			
		||||
        uniform_block_data.data.scissor_left = regs.scissor_test.GetLeft();
 | 
			
		||||
        uniform_block_data.data.scissor_top = regs.scissor_test.GetTop();
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -331,10 +331,10 @@ private:
 | 
			
		||||
        GLint alphatest_ref;
 | 
			
		||||
        GLfloat depth_scale;
 | 
			
		||||
        GLfloat depth_offset;
 | 
			
		||||
        GLint scissor_right;
 | 
			
		||||
        GLint scissor_bottom;
 | 
			
		||||
        GLint scissor_left;
 | 
			
		||||
        GLint scissor_top;
 | 
			
		||||
        GLint scissor_x1;
 | 
			
		||||
        GLint scissor_y1;
 | 
			
		||||
        GLint scissor_x2;
 | 
			
		||||
        GLint scissor_y2;
 | 
			
		||||
        alignas(16) GLvec3 fog_color;
 | 
			
		||||
        alignas(16) GLvec3 lighting_global_ambient;
 | 
			
		||||
        LightSrc light_src[8];
 | 
			
		||||
 | 
			
		||||
@ -557,10 +557,10 @@ layout (std140) uniform shader_data {
 | 
			
		||||
    int alphatest_ref;
 | 
			
		||||
    float depth_scale;
 | 
			
		||||
    float depth_offset;
 | 
			
		||||
    int scissor_right;
 | 
			
		||||
    int scissor_bottom;
 | 
			
		||||
    int scissor_left;
 | 
			
		||||
    int scissor_top;
 | 
			
		||||
    int scissor_x1;
 | 
			
		||||
    int scissor_y1;
 | 
			
		||||
    int scissor_x2;
 | 
			
		||||
    int scissor_y2;
 | 
			
		||||
    vec3 fog_color;
 | 
			
		||||
    vec3 lighting_global_ambient;
 | 
			
		||||
    LightSrc light_src[NUM_LIGHTS];
 | 
			
		||||
@ -589,13 +589,14 @@ vec4 secondary_fragment_color = vec4(0.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Append the scissor test
 | 
			
		||||
    if (state.scissor_test_mode == Regs::ScissorMode::Include || state.scissor_test_mode == Regs::ScissorMode::Exclude) {
 | 
			
		||||
        out += "if (scissor_left <= scissor_right || scissor_top <= scissor_bottom) discard;\n";
 | 
			
		||||
    if (state.scissor_test_mode != Regs::ScissorMode::Disabled) {
 | 
			
		||||
        out += "if (";
 | 
			
		||||
        // Negate the condition if we have to keep only the pixels outside the scissor box
 | 
			
		||||
        if (state.scissor_test_mode == Regs::ScissorMode::Include)
 | 
			
		||||
            out += "!";
 | 
			
		||||
        out += "(gl_FragCoord.x >= scissor_right && gl_FragCoord.x <= scissor_left && gl_FragCoord.y >= scissor_bottom && gl_FragCoord.y <= scissor_top)) discard;\n";
 | 
			
		||||
        // x2,y2 have +1 added to cover the entire pixel area
 | 
			
		||||
        out += "(gl_FragCoord.x >= scissor_x1 && gl_FragCoord.x < scissor_x2 + 1 && "
 | 
			
		||||
                "gl_FragCoord.y >= scissor_y1 && gl_FragCoord.y < scissor_y2 + 1)) discard;\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user