Several small optimizations.
This commit is contained in:
parent
176ea06e82
commit
987bd8bb8f
|
@ -314,6 +314,22 @@ static void BuildBlock(s32 blockX, s32 blockY)
|
|||
}
|
||||
}
|
||||
|
||||
inline void PrepareBlock(s32 blockX, s32 blockY)
|
||||
{
|
||||
static s32 x = -1;
|
||||
static s32 y = -1;
|
||||
|
||||
blockX &= ~(BLOCK_SIZE - 1);
|
||||
blockY &= ~(BLOCK_SIZE - 1);
|
||||
|
||||
if (x != blockX || y != blockY)
|
||||
{
|
||||
x = blockX;
|
||||
y = blockY;
|
||||
BuildBlock(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
|
||||
{
|
||||
INCSTAT(swstats.thisFrame.numTrianglesDrawn);
|
||||
|
@ -401,10 +417,6 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
InitSlope(&TexSlopes[i][comp], v0->texCoords[i][comp] * w[0], v1->texCoords[i][comp] * w[1], v2->texCoords[i][comp] * w[2], fltdx31, fltdx12, fltdy12, fltdy31);
|
||||
}
|
||||
|
||||
// Start in corner of 8x8 block
|
||||
minx &= ~(BLOCK_SIZE - 1);
|
||||
miny &= ~(BLOCK_SIZE - 1);
|
||||
|
||||
// Half-edge constants
|
||||
s32 C1 = DY12 * X1 - DX12 * Y1;
|
||||
s32 C2 = DY23 * X2 - DX23 * Y2;
|
||||
|
@ -418,6 +430,10 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
// If drawing, rasterize every block
|
||||
if (!BoundingBox::active)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -499,8 +515,25 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
}
|
||||
else
|
||||
{
|
||||
// If we are only calculating bbox, we only need to find the topmost,
|
||||
// leftmost, bottom most and rightmost pixels to be drawn.
|
||||
// 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
|
||||
|
@ -531,8 +564,7 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
if (CX1 > 0 && CX2 > 0 && CX3 > 0)
|
||||
{
|
||||
// Build the new raster block every other pixel
|
||||
BuildBlock((x & ~(BLOCK_SIZE - 1)), y & ~(BLOCK_SIZE - 1));
|
||||
|
||||
PrepareBlock(x, y);
|
||||
Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
|
||||
|
||||
if (y >= BoundingBox::coords[BoundingBox::TOP])
|
||||
|
@ -549,6 +581,9 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
CY3 += FDX31;
|
||||
}
|
||||
|
||||
// Update top limit
|
||||
miny = std::max((s32) BoundingBox::coords[BoundingBox::TOP], miny);
|
||||
|
||||
// Checking for bbox left
|
||||
s32 CX1 = C1 + DX12 * FTOP - DY12 * FLEFT;
|
||||
s32 CX2 = C2 + DX23 * FTOP - DY23 * FLEFT;
|
||||
|
@ -568,9 +603,7 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
{
|
||||
if (CY1 > 0 && CY2 > 0 && CY3 > 0)
|
||||
{
|
||||
// Build the new raster block every other pixel
|
||||
BuildBlock((x & ~(BLOCK_SIZE - 1)), y & ~(BLOCK_SIZE - 1));
|
||||
|
||||
PrepareBlock(x, y);
|
||||
Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
|
||||
|
||||
if (x >= BoundingBox::coords[BoundingBox::LEFT])
|
||||
|
@ -587,6 +620,9 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
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;
|
||||
|
@ -607,8 +643,7 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
if (CX1 > 0 && CX2 > 0 && CX3 > 0)
|
||||
{
|
||||
// Build the new raster block every other pixel
|
||||
BuildBlock((x & ~(BLOCK_SIZE - 1)), y & ~(BLOCK_SIZE - 1));
|
||||
|
||||
PrepareBlock(x, y);
|
||||
Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
|
||||
|
||||
if (y <= BoundingBox::coords[BoundingBox::BOTTOM])
|
||||
|
@ -625,6 +660,9 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
CY3 -= FDX31;
|
||||
}
|
||||
|
||||
// Update bottom limit
|
||||
maxy = std::min((s32) BoundingBox::coords[BoundingBox::BOTTOM], maxy);
|
||||
|
||||
// Checking for bbox right
|
||||
CX1 = C1 + DX12 * FBOTTOM - DY12 * FRIGHT;
|
||||
CX2 = C2 + DX23 * FBOTTOM - DY23 * FRIGHT;
|
||||
|
@ -645,8 +683,7 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
|
|||
if (CY1 > 0 && CY2 > 0 && CY3 > 0)
|
||||
{
|
||||
// Build the new raster block every other pixel
|
||||
BuildBlock((x & ~(BLOCK_SIZE - 1)), y & ~(BLOCK_SIZE - 1));
|
||||
|
||||
PrepareBlock(x, y);
|
||||
Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
|
||||
|
||||
if (x <= BoundingBox::coords[BoundingBox::RIGHT])
|
||||
|
|
Loading…
Reference in New Issue