diff options
| author | 2016-01-24 22:59:16 -0800 | |
|---|---|---|
| committer | 2016-06-27 21:14:39 -0700 | |
| commit | f0b9bc14b64765bd8bc78cb4cfb4a30eb9ab9324 (patch) | |
| tree | 5980ec623e974d6c9b71291d417365cfbe4ae4fc /src | |
| parent | PICA: Implement scissor test (diff) | |
| download | yuzu-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.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 { | |||
| 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() { | |||
| 1179 | void RasterizerOpenGL::SyncScissorTest() { | 1179 | void 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"; |