summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/Rasterizer.cpp
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2015-09-17 18:42:17 +0200
committerMarkus Wick <degasus@users.noreply.github.com>2015-09-17 18:42:17 +0200
commitedae1d3bcb4383abd344757c4eab13d975a5e153 (patch)
tree4395c37354ac9d51ce86b6d029c6bbd8a9ca4bcf /Source/Core/VideoBackends/Software/Rasterizer.cpp
parent52de4cc476429d77240434c4c0c6fcaff353f39a (diff)
parent3b5b80bf3c209b01a4835a2aa0729fc6b3f38d40 (diff)
Merge pull request #3055 from degasus/videosw
Video Software cleanup
Diffstat (limited to 'Source/Core/VideoBackends/Software/Rasterizer.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/Rasterizer.cpp328
1 files changed, 64 insertions, 264 deletions
diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp
index 9b6b9f593a..0db2765944 100644
--- a/Source/Core/VideoBackends/Software/Rasterizer.cpp
+++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp
@@ -7,7 +7,6 @@
#include "Common/CommonTypes.h"
#include "VideoBackends/Software/BPMemLoader.h"
#include "VideoBackends/Software/EfbInterface.h"
-#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/NativeVertexFormat.h"
#include "VideoBackends/Software/Rasterizer.h"
#include "VideoBackends/Software/SWStatistics.h"
@@ -129,7 +128,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi)
s32 z = (s32)MathUtil::Clamp<float>(ZSlope.GetValue(dx, dy), 0.0f, 16777215.0f);
- if (!BoundingBox::active && bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc)
+ if (bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc)
{
// TODO: Test if perf regs are incremented even if test is disabled
EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT_ZCOMPLOC);
@@ -332,12 +331,6 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
{
INCSTAT(swstats.thisFrame.numTrianglesDrawn);
- if (g_SWVideoConfig.bHwRasterizer && !BoundingBox::active)
- {
- HwRasterizer::DrawTriangleFrontFace(v0, v1, v2);
- return;
- }
-
// adapted from http://devmaster.net/posts/6145/advanced-rasterization
// 28.4 fixed-pou32 coordinates. rounded to nearest and adjusted to match hardware output
@@ -425,279 +418,86 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
- // If drawing, rasterize every block
- if (!BoundingBox::active)
- {
- // Start in corner of 8x8 block
- minx &= ~(BLOCK_SIZE - 1);
- miny &= ~(BLOCK_SIZE - 1);
+ // Start in corner of 8x8 block
+ minx &= ~(BLOCK_SIZE - 1);
+ miny &= ~(BLOCK_SIZE - 1);
- // Loop through blocks
- for (s32 y = miny; y < maxy; y += BLOCK_SIZE)
+ // Loop through blocks
+ for (s32 y = miny; y < maxy; y += BLOCK_SIZE)
+ {
+ for (s32 x = minx; x < maxx; x += BLOCK_SIZE)
{
- for (s32 x = minx; x < maxx; x += BLOCK_SIZE)
+ // Corners of block
+ s32 x0 = x << 4;
+ s32 x1 = (x + BLOCK_SIZE - 1) << 4;
+ s32 y0 = y << 4;
+ s32 y1 = (y + BLOCK_SIZE - 1) << 4;
+
+ // Evaluate half-space functions
+ bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
+ bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
+ bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
+ bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
+ int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
+
+ bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
+ bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
+ bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
+ bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
+ int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
+
+ bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
+ bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
+ bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
+ bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
+ int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);
+
+ // Skip block when outside an edge
+ if (a == 0x0 || b == 0x0 || c == 0x0)
+ continue;
+
+ BuildBlock(x, y);
+
+ // Accept whole block when totally covered
+ if (a == 0xF && b == 0xF && c == 0xF)
{
- // Corners of block
- s32 x0 = x << 4;
- s32 x1 = (x + BLOCK_SIZE - 1) << 4;
- s32 y0 = y << 4;
- s32 y1 = (y + BLOCK_SIZE - 1) << 4;
-
- // Evaluate half-space functions
- bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
- bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
- bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
- bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
- int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
-
- bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
- bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
- bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
- bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
- int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
-
- bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
- bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
- bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
- bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
- int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);
-
- // Skip block when outside an edge
- if (a == 0x0 || b == 0x0 || c == 0x0)
- continue;
-
- BuildBlock(x, y);
-
- // Accept whole block when totally covered
- if (a == 0xF && b == 0xF && c == 0xF)
+ for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
{
- for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
+ for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
{
- for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
- {
- Draw(x + ix, y + iy, ix, iy);
- }
+ Draw(x + ix, y + iy, ix, iy);
}
}
- else // Partially covered block
+ }
+ else // Partially covered block
+ {
+ s32 CY1 = C1 + DX12 * y0 - DY12 * x0;
+ s32 CY2 = C2 + DX23 * y0 - DY23 * x0;
+ s32 CY3 = C3 + DX31 * y0 - DY31 * x0;
+
+ for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
{
- s32 CY1 = C1 + DX12 * y0 - DY12 * x0;
- s32 CY2 = C2 + DX23 * y0 - DY23 * x0;
- s32 CY3 = C3 + DX31 * y0 - DY31 * x0;
+ s32 CX1 = CY1;
+ s32 CX2 = CY2;
+ s32 CX3 = CY3;
- for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
+ for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
{
- s32 CX1 = CY1;
- s32 CX2 = CY2;
- s32 CX3 = CY3;
-
- for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
+ if (CX1 > 0 && CX2 > 0 && CX3 > 0)
{
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- Draw(x + ix, y + iy, ix, iy);
- }
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
+ Draw(x + ix, y + iy, ix, iy);
}
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
+ CX1 -= FDY12;
+ CX2 -= FDY23;
+ CX3 -= FDY31;
}
- }
- }
- }
- }
- else
- {
- // Calculating bbox
- // First check for alpha channel - don't do anything it if always fails,
- // Change bbox to primitive size if it always passes
- AlphaTest::TEST_RESULT alphaRes = bpmem.alpha_test.TestResult();
-
- if (alphaRes != AlphaTest::UNDETERMINED)
- {
- if (alphaRes == AlphaTest::PASS)
- {
- BoundingBox::coords[BoundingBox::TOP] = std::min(BoundingBox::coords[BoundingBox::TOP], (u16) miny);
- BoundingBox::coords[BoundingBox::LEFT] = std::min(BoundingBox::coords[BoundingBox::LEFT], (u16) minx);
- BoundingBox::coords[BoundingBox::BOTTOM] = std::max(BoundingBox::coords[BoundingBox::BOTTOM], (u16) maxy);
- BoundingBox::coords[BoundingBox::RIGHT] = std::max(BoundingBox::coords[BoundingBox::RIGHT], (u16) maxx);
- }
- return;
- }
-
- // If we are calculating bbox with alpha, we only need to find the
- // topmost, leftmost, bottom most and rightmost pixels to be drawn.
- // So instead of drawing every single one of the triangle's pixels,
- // four loops are run: one for the top pixel, one for the left, one for
- // the bottom and one for the right. As soon as a pixel that is to be
- // drawn is found, the loop breaks. This enables a ~150% speedbost in
- // bbox calculation, albeit at the cost of some ugly repetitive code.
- const s32 FLEFT = minx << 4;
- const s32 FRIGHT = maxx << 4;
- s32 FTOP = miny << 4;
- s32 FBOTTOM = maxy << 4;
-
- // Start checking for bbox top
- s32 CY1 = C1 + DX12 * FTOP - DY12 * FLEFT;
- s32 CY2 = C2 + DX23 * FTOP - DY23 * FLEFT;
- s32 CY3 = C3 + DX31 * FTOP - DY31 * FLEFT;
-
- // Loop
- for (s32 y = miny; y <= maxy; ++y)
- {
- if (y >= BoundingBox::coords[BoundingBox::TOP])
- break;
- s32 CX1 = CY1;
- s32 CX2 = CY2;
- s32 CX3 = CY3;
-
- for (s32 x = minx; x <= maxx; ++x)
- {
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (y >= BoundingBox::coords[BoundingBox::TOP])
- break;
+ CY1 += FDX12;
+ CY2 += FDX23;
+ CY3 += FDX31;
}
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
}
-
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
- }
-
- // Update top limit
- miny = std::max((s32) BoundingBox::coords[BoundingBox::TOP], miny);
- FTOP = miny << 4;
-
- // Checking for bbox left
- s32 CX1 = C1 + DX12 * FTOP - DY12 * FLEFT;
- s32 CX2 = C2 + DX23 * FTOP - DY23 * FLEFT;
- s32 CX3 = C3 + DX31 * FTOP - DY31 * FLEFT;
-
- // Loop
- for (s32 x = minx; x <= maxx; ++x)
- {
- if (x >= BoundingBox::coords[BoundingBox::LEFT])
- break;
-
- CY1 = CX1;
- CY2 = CX2;
- CY3 = CX3;
-
- for (s32 y = miny; y <= maxy; ++y)
- {
- if (CY1 > 0 && CY2 > 0 && CY3 > 0)
- {
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (x >= BoundingBox::coords[BoundingBox::LEFT])
- break;
- }
-
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
- }
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
- }
-
- // Update left limit
- minx = std::max((s32) BoundingBox::coords[BoundingBox::LEFT], minx);
-
- // Checking for bbox bottom
- CY1 = C1 + DX12 * FBOTTOM - DY12 * FRIGHT;
- CY2 = C2 + DX23 * FBOTTOM - DY23 * FRIGHT;
- CY3 = C3 + DX31 * FBOTTOM - DY31 * FRIGHT;
-
- // Loop
- for (s32 y = maxy; y >= miny; --y)
- {
- CX1 = CY1;
- CX2 = CY2;
- CX3 = CY3;
-
- if (y <= BoundingBox::coords[BoundingBox::BOTTOM])
- break;
-
- for (s32 x = maxx; x >= minx; --x)
- {
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (y <= BoundingBox::coords[BoundingBox::BOTTOM])
- break;
- }
-
- CX1 += FDY12;
- CX2 += FDY23;
- CX3 += FDY31;
- }
-
- CY1 -= FDX12;
- CY2 -= FDX23;
- CY3 -= FDX31;
- }
-
- // Update bottom limit
- maxy = std::min((s32) BoundingBox::coords[BoundingBox::BOTTOM], maxy);
- FBOTTOM = maxy << 4;
-
- // Checking for bbox right
- CX1 = C1 + DX12 * FBOTTOM - DY12 * FRIGHT;
- CX2 = C2 + DX23 * FBOTTOM - DY23 * FRIGHT;
- CX3 = C3 + DX31 * FBOTTOM - DY31 * FRIGHT;
-
- // Loop
- for (s32 x = maxx; x >= minx; --x)
- {
- if (x <= BoundingBox::coords[BoundingBox::RIGHT])
- break;
-
- CY1 = CX1;
- CY2 = CX2;
- CY3 = CX3;
-
- for (s32 y = maxy; y >= miny; --y)
- {
- if (CY1 > 0 && CY2 > 0 && CY3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (x <= BoundingBox::coords[BoundingBox::RIGHT])
- break;
- }
-
- CY1 -= FDX12;
- CY2 -= FDX23;
- CY3 -= FDX31;
- }
-
- CX1 += FDY12;
- CX2 += FDY23;
- CX3 += FDY31;
}
}
}