This commit is contained in:
Jakly 2024-11-12 12:56:34 +01:00 committed by GitHub
commit d7f39a2f2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 71 deletions

View File

@ -774,8 +774,8 @@ void SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
interp_start = &rp->SlopeR.Interp; interp_start = &rp->SlopeR.Interp;
interp_end = &rp->SlopeL.Interp; interp_end = &rp->SlopeL.Interp;
rp->SlopeR.EdgeParams<true>(&l_edgelen, &l_edgecov); rp->SlopeR.EdgeParams(&l_edgelen, &l_edgecov, true);
rp->SlopeL.EdgeParams<true>(&r_edgelen, &r_edgecov); rp->SlopeL.EdgeParams(&r_edgelen, &r_edgecov, true);
std::swap(xstart, xend); std::swap(xstart, xend);
std::swap(wl, wr); std::swap(wl, wr);
@ -806,9 +806,9 @@ void SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
interp_start = &rp->SlopeL.Interp; interp_start = &rp->SlopeL.Interp;
interp_end = &rp->SlopeR.Interp; interp_end = &rp->SlopeR.Interp;
rp->SlopeL.EdgeParams<false>(&l_edgelen, &l_edgecov); rp->SlopeL.EdgeParams(&l_edgelen, &l_edgecov, false);
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov); rp->SlopeR.EdgeParams(&r_edgelen, &r_edgecov, false);
// CHECKME: edge fill rules for unswapped opaque shadow mask polygons // CHECKME: edge fill rules for unswapped opaque shadow mask polygons
if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe) if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe)
{ {
@ -1003,8 +1003,8 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
interp_start = &rp->SlopeR.Interp; interp_start = &rp->SlopeR.Interp;
interp_end = &rp->SlopeL.Interp; interp_end = &rp->SlopeL.Interp;
rp->SlopeR.EdgeParams<true>(&l_edgelen, &l_edgecov); rp->SlopeR.EdgeParams(&l_edgelen, &l_edgecov, true);
rp->SlopeL.EdgeParams<true>(&r_edgelen, &r_edgecov); rp->SlopeL.EdgeParams(&r_edgelen, &r_edgecov, true);
std::swap(xstart, xend); std::swap(xstart, xend);
std::swap(wl, wr); std::swap(wl, wr);
@ -1041,8 +1041,8 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
interp_start = &rp->SlopeL.Interp; interp_start = &rp->SlopeL.Interp;
interp_end = &rp->SlopeR.Interp; interp_end = &rp->SlopeR.Interp;
rp->SlopeL.EdgeParams<false>(&l_edgelen, &l_edgecov); rp->SlopeL.EdgeParams(&l_edgelen, &l_edgecov, false);
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov); rp->SlopeR.EdgeParams(&r_edgelen, &r_edgecov, false);
// edge fill rules for unswapped opaque edges: // edge fill rules for unswapped opaque edges:
// * right edge is filled if slope > 1 // * right edge is filled if slope > 1
@ -1096,18 +1096,11 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
if (x < 0) x = 0; if (x < 0) x = 0;
s32 xlimit; s32 xlimit;
s32 xcov = 0;
// part 1: left edge // part 1: left edge
edge = yedge | 0x1; edge = yedge | 0x1;
xlimit = xstart+l_edgelen; xlimit = xstart+l_edgelen;
if (xlimit > xend+1) xlimit = xend+1; if (xlimit > xend+1) xlimit = xend+1;
if (xlimit > 256) xlimit = 256; if (xlimit > 256) xlimit = 256;
if (l_edgecov & (1<<31))
{
xcov = (l_edgecov >> 12) & 0x3FF;
if (xcov == 0x3FF) xcov = 0;
}
if (!l_filledge) x = xlimit; if (!l_filledge) x = xlimit;
else else
@ -1166,14 +1159,12 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
// anti-aliasing: all edges are rendered // anti-aliasing: all edges are rendered
// calculate coverage // calculate coverage
s32 cov = l_edgecov; attr |= (l_edgecov >> 5) << 8;
if (cov & (1<<31)) if (x < xlimit-1)
{ {
cov = xcov >> 5; l_edgecov += rp->SlopeL.XCov_Incr;
if (cov > 31) cov = 31; if (l_edgecov > 0x3FF) l_edgecov = 0x3FF;
xcov += (l_edgecov & 0x3FF);
} }
attr |= (cov << 8);
// push old pixel down if needed // push old pixel down if needed
if (pixeladdr < BufferSize) if (pixeladdr < BufferSize)
@ -1292,11 +1283,6 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
edge = yedge | 0x2; edge = yedge | 0x2;
xlimit = xend+1; xlimit = xend+1;
if (xlimit > 256) xlimit = 256; if (xlimit > 256) xlimit = 256;
if (r_edgecov & (1<<31))
{
xcov = (r_edgecov >> 12) & 0x3FF;
if (xcov == 0x3FF) xcov = 0;
}
if (r_filledge) if (r_filledge)
for (; x < xlimit; x++) for (; x < xlimit; x++)
@ -1354,14 +1340,12 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
// anti-aliasing: all edges are rendered // anti-aliasing: all edges are rendered
// calculate coverage // calculate coverage
s32 cov = r_edgecov; attr |= (r_edgecov >> 5) << 8;
if (cov & (1<<31)) if (x < xlimit-1)
{ {
cov = 0x1F - (xcov >> 5); r_edgecov -= rp->SlopeR.XCov_Incr;
if (cov < 0) cov = 0; if (r_edgecov < 0) r_edgecov = 0;
xcov += (r_edgecov & 0x3FF);
} }
attr |= (cov << 8);
// push old pixel down if needed // push old pixel down if needed
if (pixeladdr < BufferSize) if (pixeladdr < BufferSize)

View File

@ -238,6 +238,7 @@ private:
dx = 0; dx = 0;
this->x0 = x0; this->x0 = x0;
this->y0 = y0;
this->xmin = x0; this->xmin = x0;
this->xmax = x0; this->xmax = x0;
@ -247,7 +248,7 @@ private:
Interp.Setup(0, 0, 0, 0); Interp.Setup(0, 0, 0, 0);
Interp.SetX(0); Interp.SetX(0);
xcov_incr = 0; XCov_Incr = 0;
return x0; return x0;
} }
@ -255,6 +256,7 @@ private:
constexpr s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y) constexpr s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y)
{ {
this->x0 = x0; this->x0 = x0;
this->y0 = y0;
this->y = y; this->y = y;
if (x1 > x0) if (x1 > x0)
@ -322,7 +324,7 @@ private:
Interp.SetX(y); Interp.SetX(y);
// used for calculating AA coverage // used for calculating AA coverage
if (XMajor) xcov_incr = (ylen << 10) / xlen; if (XMajor) XCov_Incr = ((ylen << 10) / xlen) & 0x3FF;
return x; return x;
} }
@ -347,19 +349,15 @@ private:
else if (ret > xmax) ret = xmax; else if (ret > xmax) ret = xmax;
return ret; return ret;
} }
template<bool swapped> constexpr void EdgeParams_XMajor(s32* length, s32* coverage, bool swapped) const
constexpr void EdgeParams_XMajor(s32* length, s32* coverage) const
{ {
// only do length calc for right side when swapped as it's // only do length calc for right side when swapped as it's
// only needed for aa calcs, as actual line spans are broken // only needed for aa calcs, as actual line spans are broken
if constexpr (!swapped || side) if (side ^ Negative)
{ *length = (dx >> 18) - ((dx-Increment) >> 18);
if (side ^ Negative) else
*length = (dx >> 18) - ((dx-Increment) >> 18); *length = ((dx+Increment) >> 18) - (dx >> 18);
else
*length = ((dx+Increment) >> 18) - (dx >> 18);
}
// for X-major edges, we return the coverage // for X-major edges, we return the coverage
// for the first pixel, and the increment for // for the first pixel, and the increment for
@ -369,13 +367,20 @@ private:
if (side) startx = startx - *length + 1; if (side) startx = startx - *length + 1;
s32 startcov = (((startx << 10) + 0x1FF) * ylen) / xlen; s32 startcov = (((startx << 10) + 0x1FF) * ylen) / xlen;
*coverage = (1<<31) | ((startcov & 0x3FF) << 12) | (xcov_incr & 0x3FF);
if constexpr (swapped) *length = 1; // fix the y value for negative slopes
s32 ycoord = Negative ? (ylen << 10) - startcov >> 10 : startcov >> 10;
// if yvalue is not equal to actual y value, invert coverage value
startcov &= 0x3FF;
if (ycoord != y - y0) startcov = 0x3FF - startcov;
if (side ^ swapped) startcov = 0x3FF - startcov;
*coverage = startcov;
if (swapped) *length = 1;
} }
template<bool swapped> constexpr void EdgeParams_YMajor(s32* length, s32* coverage, bool swapped) const
constexpr void EdgeParams_YMajor(s32* length, s32* coverage) const
{ {
*length = 1; *length = 1;
@ -383,51 +388,39 @@ private:
{ {
// for some reason vertical edges' aa values // for some reason vertical edges' aa values
// are inverted too when the edges are swapped // are inverted too when the edges are swapped
if constexpr (swapped) *coverage = swapped ? 0 : 31 << 5;
*coverage = 0;
else
*coverage = 31;
} }
else else
{ {
s32 cov = ((dx >> 9) + (Increment >> 10)) >> 4; s32 cov = ((dx >> 9) + (Increment >> 10)) >> 4;
if ((cov >> 5) != (dx >> 18)) cov = 31; if ((cov >> 5) != (dx >> 18)) cov = 31;
cov &= 0x1F; cov &= 0x1F;
if constexpr (swapped) if (side ^ !Negative ^ swapped) cov = 0x1F - cov;
{
if (side ^ Negative) cov = 0x1F - cov;
}
else
{
if (!(side ^ Negative)) cov = 0x1F - cov;
}
*coverage = cov; // shift left 5 just to make it align with xmajor coverage values
*coverage = cov << 5;
} }
} }
template<bool swapped> constexpr void EdgeParams(s32* length, s32* coverage, bool swapped) const
constexpr void EdgeParams(s32* length, s32* coverage) const
{ {
if (XMajor) if (XMajor)
return EdgeParams_XMajor<swapped>(length, coverage); return EdgeParams_XMajor(length, coverage, swapped);
else else
return EdgeParams_YMajor<swapped>(length, coverage); return EdgeParams_YMajor(length, coverage, swapped);
} }
s32 Increment; s32 Increment;
bool Negative; bool Negative;
bool XMajor; bool XMajor;
Interpolator<1> Interp; Interpolator<1> Interp;
s32 XCov_Incr;
private: private:
s32 x0, xmin, xmax; s32 x0, y0, xmin, xmax;
s32 xlen, ylen; s32 xlen, ylen;
s32 dx; s32 dx;
s32 y; s32 y;
s32 xcov_incr;
s32 ycoverage, ycov_incr;
}; };
u32 AlphaBlend(const GPU3D& gpu3d, u32 srccolor, u32 dstcolor, u32 alpha) const noexcept; u32 AlphaBlend(const GPU3D& gpu3d, u32 srccolor, u32 dstcolor, u32 alpha) const noexcept;