diff options
| author | 2015-12-02 13:23:51 -0500 | |
|---|---|---|
| committer | 2016-06-27 21:14:13 -0700 | |
| commit | f9be06b15f08cb559580e1d19b43158640a37d67 (patch) | |
| tree | 9b20e75d7ef02e0feac2be0cb96843ebbb6814f8 /src/video_core/rasterizer.cpp | |
| parent | Merge pull request #1930 from scurest/superfluous-moves (diff) | |
| download | yuzu-f9be06b15f08cb559580e1d19b43158640a37d67.tar.gz yuzu-f9be06b15f08cb559580e1d19b43158640a37d67.tar.xz yuzu-f9be06b15f08cb559580e1d19b43158640a37d67.zip | |
PICA: Implement scissor test
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index a84170094..514d64208 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -338,12 +338,25 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 338 | return; | 338 | return; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | // TODO: Proper scissor rect test! | ||
| 342 | u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); | 341 | u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); |
| 343 | u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); | 342 | u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); |
| 344 | u16 max_x = std::max({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); | 343 | u16 max_x = std::max({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); |
| 345 | 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}); |
| 346 | 345 | ||
| 346 | // Convert the scissor box coordinates to 12.4 fixed point | ||
| 347 | u16 scissor_left = (u16)(regs.scissor_test.GetLeft() << 4); | ||
| 348 | u16 scissor_top = (u16)(regs.scissor_test.GetTop() << 4); | ||
| 349 | u16 scissor_right = (u16)(regs.scissor_test.right << 4); | ||
| 350 | u16 scissor_bottom = (u16)(regs.scissor_test.bottom << 4); | ||
| 351 | |||
| 352 | if (regs.scissor_test.mode == Regs::ScissorMode::Include) { | ||
| 353 | // Calculate the new bounds | ||
| 354 | min_x = std::max(min_x, scissor_right); | ||
| 355 | min_y = std::max(min_y, scissor_bottom); | ||
| 356 | max_x = std::min(max_x, scissor_left); | ||
| 357 | max_y = std::min(max_y, scissor_top); | ||
| 358 | } | ||
| 359 | |||
| 347 | min_x &= Fix12P4::IntMask(); | 360 | min_x &= Fix12P4::IntMask(); |
| 348 | min_y &= Fix12P4::IntMask(); | 361 | min_y &= Fix12P4::IntMask(); |
| 349 | max_x = ((max_x + Fix12P4::FracMask()) & Fix12P4::IntMask()); | 362 | max_x = ((max_x + Fix12P4::FracMask()) & Fix12P4::IntMask()); |
| @@ -383,6 +396,13 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 383 | for (u16 y = min_y + 8; y < max_y; y += 0x10) { | 396 | for (u16 y = min_y + 8; y < max_y; y += 0x10) { |
| 384 | for (u16 x = min_x + 8; x < max_x; x += 0x10) { | 397 | for (u16 x = min_x + 8; x < max_x; x += 0x10) { |
| 385 | 398 | ||
| 399 | // 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 | x >= scissor_right && x <= scissor_left && | ||
| 402 | y >= scissor_bottom && y <= scissor_top) { | ||
| 403 | continue; | ||
| 404 | } | ||
| 405 | |||
| 386 | // Calculate the barycentric coordinates w0, w1 and w2 | 406 | // Calculate the barycentric coordinates w0, w1 and w2 |
| 387 | int w0 = bias0 + SignedArea(vtxpos[1].xy(), vtxpos[2].xy(), {x, y}); | 407 | int w0 = bias0 + SignedArea(vtxpos[1].xy(), vtxpos[2].xy(), {x, y}); |
| 388 | int w1 = bias1 + SignedArea(vtxpos[2].xy(), vtxpos[0].xy(), {x, y}); | 408 | int w1 = bias1 + SignedArea(vtxpos[2].xy(), vtxpos[0].xy(), {x, y}); |