diff options
| -rw-r--r-- | src/video_core/pica.h | 16 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 15 | 
5 files changed, 39 insertions, 45 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 065a3fd0c..7099c31a0 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -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 { diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 514d64208..6f369a00e 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -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 diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 14ee97d57..ab02aadc9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -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;      }  } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 193c10291..653ac9cd9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -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]; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 10bb44210..b2e452afe 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -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";  | 
