summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuri Kunde Schlesner <yuriks@yuriks.net>2016-01-25 07:59:16 +0100
committerYuri Kunde Schlesner <yuriks@yuriks.net>2016-06-28 06:14:39 +0200
commitf0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324 (patch)
tree5980ec623e974d6c9b71291d417365cfbe4ae4fc
parentPICA: Implement scissor test (diff)
downloadyuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.gz
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.bz2
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.lz
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.xz
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.zst
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.zip
-rw-r--r--src/video_core/pica.h16
-rw-r--r--src/video_core/rasterizer.cpp25
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp15
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";