summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-01-24 22:59:16 -0800
committerGravatar Yuri Kunde Schlesner2016-06-27 21:14:39 -0700
commitf0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324 (patch)
tree5980ec623e974d6c9b71291d417365cfbe4ae4fc /src
parentPICA: Implement scissor test (diff)
downloadyuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.gz
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.tar.xz
yuzu-f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324.zip
PICA: Scissor fixes and cleanups
Diffstat (limited to 'src')
-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 {
128 BitField<0, 2, ScissorMode> mode; 128 BitField<0, 2, ScissorMode> mode;
129 129
130 union { 130 union {
131 BitField< 0, 16, u32> right; 131 BitField< 0, 16, u32> x1;
132 BitField<16, 16, u32> bottom; 132 BitField<16, 16, u32> y1;
133 }; 133 };
134 134
135 union { 135 union {
136 BitField< 0, 16, u32> left_minus_1; 136 BitField< 0, 16, u32> x2;
137 BitField<16, 16, u32> top_minus_1; 137 BitField<16, 16, u32> y2;
138 }; 138 };
139
140 u32 GetTop() const {
141 return top_minus_1 + 1;
142 }
143
144 u32 GetLeft() const {
145 return left_minus_1 + 1;
146 }
147 } scissor_test; 139 } scissor_test;
148 140
149 union { 141 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,
344 u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); 344 u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y});
345 345
346 // Convert the scissor box coordinates to 12.4 fixed point 346 // Convert the scissor box coordinates to 12.4 fixed point
347 u16 scissor_left = (u16)(regs.scissor_test.GetLeft() << 4); 347 u16 scissor_x1 = (u16)( regs.scissor_test.x1 << 4);
348 u16 scissor_top = (u16)(regs.scissor_test.GetTop() << 4); 348 u16 scissor_y1 = (u16)( regs.scissor_test.y1 << 4);
349 u16 scissor_right = (u16)(regs.scissor_test.right << 4); 349 // x2,y2 have +1 added to cover the entire sub-pixel area
350 u16 scissor_bottom = (u16)(regs.scissor_test.bottom << 4); 350 u16 scissor_x2 = (u16)((regs.scissor_test.x2 + 1) << 4);
351 u16 scissor_y2 = (u16)((regs.scissor_test.y2 + 1) << 4);
351 352
352 if (regs.scissor_test.mode == Regs::ScissorMode::Include) { 353 if (regs.scissor_test.mode == Regs::ScissorMode::Include) {
353 // Calculate the new bounds 354 // Calculate the new bounds
354 min_x = std::max(min_x, scissor_right); 355 min_x = std::max(min_x, scissor_x1);
355 min_y = std::max(min_y, scissor_bottom); 356 min_y = std::max(min_y, scissor_y1);
356 max_x = std::min(max_x, scissor_left); 357 max_x = std::min(max_x, scissor_x2);
357 max_y = std::min(max_y, scissor_top); 358 max_y = std::min(max_y, scissor_y2);
358 } 359 }
359 360
360 min_x &= Fix12P4::IntMask(); 361 min_x &= Fix12P4::IntMask();
@@ -397,10 +398,10 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
397 for (u16 x = min_x + 8; x < max_x; x += 0x10) { 398 for (u16 x = min_x + 8; x < max_x; x += 0x10) {
398 399
399 // Do not process the pixel if it's inside the scissor box and the scissor mode is set to Exclude 400 // Do not process the pixel if it's inside the scissor box and the scissor mode is set to Exclude
400 if (regs.scissor_test.mode == Regs::ScissorMode::Exclude && 401 if (regs.scissor_test.mode == Regs::ScissorMode::Exclude) {
401 x >= scissor_right && x <= scissor_left && 402 if (x >= scissor_x1 && x < scissor_x2 &&
402 y >= scissor_bottom && y <= scissor_top) { 403 y >= scissor_y1 && y < scissor_y2)
403 continue; 404 continue;
404 } 405 }
405 406
406 // Calculate the barycentric coordinates w0, w1 and w2 407 // 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) {
357 case PICA_REG_INDEX(scissor_test.mode): 357 case PICA_REG_INDEX(scissor_test.mode):
358 shader_dirty = true; 358 shader_dirty = true;
359 break; 359 break;
360 case PICA_REG_INDEX(scissor_test.right): 360 case PICA_REG_INDEX(scissor_test.x1): // and y1
361 case PICA_REG_INDEX(scissor_test.left_minus_1): 361 case PICA_REG_INDEX(scissor_test.x2): // and y2
362 SyncScissorTest(); 362 SyncScissorTest();
363 break; 363 break;
364 364
@@ -1179,15 +1179,15 @@ void RasterizerOpenGL::SyncDepthTest() {
1179void RasterizerOpenGL::SyncScissorTest() { 1179void RasterizerOpenGL::SyncScissorTest() {
1180 const auto& regs = Pica::g_state.regs; 1180 const auto& regs = Pica::g_state.regs;
1181 1181
1182 if (uniform_block_data.data.scissor_right != regs.scissor_test.right || 1182 if (uniform_block_data.data.scissor_x1 != regs.scissor_test.x1 ||
1183 uniform_block_data.data.scissor_bottom != regs.scissor_test.bottom || 1183 uniform_block_data.data.scissor_y1 != regs.scissor_test.y1 ||
1184 uniform_block_data.data.scissor_left != regs.scissor_test.GetLeft() || 1184 uniform_block_data.data.scissor_x2 != regs.scissor_test.x2 ||
1185 uniform_block_data.data.scissor_top != regs.scissor_test.GetTop()) { 1185 uniform_block_data.data.scissor_y2 != regs.scissor_test.y2) {
1186 1186
1187 uniform_block_data.data.scissor_right = regs.scissor_test.right; 1187 uniform_block_data.data.scissor_x1 = regs.scissor_test.x1;
1188 uniform_block_data.data.scissor_bottom = regs.scissor_test.bottom; 1188 uniform_block_data.data.scissor_y1 = regs.scissor_test.y1;
1189 uniform_block_data.data.scissor_left = regs.scissor_test.GetLeft(); 1189 uniform_block_data.data.scissor_x2 = regs.scissor_test.x2;
1190 uniform_block_data.data.scissor_top = regs.scissor_test.GetTop(); 1190 uniform_block_data.data.scissor_y2 = regs.scissor_test.y2;
1191 uniform_block_data.dirty = true; 1191 uniform_block_data.dirty = true;
1192 } 1192 }
1193} 1193}
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:
331 GLint alphatest_ref; 331 GLint alphatest_ref;
332 GLfloat depth_scale; 332 GLfloat depth_scale;
333 GLfloat depth_offset; 333 GLfloat depth_offset;
334 GLint scissor_right; 334 GLint scissor_x1;
335 GLint scissor_bottom; 335 GLint scissor_y1;
336 GLint scissor_left; 336 GLint scissor_x2;
337 GLint scissor_top; 337 GLint scissor_y2;
338 alignas(16) GLvec3 fog_color; 338 alignas(16) GLvec3 fog_color;
339 alignas(16) GLvec3 lighting_global_ambient; 339 alignas(16) GLvec3 lighting_global_ambient;
340 LightSrc light_src[8]; 340 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 {
557 int alphatest_ref; 557 int alphatest_ref;
558 float depth_scale; 558 float depth_scale;
559 float depth_offset; 559 float depth_offset;
560 int scissor_right; 560 int scissor_x1;
561 int scissor_bottom; 561 int scissor_y1;
562 int scissor_left; 562 int scissor_x2;
563 int scissor_top; 563 int scissor_y2;
564 vec3 fog_color; 564 vec3 fog_color;
565 vec3 lighting_global_ambient; 565 vec3 lighting_global_ambient;
566 LightSrc light_src[NUM_LIGHTS]; 566 LightSrc light_src[NUM_LIGHTS];
@@ -589,13 +589,14 @@ vec4 secondary_fragment_color = vec4(0.0);
589 } 589 }
590 590
591 // Append the scissor test 591 // Append the scissor test
592 if (state.scissor_test_mode == Regs::ScissorMode::Include || state.scissor_test_mode == Regs::ScissorMode::Exclude) { 592 if (state.scissor_test_mode != Regs::ScissorMode::Disabled) {
593 out += "if (scissor_left <= scissor_right || scissor_top <= scissor_bottom) discard;\n";
594 out += "if ("; 593 out += "if (";
595 // Negate the condition if we have to keep only the pixels outside the scissor box 594 // Negate the condition if we have to keep only the pixels outside the scissor box
596 if (state.scissor_test_mode == Regs::ScissorMode::Include) 595 if (state.scissor_test_mode == Regs::ScissorMode::Include)
597 out += "!"; 596 out += "!";
598 out += "(gl_FragCoord.x >= scissor_right && gl_FragCoord.x <= scissor_left && gl_FragCoord.y >= scissor_bottom && gl_FragCoord.y <= scissor_top)) discard;\n"; 597 // x2,y2 have +1 added to cover the entire pixel area
598 out += "(gl_FragCoord.x >= scissor_x1 && gl_FragCoord.x < scissor_x2 + 1 && "
599 "gl_FragCoord.y >= scissor_y1 && gl_FragCoord.y < scissor_y2 + 1)) discard;\n";
599 } 600 }
600 601
601 out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; 602 out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n";