parent
72ffe6b297
commit
0b85038586
|
@ -825,7 +825,6 @@ void SoftRenderer::CheckSlope(RendererPolygon* rp, s32 y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool accuracy>
|
|
||||||
bool SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y, s32* timingcounter)
|
bool SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y, s32* timingcounter)
|
||||||
{
|
{
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
|
@ -958,20 +957,15 @@ bool SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
|
||||||
if (x < 0) x = 0;
|
if (x < 0) x = 0;
|
||||||
s32 xlimit;
|
s32 xlimit;
|
||||||
|
|
||||||
if (accuracy)
|
// determine if the span can be rendered within the time allotted to the scanline
|
||||||
|
s32 diff = DoTimingsPixels(xend-x, timingcounter);
|
||||||
|
if (diff != 0)
|
||||||
{
|
{
|
||||||
// determine if the span can be rendered within the time allotted to the scanline
|
xend -= diff;
|
||||||
// TODO: verify the timing characteristics of shadow masks are the same as regular polygons.
|
r_edgelen -= diff;
|
||||||
s32 diff = DoTimingsPixels(xend-x, timingcounter);
|
abortscanline = true;
|
||||||
if (diff != 0)
|
|
||||||
{
|
|
||||||
xend -= diff;
|
|
||||||
r_edgelen -= diff;
|
|
||||||
abortscanline = true;
|
|
||||||
}
|
|
||||||
else abortscanline = false;
|
|
||||||
}
|
}
|
||||||
// note: if accuracy mode isn't enabled the abort flag never gets set, this is fine, because it also never gets used by fast mode.
|
else abortscanline = false;
|
||||||
|
|
||||||
// we cap it to 256 *after* counting the cycles, because yes, it tries to render oob pixels.
|
// we cap it to 256 *after* counting the cycles, because yes, it tries to render oob pixels.
|
||||||
if (xend > 256)
|
if (xend > 256)
|
||||||
|
@ -1064,7 +1058,6 @@ bool SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
|
||||||
return abortscanline;
|
return abortscanline;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool accuracy>
|
|
||||||
bool SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y, s32* timingcounter)
|
bool SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y, s32* timingcounter)
|
||||||
{
|
{
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
|
@ -1220,19 +1213,15 @@ bool SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
||||||
|
|
||||||
s32 xcov = 0;
|
s32 xcov = 0;
|
||||||
|
|
||||||
if (accuracy)
|
// determine if the span can be rendered within the time allotted to the scanline
|
||||||
|
s32 diff = DoTimingsPixels(xend-x, timingcounter);
|
||||||
|
if (diff != 0)
|
||||||
{
|
{
|
||||||
// determine if the span can be rendered within the time allotted to the scanline
|
xend -= diff;
|
||||||
s32 diff = DoTimingsPixels(xend-x, timingcounter);
|
r_edgelen -= diff;
|
||||||
if (diff != 0)
|
abortscanline = true;
|
||||||
{
|
|
||||||
xend -= diff;
|
|
||||||
r_edgelen -= diff;
|
|
||||||
abortscanline = true;
|
|
||||||
}
|
|
||||||
else abortscanline = false;
|
|
||||||
}
|
}
|
||||||
// note: if accuracy mode isn't enabled the abort flag never gets set, this is fine, because it also never gets used by fast mode.
|
else abortscanline = false;
|
||||||
|
|
||||||
// we cap it to 256 *after* counting the cycles, because yes, it tries to render oob pixels.
|
// we cap it to 256 *after* counting the cycles, because yes, it tries to render oob pixels.
|
||||||
if (xend > 256)
|
if (xend > 256)
|
||||||
|
@ -1528,7 +1517,6 @@ bool SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
||||||
return abortscanline;
|
return abortscanline;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool accuracy>
|
|
||||||
void SoftRenderer::RenderScanline(const GPU& gpu, s32 y, int firstpoly, int npolys, s32* timingcounter)
|
void SoftRenderer::RenderScanline(const GPU& gpu, s32 y, int firstpoly, int npolys, s32* timingcounter)
|
||||||
{
|
{
|
||||||
bool abort = false;
|
bool abort = false;
|
||||||
|
@ -1537,24 +1525,24 @@ void SoftRenderer::RenderScanline(const GPU& gpu, s32 y, int firstpoly, int npol
|
||||||
RendererPolygon* rp = &PolygonList[firstpoly];
|
RendererPolygon* rp = &PolygonList[firstpoly];
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
|
|
||||||
if (accuracy && y == polygon->YBottom && y != polygon->YTop)
|
if (y == polygon->YBottom && y != polygon->YTop)
|
||||||
{
|
{
|
||||||
if (!abort) abort = !DoTimings(EmptyPolyScanline, timingcounter);
|
if (!abort) abort = !DoTimings(EmptyPolyScanline, timingcounter);
|
||||||
}
|
}
|
||||||
else if (y >= polygon->YTop && (y < polygon->YBottom || (y == polygon->YTop && polygon->YBottom == polygon->YTop)))
|
else if (y >= polygon->YTop && (y < polygon->YBottom || (y == polygon->YTop && polygon->YBottom == polygon->YTop)))
|
||||||
{
|
{
|
||||||
if (accuracy && !abort) abort = (!DoTimings(PerPolyScanline, timingcounter)
|
if (!abort) abort = (!DoTimings(PerPolyScanline, timingcounter)
|
||||||
|| !CheckTimings(MinToStartPoly, timingcounter));
|
|| !CheckTimings(MinToStartPoly, timingcounter));
|
||||||
|
|
||||||
if (accuracy && abort)
|
if (abort)
|
||||||
{
|
{
|
||||||
CheckSlope(rp, y);
|
CheckSlope(rp, y);
|
||||||
Step(rp);
|
Step(rp);
|
||||||
}
|
}
|
||||||
else if (polygon->IsShadowMask)
|
else if (polygon->IsShadowMask)
|
||||||
abort = RenderShadowMaskScanline<accuracy>(gpu.GPU3D, rp, y, timingcounter);
|
abort = RenderShadowMaskScanline(gpu.GPU3D, rp, y, timingcounter);
|
||||||
else
|
else
|
||||||
abort = RenderPolygonScanline<accuracy>(gpu, rp, y, timingcounter);
|
abort = RenderPolygonScanline(gpu, rp, y, timingcounter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1891,29 +1879,6 @@ void SoftRenderer::ClearBuffers(const GPU& gpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftRenderer::RenderPolygonsFast(GPU& gpu, Polygon** polygons, int npolys)
|
|
||||||
{
|
|
||||||
gpu.GPU3D.RDLinesTemp = 46; // dumb way of making sure it gets updated to a "normal" value when the gpu starts rasterizing.
|
|
||||||
int j = 0;
|
|
||||||
for (int i = 0; i < npolys; i++)
|
|
||||||
{
|
|
||||||
if (polygons[i]->Degenerate) continue;
|
|
||||||
SetupPolygon(&PolygonList[j++], polygons[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderScanline<false>(gpu, 0, 0, j, nullptr);
|
|
||||||
|
|
||||||
for (s32 y = 1; y < 192; y++)
|
|
||||||
{
|
|
||||||
RenderScanline<false>(gpu, y, 0, j, nullptr);
|
|
||||||
ScanlineFinalPass<false>(gpu.GPU3D, y-1, true, true);
|
|
||||||
Platform::Semaphore_Post(Sema_ScanlineCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScanlineFinalPass<false>(gpu.GPU3D, 191, true, true);
|
|
||||||
Platform::Semaphore_Post(Sema_ScanlineCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RDLINES_COUNT_INCREMENT\
|
#define RDLINES_COUNT_INCREMENT\
|
||||||
/* feels wrong, needs improvement */\
|
/* feels wrong, needs improvement */\
|
||||||
while (RasterTiming >= RDDecrement[nextreadrd])\
|
while (RasterTiming >= RDDecrement[nextreadrd])\
|
||||||
|
@ -1943,8 +1908,8 @@ void SoftRenderer::RenderPolygonsFast(GPU& gpu, Polygon** polygons, int npolys)
|
||||||
ScanlineTimeout = SLRead[y-1] - (PreReadCutoff+FinalPassLen);\
|
ScanlineTimeout = SLRead[y-1] - (PreReadCutoff+FinalPassLen);\
|
||||||
\
|
\
|
||||||
FindFirstPolyDoTimings(j, y, &firstpolyeven, &firstpolyodd, &rastertimingeven, &rastertimingodd);\
|
FindFirstPolyDoTimings(j, y, &firstpolyeven, &firstpolyodd, &rastertimingeven, &rastertimingodd);\
|
||||||
RenderScanline<true>(gpu, y, firstpolyeven, j, &rastertimingeven);\
|
RenderScanline(gpu, y, firstpolyeven, j, &rastertimingeven);\
|
||||||
RenderScanline<true>(gpu, y+1, firstpolyodd, j, &rastertimingodd);\
|
RenderScanline(gpu, y+1, firstpolyodd, j, &rastertimingodd);\
|
||||||
\
|
\
|
||||||
prevtimespent = timespent;\
|
prevtimespent = timespent;\
|
||||||
RasterTiming += timespent = std::max(std::initializer_list<s32> {rastertimingeven, rastertimingodd, FinalPassLen});\
|
RasterTiming += timespent = std::max(std::initializer_list<s32> {rastertimingeven, rastertimingodd, FinalPassLen});\
|
||||||
|
@ -1975,8 +1940,8 @@ void SoftRenderer::RenderPolygonsTiming(GPU& gpu, Polygon** polygons, int npolys
|
||||||
|
|
||||||
FindFirstPolyDoTimings(j, 0, &firstpolyeven, &firstpolyodd, &rastertimingeven, &rastertimingodd);
|
FindFirstPolyDoTimings(j, 0, &firstpolyeven, &firstpolyodd, &rastertimingeven, &rastertimingodd);
|
||||||
// scanlines are rendered in pairs of two
|
// scanlines are rendered in pairs of two
|
||||||
RenderScanline<true>(gpu, 0, firstpolyeven, j, &rastertimingeven);
|
RenderScanline(gpu, 0, firstpolyeven, j, &rastertimingeven);
|
||||||
RenderScanline<true>(gpu, 1, firstpolyodd, j, &rastertimingodd);
|
RenderScanline(gpu, 1, firstpolyodd, j, &rastertimingodd);
|
||||||
|
|
||||||
// it can't proceed to the next scanline unless all others steps are done (both scanlines in the pair, and final pass)
|
// it can't proceed to the next scanline unless all others steps are done (both scanlines in the pair, and final pass)
|
||||||
RasterTiming = timespent = std::max(std::initializer_list<s32> {rastertimingeven, rastertimingodd, FinalPassLen});
|
RasterTiming = timespent = std::max(std::initializer_list<s32> {rastertimingeven, rastertimingodd, FinalPassLen});
|
||||||
|
@ -2067,13 +2032,9 @@ void SoftRenderer::RenderFrame(GPU& gpu)
|
||||||
|
|
||||||
if (gpu.GPU3D.RenderingEnabled >= 3)
|
if (gpu.GPU3D.RenderingEnabled >= 3)
|
||||||
{
|
{
|
||||||
if (Accuracy)
|
RenderPolygonsTiming(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
||||||
RenderPolygonsTiming(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
|
||||||
else
|
|
||||||
RenderPolygonsFast(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
|
||||||
}
|
}
|
||||||
else
|
else memcpy(FinalBuffer, ColorBuffer, sizeof(FinalBuffer));
|
||||||
if (Accuracy) memcpy(FinalBuffer, ColorBuffer, sizeof(FinalBuffer));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2109,14 +2070,11 @@ void SoftRenderer::RenderThreadFunc(GPU& gpu)
|
||||||
|
|
||||||
if (gpu.GPU3D.RenderingEnabled >= 3)
|
if (gpu.GPU3D.RenderingEnabled >= 3)
|
||||||
{
|
{
|
||||||
if (Accuracy)
|
RenderPolygonsTiming(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
||||||
RenderPolygonsTiming(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
|
||||||
else
|
|
||||||
RenderPolygonsFast(gpu, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Accuracy) memcpy(FinalBuffer, ColorBuffer, sizeof(FinalBuffer));
|
memcpy(FinalBuffer, ColorBuffer, sizeof(FinalBuffer));
|
||||||
Platform::Semaphore_Post(Sema_ScanlineCount, 192);
|
Platform::Semaphore_Post(Sema_ScanlineCount, 192);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2131,7 +2089,7 @@ void SoftRenderer::RenderThreadFunc(GPU& gpu)
|
||||||
void SoftRenderer::ScanlineSync(int line)
|
void SoftRenderer::ScanlineSync(int line)
|
||||||
{
|
{
|
||||||
// only used in accurate mode (timings must be emulated)
|
// only used in accurate mode (timings must be emulated)
|
||||||
if (Accuracy && RenderThreadRunning.load(std::memory_order_relaxed))
|
if (RenderThreadRunning.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
if (line < 192)
|
if (line < 192)
|
||||||
{
|
{
|
||||||
|
@ -2144,20 +2102,7 @@ void SoftRenderer::ScanlineSync(int line)
|
||||||
|
|
||||||
u32* SoftRenderer::GetLine(int line)
|
u32* SoftRenderer::GetLine(int line)
|
||||||
{
|
{
|
||||||
// only wait in in-accurate mode (we've already waited for scanlines in accurate mode)
|
return &FinalBuffer[line*ScanlineWidth];
|
||||||
if (!Accuracy)
|
|
||||||
{
|
|
||||||
if (RenderThreadRunning.load(std::memory_order_relaxed))
|
|
||||||
{
|
|
||||||
if (line < 192)
|
|
||||||
// We need a scanline, so let's wait for the render thread to finish it.
|
|
||||||
// (both threads process scanlines from top-to-bottom,
|
|
||||||
// so we don't need to wait for a specific row)
|
|
||||||
Platform::Semaphore_Wait(Sema_ScanlineCount);
|
|
||||||
}
|
|
||||||
return &ColorBuffer[line*ScanlineWidth];
|
|
||||||
}
|
|
||||||
else return &FinalBuffer[line*ScanlineWidth];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,9 +468,9 @@ private:
|
||||||
void SetupPolygon(RendererPolygon* rp, Polygon* polygon) const;
|
void SetupPolygon(RendererPolygon* rp, Polygon* polygon) const;
|
||||||
void Step(RendererPolygon* rp);
|
void Step(RendererPolygon* rp);
|
||||||
void CheckSlope(RendererPolygon* rp, s32 y);
|
void CheckSlope(RendererPolygon* rp, s32 y);
|
||||||
template <bool accuracy> bool RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y, s32* timingcounter);
|
bool RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y, s32* timingcounter);
|
||||||
template <bool accuracy> bool RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y, s32* timingcounter);
|
bool RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y, s32* timingcounter);
|
||||||
template <bool accuracy> void RenderScanline(const GPU& gpu, s32 y, int firstpoly, int npolys, s32* timingcounter);
|
void RenderScanline(const GPU& gpu, s32 y, int firstpoly, int npolys, s32* timingcounter);
|
||||||
u32 CalculateFogDensity(const GPU3D& gpu3d, u32 pixeladdr) const;
|
u32 CalculateFogDensity(const GPU3D& gpu3d, u32 pixeladdr) const;
|
||||||
bool CheckEdgeMarkingPixel(u32 polyid, u32 z, u32 pixeladdr);
|
bool CheckEdgeMarkingPixel(u32 polyid, u32 z, u32 pixeladdr);
|
||||||
bool CheckEdgeMarkingClearPlane(const GPU3D& gpu3d, u32 polyid, u32 z);
|
bool CheckEdgeMarkingClearPlane(const GPU3D& gpu3d, u32 polyid, u32 z);
|
||||||
|
@ -521,8 +521,6 @@ private:
|
||||||
|
|
||||||
bool FrameIdentical;
|
bool FrameIdentical;
|
||||||
|
|
||||||
bool Accuracy = true; // TODO
|
|
||||||
|
|
||||||
// threading
|
// threading
|
||||||
|
|
||||||
bool Threaded;
|
bool Threaded;
|
||||||
|
|
Loading…
Reference in New Issue