mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
tentative timings for "empty" polys scanlines, fix swapped polys breaking
This commit is contained in:
parent
92ca04e479
commit
c45d3320d0
@ -781,16 +781,16 @@ bool GPU3D::DoTimings(s32 cycles, bool odd)
|
|||||||
if (odd)
|
if (odd)
|
||||||
{
|
{
|
||||||
RasterTimingCounterOdd += cycles;
|
RasterTimingCounterOdd += cycles;
|
||||||
if ((RasterTimingCounterOdd + RasterTimingCounterPrev) < RasterTimingCap) return 0;
|
if ((RasterTimingCounterOdd + RasterTimingCounterPrev) < RasterTimingCap) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RasterTimingCounterEven += cycles;
|
RasterTimingCounterEven += cycles;
|
||||||
if ((RasterTimingCounterEven + RasterTimingCounterPrev) < RasterTimingCap) return 0;
|
if ((RasterTimingCounterEven + RasterTimingCounterPrev) < RasterTimingCap) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DispCnt |= (1<<12);
|
DispCnt |= (1<<12);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU3D::EndScanline(bool odd)
|
void GPU3D::EndScanline(bool odd)
|
||||||
@ -805,7 +805,7 @@ void GPU3D::EndScanline(bool odd)
|
|||||||
// seems to display the lowest scanline buffer count reached during the current frame.
|
// seems to display the lowest scanline buffer count reached during the current frame.
|
||||||
// we also caps it to 46 here, because this reg does that too for some reason.
|
// we also caps it to 46 here, because this reg does that too for some reason.
|
||||||
if (RDLines > RDLinesMin) RDLines = RDLinesMin;
|
if (RDLines > RDLinesMin) RDLines = RDLinesMin;
|
||||||
if (RDLines < RDLinesMin) RDLinesMin = RDLines;
|
else if (RDLines < RDLinesMin) RDLinesMin = RDLines;
|
||||||
RasterTimingCounterOdd = 0;
|
RasterTimingCounterOdd = 0;
|
||||||
RasterTimingCounterEven = 0;
|
RasterTimingCounterEven = 0;
|
||||||
}
|
}
|
||||||
|
19
src/GPU3D.h
19
src/GPU3D.h
@ -30,14 +30,6 @@ namespace melonDS
|
|||||||
{
|
{
|
||||||
class GPU;
|
class GPU;
|
||||||
|
|
||||||
// numbers based on 339 poly 64-172 horiz. line poly
|
|
||||||
static constexpr int RasterTimingCap = 51116;
|
|
||||||
static constexpr int PerPolyTiming = 12; // should be correct for *most* line polygons
|
|
||||||
static constexpr int PerPixelTiming = 1; // does not apply to the first 4 pixels in a polygon (per scanline?)
|
|
||||||
static constexpr int PerScanlineTiming = 1064;// approximate currently, used to calc RDLines
|
|
||||||
static constexpr int PerScanlineRecup = 2112; // seems to check out?
|
|
||||||
//static constexpr int EmptyPolyScanline;
|
|
||||||
//static constexpr int FirstPixelTiming;
|
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
@ -345,6 +337,17 @@ public:
|
|||||||
u32 ScrolledLine[256];
|
u32 ScrolledLine[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// numbers based on 339 poly 64-172 horiz. line poly
|
||||||
|
static constexpr int Frac = 481; // add a fractional component if pixels is not enough precision
|
||||||
|
static constexpr int RasterTimingCap = 51116*Frac;
|
||||||
|
static constexpr int PerScanlineTiming = 1064*Frac; // approximate currently, used to calc RDLines. TEMPORARY UNTIL ACCURATE "FRAMEBUFFER" CAN BE IMPLEMENTED
|
||||||
|
static constexpr int PerScanlineRecup = 2112*Frac; // seems to check out?
|
||||||
|
|
||||||
|
static constexpr int PerPolyTiming = 12*Frac; // should be correct for *most* line polygons and polygons with vertical slopes
|
||||||
|
static constexpr int PerPixelTiming = 1*Frac; // does not apply to the first 4 pixels in a polygon (per scanline?)
|
||||||
|
static constexpr int EmptyPolyScanline = 4*Frac - 14; // seems to be slightly under 4?
|
||||||
|
//static constexpr int FirstPixelTiming;
|
||||||
|
|
||||||
class Renderer3D
|
class Renderer3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -672,6 +672,31 @@ void SoftRenderer::SetupPolygon(SoftRenderer::RendererPolygon* rp, Polygon* poly
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoftRenderer::Step(RendererPolygon* rp, bool abortscanline)
|
||||||
|
{
|
||||||
|
rp->XL = rp->SlopeL.Step();
|
||||||
|
rp->XR = rp->SlopeR.Step();
|
||||||
|
return abortscanline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftRenderer::CheckSlope(RendererPolygon* rp, s32 y)
|
||||||
|
{
|
||||||
|
Polygon* polygon = rp->PolyData;
|
||||||
|
|
||||||
|
if (polygon->YTop != polygon->YBottom)
|
||||||
|
{
|
||||||
|
if (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom)
|
||||||
|
{
|
||||||
|
SetupPolygonLeftEdge(rp, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom)
|
||||||
|
{
|
||||||
|
SetupPolygonRightEdge(rp, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
|
void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
|
||||||
{
|
{
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
@ -900,10 +925,8 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
|
|||||||
rp->XR = rp->SlopeR.Step();
|
rp->XR = rp->SlopeR.Step();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||||
{
|
{
|
||||||
if (GPU.GPU3D.DoTimings(PerPolyTiming, odd)) return;
|
|
||||||
int pixelsrendered = 0;
|
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
u32 polyattr = (polygon->Attr & 0x3F008000);
|
u32 polyattr = (polygon->Attr & 0x3F008000);
|
||||||
if (!polygon->FacingView) polyattr |= (1<<4);
|
if (!polygon->FacingView) polyattr |= (1<<4);
|
||||||
@ -921,18 +944,9 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
|
|
||||||
PrevIsShadowMask = false;
|
PrevIsShadowMask = false;
|
||||||
|
|
||||||
if (polygon->YTop != polygon->YBottom)
|
CheckSlope(rp, y);
|
||||||
{
|
|
||||||
if (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom)
|
|
||||||
{
|
|
||||||
SetupPolygonLeftEdge(rp, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom)
|
if (GPU.GPU3D.DoTimings(PerPolyTiming, odd)) return Step(rp, true);
|
||||||
{
|
|
||||||
SetupPolygonRightEdge(rp, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex *vlcur, *vlnext, *vrcur, *vrnext;
|
Vertex *vlcur, *vlnext, *vrcur, *vrnext;
|
||||||
s32 xstart, xend;
|
s32 xstart, xend;
|
||||||
@ -941,6 +955,7 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
s32 l_edgecov, r_edgecov;
|
s32 l_edgecov, r_edgecov;
|
||||||
Interpolator<1>* interp_start;
|
Interpolator<1>* interp_start;
|
||||||
Interpolator<1>* interp_end;
|
Interpolator<1>* interp_end;
|
||||||
|
u8 pixelsrendered = 0; // for tracking timings
|
||||||
|
|
||||||
xstart = rp->XL;
|
xstart = rp->XL;
|
||||||
xend = rp->XR;
|
xend = rp->XR;
|
||||||
@ -1077,10 +1092,11 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
if (xcov == 0x3FF) xcov = 0;
|
if (xcov == 0x3FF) xcov = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (; x < xlimit; x++)
|
for (; x < xlimit; x++)
|
||||||
{
|
{
|
||||||
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return;
|
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return Step(rp, true);
|
||||||
pixelsrendered++;
|
else pixelsrendered++;
|
||||||
if (!l_filledge) continue;
|
if (!l_filledge) continue;
|
||||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 dstattr = AttrBuffer[pixeladdr];
|
u32 dstattr = AttrBuffer[pixeladdr];
|
||||||
@ -1176,8 +1192,8 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
|
|
||||||
for (; x < xlimit; x++)
|
for (; x < xlimit; x++)
|
||||||
{
|
{
|
||||||
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return;
|
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return Step(rp, true);
|
||||||
pixelsrendered++;
|
else pixelsrendered++;
|
||||||
if (wireframe && !edge) continue;
|
if (wireframe && !edge) continue;
|
||||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 dstattr = AttrBuffer[pixeladdr];
|
u32 dstattr = AttrBuffer[pixeladdr];
|
||||||
@ -1270,8 +1286,8 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
|
|
||||||
for (; x < xlimit; x++)
|
for (; x < xlimit; x++)
|
||||||
{
|
{
|
||||||
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return;
|
if (pixelsrendered >= 4 && GPU.GPU3D.DoTimings(PerPixelTiming, odd)) return Step(rp, true);
|
||||||
pixelsrendered++;
|
else pixelsrendered++;
|
||||||
if (!r_filledge) continue;
|
if (!r_filledge) continue;
|
||||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 dstattr = AttrBuffer[pixeladdr];
|
u32 dstattr = AttrBuffer[pixeladdr];
|
||||||
@ -1358,27 +1374,33 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
|||||||
PlotTranslucentPixel(pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
PlotTranslucentPixel(pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Step(rp, false);
|
||||||
rp->XL = rp->SlopeL.Step();
|
|
||||||
rp->XR = rp->SlopeR.Step();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftRenderer::RenderScanline(s32 y, int npolys)
|
void SoftRenderer::RenderScanline(s32 y, int npolys)
|
||||||
{
|
{
|
||||||
bool odd = !(y % 2);
|
bool odd = !(y % 2);
|
||||||
|
bool abort = false;
|
||||||
for (int i = 0; i < npolys; i++)
|
for (int i = 0; i < npolys; i++)
|
||||||
{
|
{
|
||||||
if (GPU.GPU3D.DoTimings(0, odd)) break;
|
|
||||||
|
|
||||||
RendererPolygon* rp = &PolygonList[i];
|
RendererPolygon* rp = &PolygonList[i];
|
||||||
Polygon* polygon = rp->PolyData;
|
Polygon* polygon = rp->PolyData;
|
||||||
|
|
||||||
if (y >= polygon->YTop && (y < polygon->YBottom || (y == polygon->YTop && polygon->YBottom == polygon->YTop)))
|
if (abort)
|
||||||
|
{
|
||||||
|
CheckSlope(rp, y);
|
||||||
|
Step(rp, NULL);
|
||||||
|
}
|
||||||
|
else if (y == polygon->YBottom && y != polygon->YTop)
|
||||||
|
{
|
||||||
|
if (GPU.GPU3D.DoTimings(EmptyPolyScanline, odd)) abort = true;
|
||||||
|
}
|
||||||
|
else if (y >= polygon->YTop && (y < polygon->YBottom || (y == polygon->YTop && polygon->YBottom == polygon->YTop)))
|
||||||
{
|
{
|
||||||
if (polygon->IsShadowMask)
|
if (polygon->IsShadowMask)
|
||||||
RenderShadowMaskScanline(rp, y);
|
RenderShadowMaskScanline(rp, y);
|
||||||
else
|
else
|
||||||
RenderPolygonScanline(rp, y, odd);
|
if (RenderPolygonScanline(rp, y, odd)) abort = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GPU.GPU3D.EndScanline(odd);
|
GPU.GPU3D.EndScanline(odd);
|
||||||
|
@ -460,8 +460,10 @@ private:
|
|||||||
void SetupPolygonLeftEdge(RendererPolygon* rp, s32 y);
|
void SetupPolygonLeftEdge(RendererPolygon* rp, s32 y);
|
||||||
void SetupPolygonRightEdge(RendererPolygon* rp, s32 y);
|
void SetupPolygonRightEdge(RendererPolygon* rp, s32 y);
|
||||||
void SetupPolygon(RendererPolygon* rp, Polygon* polygon);
|
void SetupPolygon(RendererPolygon* rp, Polygon* polygon);
|
||||||
|
bool Step(RendererPolygon* rp, bool abortscanline);
|
||||||
|
void CheckSlope(RendererPolygon* rp, s32 y);
|
||||||
void RenderShadowMaskScanline(RendererPolygon* rp, s32 y);
|
void RenderShadowMaskScanline(RendererPolygon* rp, s32 y);
|
||||||
void RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd);
|
bool RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd);
|
||||||
void RenderScanline(s32 y, int npolys);
|
void RenderScanline(s32 y, int npolys);
|
||||||
u32 CalculateFogDensity(u32 pixeladdr);
|
u32 CalculateFogDensity(u32 pixeladdr);
|
||||||
void ScanlineFinalPass(s32 y);
|
void ScanlineFinalPass(s32 y);
|
||||||
|
Loading…
Reference in New Issue
Block a user