improve edge marking bug accuracy

also begin groundwork for rdlines_count register emulation
This commit is contained in:
Jaklyy 2024-02-25 16:45:22 -05:00
parent f2cf447fc1
commit 9219a084c4
3 changed files with 51 additions and 12 deletions

View File

@ -241,7 +241,8 @@ void GPU3D::Reset() noexcept
AlphaRefVal = 0;
AlphaRef = 0;
RDLines = 46;
RDLines = 63; // defaults to 63 for one frame? (CHECKME: when does it reset?)
RDLinesTemp = 46;
memset(ToonTable, 0, sizeof(ToonTable));
memset(EdgeTable, 0, sizeof(EdgeTable));
@ -2401,7 +2402,6 @@ void GPU3D::CheckFIFODMA() noexcept
void GPU3D::VCount144(GPU& gpu) noexcept
{
RDLines = 46;
CurrentRenderer->VCount144(gpu);
}
@ -2431,6 +2431,7 @@ bool YSort(Polygon* a, Polygon* b)
void GPU3D::VBlank() noexcept
{
RDLines = RDLinesTemp;
if (GeometryEnabled)
{
if (RenderingEnabled)
@ -2508,6 +2509,7 @@ void GPU3D::VBlank() noexcept
void GPU3D::VCount215(GPU& gpu) noexcept
{
//RDLinesTemp = 46;
CurrentRenderer->RenderFrame(gpu);
}
@ -2645,7 +2647,7 @@ u16 GPU3D::Read16(u32 addr) noexcept
return DispCnt;
case 0x04000320:
return RDLines; // IT IS TIME
return RDLines; // CHECKME: Can this always be read? Even when the gpu is powered off?
case 0x04000600:
{
@ -2689,7 +2691,7 @@ u32 GPU3D::Read32(u32 addr) noexcept
return DispCnt;
case 0x04000320:
return RDLines; // IT IS TIME
return RDLines;
case 0x04000600:
{

View File

@ -246,7 +246,8 @@ public:
bool RenderingEnabled = false;
u32 DispCnt = 0;
u32 RDLines = 0;
u8 RDLines = 63;
u8 RDLinesTemp = 46;
u8 AlphaRefVal = 0;
u8 AlphaRef = 0;

View File

@ -1876,13 +1876,17 @@ void SoftRenderer::RenderPolygons(GPU& gpu, Polygon** polygons, int npolys)
RenderScanline(gpu, 0, j, &rastertimingeven);
RenderScanline(gpu, 1, j, &rastertimingodd);
// 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});
// 12 cycles at the end of a "timeout" are always used for w/e reason
RasterTiming += std::clamp(ScanlineTimeout - RasterTiming, 0, 12);
gpu.GPU3D.RDLinesTemp = 46;
// if first pair was not delayed past the first read, then later scanlines cannot either
// this allows us to implement a fast path
//if (slread[0] - timespent + ScanlinePushDelay >= 256)
{
// begin scanline timeout
ScanlineTimeout = slread[1] - FinalPassLen;
RenderScanline(gpu, 2, j, &rastertimingeven);
@ -1892,8 +1896,20 @@ void SoftRenderer::RenderPolygons(GPU& gpu, Polygon** polygons, int npolys)
RasterTiming += timespent = std::max(std::initializer_list<s32> {rastertimingeven, rastertimingodd, FinalPassLen});
RasterTiming += std::clamp(ScanlineTimeout - RasterTiming, 0, 12);
ScanlineFinalPass<true>(gpu.GPU3D, 0, true, true);
scanlineswaiting++;
while (RasterTiming >= slread[nextread] + 565)
{
if (RasterTiming < slread[nextread] + 565)
{
RasterTiming += timespent = (slread[nextread] + 565) - RasterTiming; // why + 565?
timespent += 571; // fixes edge marking bug emulation. not sure why this is needed?
}
scanlineswaiting--;
nextread++;
}
ScanlineFinalPass<true>(gpu.GPU3D, 0, true, timespent >= 502);
for (int y = 4; y < 192; y+=2)
{
ScanlineTimeout = slread[y-1] - FinalPassLen;
@ -1907,9 +1923,13 @@ void SoftRenderer::RenderPolygons(GPU& gpu, Polygon** polygons, int npolys)
scanlineswaiting+=2;
while (scanlineswaiting >= 47)
while (scanlineswaiting >= 47 || RasterTiming >= slread[nextread] + 565)
{
if (RasterTiming < slread[nextread]) RasterTiming += timespent = (slread[nextread] + 565) - RasterTiming; // why + 565?
if (RasterTiming < slread[nextread] + 565)
{
RasterTiming += timespent = (slread[nextread] + 565) - RasterTiming; // why + 565?
timespent += 571; // fixes edge marking bug emulation. not sure why this is needed?
}
scanlineswaiting--;
nextread++;
}
@ -1917,11 +1937,27 @@ void SoftRenderer::RenderPolygons(GPU& gpu, Polygon** polygons, int npolys)
ScanlineFinalPass<true>(gpu.GPU3D, y-3, prevtimespent >= 502 || y-3 == 1, timespent >= 502);
ScanlineFinalPass<true>(gpu.GPU3D, y-2, prevtimespent >= 502, timespent >= 502);
}
scanlineswaiting+= 2;
prevtimespent = timespent;
ScanlineFinalPass<true>(gpu.GPU3D, 189, timespent >= 502, timespent >= 502);
ScanlineFinalPass<true>(gpu.GPU3D, 190, timespent >= 502, true);
// do this one last time to allow for edge marking bug emulation.
while (scanlineswaiting >= 47 || RasterTiming >= slread[nextread] + 565)
{
if (RasterTiming < slread[nextread] + 565)
{
RasterTiming += timespent = (slread[nextread] + 565) - RasterTiming; // why + 565?
timespent += 571; // fixes edge marking bug emulation. not sure why this is needed?
}
scanlineswaiting--;
nextread++;
}
ScanlineFinalPass<true>(gpu.GPU3D, 189, prevtimespent >= 502, timespent >= 502);
ScanlineFinalPass<true>(gpu.GPU3D, 190, prevtimespent >= 502, true);
// skip timing emulation here since it's irrelevant, also use timespent instead of prev because we're skipping timing emulation
ScanlineFinalPass<true>(gpu.GPU3D, 191, timespent >= 502, true);
ScanlineFinalPass<true>(gpu.GPU3D, 191, true, true);
}
/*else
{