diff options
| author | Markus Wick <degasus@users.noreply.github.com> | 2015-09-17 18:42:17 +0200 |
|---|---|---|
| committer | Markus Wick <degasus@users.noreply.github.com> | 2015-09-17 18:42:17 +0200 |
| commit | edae1d3bcb4383abd344757c4eab13d975a5e153 (patch) | |
| tree | 4395c37354ac9d51ce86b6d029c6bbd8a9ca4bcf /Source/Core/VideoBackends/Software/Rasterizer.cpp | |
| parent | 52de4cc476429d77240434c4c0c6fcaff353f39a (diff) | |
| parent | 3b5b80bf3c209b01a4835a2aa0729fc6b3f38d40 (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.cpp | 328 |
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; } } } |
