mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-28 16:50:15 -06:00
Merge branch 'master' of https://github.com/melonDS-emu/melonDS into RDLines
This commit is contained in:
@ -42,14 +42,16 @@ void SoftRenderer::StopRenderThread()
|
||||
}
|
||||
}
|
||||
|
||||
void SoftRenderer::SetupRenderThread()
|
||||
void SoftRenderer::SetupRenderThread(GPU& gpu)
|
||||
{
|
||||
if (Threaded)
|
||||
{
|
||||
if (!RenderThreadRunning.load(std::memory_order_relaxed))
|
||||
{
|
||||
RenderThreadRunning = true;
|
||||
RenderThread = Platform::Thread_Create(std::bind(&SoftRenderer::RenderThreadFunc, this));
|
||||
RenderThread = Platform::Thread_Create([this, &gpu]() {
|
||||
RenderThreadFunc(gpu);
|
||||
});
|
||||
}
|
||||
|
||||
// otherwise more than one frame can be queued up at once
|
||||
@ -71,8 +73,8 @@ void SoftRenderer::SetupRenderThread()
|
||||
}
|
||||
|
||||
|
||||
SoftRenderer::SoftRenderer(melonDS::GPU& gpu, bool threaded) noexcept
|
||||
: Renderer3D(false), GPU(gpu), Threaded(threaded)
|
||||
SoftRenderer::SoftRenderer(bool threaded) noexcept
|
||||
: Renderer3D(false), Threaded(threaded)
|
||||
{
|
||||
Sema_RenderStart = Platform::Semaphore_Create();
|
||||
Sema_RenderDone = Platform::Semaphore_Create();
|
||||
@ -92,7 +94,7 @@ SoftRenderer::~SoftRenderer()
|
||||
Platform::Semaphore_Free(Sema_ScanlineCount);
|
||||
}
|
||||
|
||||
void SoftRenderer::Reset()
|
||||
void SoftRenderer::Reset(GPU& gpu)
|
||||
{
|
||||
memset(ColorBuffer, 0, BufferSize * 2 * 4);
|
||||
memset(DepthBuffer, 0, BufferSize * 2 * 4);
|
||||
@ -100,15 +102,15 @@ void SoftRenderer::Reset()
|
||||
|
||||
PrevIsShadowMask = false;
|
||||
|
||||
SetupRenderThread();
|
||||
SetupRenderThread(gpu);
|
||||
}
|
||||
|
||||
void SoftRenderer::SetThreaded(bool threaded) noexcept
|
||||
void SoftRenderer::SetThreaded(bool threaded, GPU& gpu) noexcept
|
||||
{
|
||||
if (Threaded != threaded)
|
||||
{
|
||||
Threaded = threaded;
|
||||
SetupRenderThread();
|
||||
SetupRenderThread(gpu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,10 +249,10 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 1: // A3I5
|
||||
{
|
||||
vramaddr += ((t * width) + s);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
|
||||
texpal <<= 4;
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + ((pixel&0x1F)<<1));
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + ((pixel&0x1F)<<1), gpu);
|
||||
*alpha = ((pixel >> 3) & 0x1C) + (pixel >> 6);
|
||||
}
|
||||
break;
|
||||
@ -258,12 +260,12 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 2: // 4-color
|
||||
{
|
||||
vramaddr += (((t * width) + s) >> 2);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
pixel >>= ((s & 0x3) << 1);
|
||||
pixel &= 0x3;
|
||||
|
||||
texpal <<= 3;
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1));
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1), gpu);
|
||||
*alpha = (pixel==0) ? alpha0 : 31;
|
||||
}
|
||||
break;
|
||||
@ -271,12 +273,12 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 3: // 16-color
|
||||
{
|
||||
vramaddr += (((t * width) + s) >> 1);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
if (s & 0x1) pixel >>= 4;
|
||||
else pixel &= 0xF;
|
||||
|
||||
texpal <<= 4;
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1));
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1), gpu);
|
||||
*alpha = (pixel==0) ? alpha0 : 31;
|
||||
}
|
||||
break;
|
||||
@ -284,10 +286,10 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 4: // 256-color
|
||||
{
|
||||
vramaddr += ((t * width) + s);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
|
||||
texpal <<= 4;
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1));
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + (pixel<<1), gpu);
|
||||
*alpha = (pixel==0) ? alpha0 : 31;
|
||||
}
|
||||
break;
|
||||
@ -301,30 +303,30 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
if (vramaddr >= 0x40000)
|
||||
slot1addr += 0x10000;
|
||||
|
||||
u8 val = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 val = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
val >>= (2 * (s & 0x3));
|
||||
|
||||
u16 palinfo = ReadVRAM_Texture<u16>(slot1addr);
|
||||
u16 palinfo = ReadVRAM_Texture<u16>(slot1addr, gpu);
|
||||
u32 paloffset = (palinfo & 0x3FFF) << 2;
|
||||
texpal <<= 4;
|
||||
|
||||
switch (val & 0x3)
|
||||
{
|
||||
case 0:
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset);
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset, gpu);
|
||||
*alpha = 31;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 2);
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 2, gpu);
|
||||
*alpha = 31;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ((palinfo >> 14) == 1)
|
||||
{
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2);
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset, gpu);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2, gpu);
|
||||
|
||||
u32 r0 = color0 & 0x001F;
|
||||
u32 g0 = color0 & 0x03E0;
|
||||
@ -341,8 +343,8 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
}
|
||||
else if ((palinfo >> 14) == 3)
|
||||
{
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2);
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset, gpu);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2, gpu);
|
||||
|
||||
u32 r0 = color0 & 0x001F;
|
||||
u32 g0 = color0 & 0x03E0;
|
||||
@ -358,20 +360,20 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
*color = r | g | b;
|
||||
}
|
||||
else
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 4);
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 4, gpu);
|
||||
*alpha = 31;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ((palinfo >> 14) == 2)
|
||||
{
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 6);
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + paloffset + 6, gpu);
|
||||
*alpha = 31;
|
||||
}
|
||||
else if ((palinfo >> 14) == 3)
|
||||
{
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2);
|
||||
u16 color0 = ReadVRAM_TexPal<u16>(texpal + paloffset, gpu);
|
||||
u16 color1 = ReadVRAM_TexPal<u16>(texpal + paloffset + 2, gpu);
|
||||
|
||||
u32 r0 = color0 & 0x001F;
|
||||
u32 g0 = color0 & 0x03E0;
|
||||
@ -400,10 +402,10 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 6: // A5I3
|
||||
{
|
||||
vramaddr += ((t * width) + s);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr);
|
||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||
|
||||
texpal <<= 4;
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + ((pixel&0x7)<<1));
|
||||
*color = ReadVRAM_TexPal<u16>(texpal + ((pixel&0x7)<<1), gpu);
|
||||
*alpha = (pixel >> 3);
|
||||
}
|
||||
break;
|
||||
@ -411,7 +413,7 @@ void SoftRenderer::TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* co
|
||||
case 7: // direct color
|
||||
{
|
||||
vramaddr += (((t * width) + s) << 1);
|
||||
*color = ReadVRAM_Texture<u16>(vramaddr);
|
||||
*color = ReadVRAM_Texture<u16>(vramaddr, gpu);
|
||||
*alpha = (*color & 0x8000) ? 31 : 0;
|
||||
}
|
||||
break;
|
||||
@ -468,7 +470,7 @@ bool DepthTest_LessThan_FrontFacing(s32 dstz, s32 z, u32 dstattr)
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 SoftRenderer::AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha) noexcept
|
||||
u32 SoftRenderer::AlphaBlend(const GPU3D& gpu3d, u32 srccolor, u32 dstcolor, u32 alpha) const noexcept
|
||||
{
|
||||
u32 dstalpha = dstcolor >> 24;
|
||||
|
||||
@ -479,7 +481,7 @@ u32 SoftRenderer::AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha) noexcept
|
||||
u32 srcG = (srccolor >> 8) & 0x3F;
|
||||
u32 srcB = (srccolor >> 16) & 0x3F;
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<3))
|
||||
if (gpu3d.RenderDispCnt & (1<<3))
|
||||
{
|
||||
u32 dstR = dstcolor & 0x3F;
|
||||
u32 dstG = (dstcolor >> 8) & 0x3F;
|
||||
@ -498,7 +500,7 @@ u32 SoftRenderer::AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha) noexcept
|
||||
return srcR | (srcG << 8) | (srcB << 16) | (dstalpha << 24);
|
||||
}
|
||||
|
||||
u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t)
|
||||
u32 SoftRenderer::RenderPixel(const GPU& gpu, const Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t) const
|
||||
{
|
||||
u8 r, g, b, a;
|
||||
|
||||
@ -508,7 +510,7 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
|
||||
|
||||
if (blendmode == 2)
|
||||
{
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<1))
|
||||
if (gpu.GPU3D.RenderDispCnt & (1<<1))
|
||||
{
|
||||
// highlight mode: color is calculated normally
|
||||
// except all vertex color components are set
|
||||
@ -522,7 +524,7 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
|
||||
{
|
||||
// toon mode: vertex color is replaced by toon color
|
||||
|
||||
u16 tooncolor = GPU.GPU3D.RenderToonTable[vr >> 1];
|
||||
u16 tooncolor = gpu.GPU3D.RenderToonTable[vr >> 1];
|
||||
|
||||
vr = (tooncolor << 1) & 0x3E; if (vr) vr++;
|
||||
vg = (tooncolor >> 4) & 0x3E; if (vg) vg++;
|
||||
@ -530,12 +532,12 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
|
||||
}
|
||||
}
|
||||
|
||||
if ((GPU.GPU3D.RenderDispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0))
|
||||
if ((gpu.GPU3D.RenderDispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0))
|
||||
{
|
||||
u8 tr, tg, tb;
|
||||
|
||||
u16 tcolor; u8 talpha;
|
||||
TextureLookup(polygon->TexParam, polygon->TexPalette, s, t, &tcolor, &talpha);
|
||||
TextureLookup(gpu, polygon->TexParam, polygon->TexPalette, s, t, &tcolor, &talpha);
|
||||
|
||||
tr = (tcolor << 1) & 0x3E; if (tr) tr++;
|
||||
tg = (tcolor >> 4) & 0x3E; if (tg) tg++;
|
||||
@ -583,9 +585,9 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
|
||||
a = polyalpha;
|
||||
}
|
||||
|
||||
if ((blendmode == 2) && (GPU.GPU3D.RenderDispCnt & (1<<1)))
|
||||
if ((blendmode == 2) && (gpu.GPU3D.RenderDispCnt & (1<<1)))
|
||||
{
|
||||
u16 tooncolor = GPU.GPU3D.RenderToonTable[vr >> 1];
|
||||
u16 tooncolor = gpu.GPU3D.RenderToonTable[vr >> 1];
|
||||
|
||||
vr = (tooncolor << 1) & 0x3E; if (vr) vr++;
|
||||
vg = (tooncolor >> 4) & 0x3E; if (vg) vg++;
|
||||
@ -606,7 +608,7 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
|
||||
return r | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
void SoftRenderer::PlotTranslucentPixel(u32 pixeladdr, u32 color, u32 z, u32 polyattr, u32 shadow)
|
||||
void SoftRenderer::PlotTranslucentPixel(const GPU3D& gpu3d, u32 pixeladdr, u32 color, u32 z, u32 polyattr, u32 shadow)
|
||||
{
|
||||
u32 dstattr = AttrBuffer[pixeladdr];
|
||||
u32 attr = (polyattr & 0xE0F0) | ((polyattr >> 8) & 0xFF0000) | (1<<22) | (dstattr & 0xFF001F0F);
|
||||
@ -636,7 +638,7 @@ void SoftRenderer::PlotTranslucentPixel(u32 pixeladdr, u32 color, u32 z, u32 pol
|
||||
if (!(dstattr & (1<<15)))
|
||||
attr &= ~(1<<15);
|
||||
|
||||
color = AlphaBlend(color, ColorBuffer[pixeladdr], color>>24);
|
||||
color = AlphaBlend(gpu3d, color, ColorBuffer[pixeladdr], color>>24);
|
||||
|
||||
if (z != -1)
|
||||
DepthBuffer[pixeladdr] = z;
|
||||
@ -645,7 +647,7 @@ void SoftRenderer::PlotTranslucentPixel(u32 pixeladdr, u32 color, u32 z, u32 pol
|
||||
AttrBuffer[pixeladdr] = attr;
|
||||
}
|
||||
|
||||
void SoftRenderer::SetupPolygonLeftEdge(SoftRenderer::RendererPolygon* rp, s32 y)
|
||||
void SoftRenderer::SetupPolygonLeftEdge(SoftRenderer::RendererPolygon* rp, s32 y) const
|
||||
{
|
||||
Polygon* polygon = rp->PolyData;
|
||||
|
||||
@ -672,7 +674,7 @@ void SoftRenderer::SetupPolygonLeftEdge(SoftRenderer::RendererPolygon* rp, s32 y
|
||||
polygon->FinalW[rp->CurVL], polygon->FinalW[rp->NextVL], y);
|
||||
}
|
||||
|
||||
void SoftRenderer::SetupPolygonRightEdge(SoftRenderer::RendererPolygon* rp, s32 y)
|
||||
void SoftRenderer::SetupPolygonRightEdge(SoftRenderer::RendererPolygon* rp, s32 y) const
|
||||
{
|
||||
Polygon* polygon = rp->PolyData;
|
||||
|
||||
@ -699,7 +701,7 @@ void SoftRenderer::SetupPolygonRightEdge(SoftRenderer::RendererPolygon* rp, s32
|
||||
polygon->FinalW[rp->CurVR], polygon->FinalW[rp->NextVR], y);
|
||||
}
|
||||
|
||||
void SoftRenderer::SetupPolygon(SoftRenderer::RendererPolygon* rp, Polygon* polygon)
|
||||
void SoftRenderer::SetupPolygon(SoftRenderer::RendererPolygon* rp, Polygon* polygon) const
|
||||
{
|
||||
u32 nverts = polygon->NumVertices;
|
||||
|
||||
@ -776,7 +778,7 @@ void SoftRenderer::CheckSlope(RendererPolygon* rp, s32 y)
|
||||
}
|
||||
}
|
||||
|
||||
bool SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
bool SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y, bool odd)
|
||||
{
|
||||
Polygon* polygon = rp->PolyData;
|
||||
|
||||
@ -843,7 +845,7 @@ bool SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y, bool odd
|
||||
std::swap(zl, zr);
|
||||
|
||||
// CHECKME: edge fill rules for swapped opaque shadow mask polygons
|
||||
if ((GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (GPU.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe)
|
||||
{
|
||||
l_filledge = true;
|
||||
r_filledge = true;
|
||||
@ -871,7 +873,7 @@ bool SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y, bool odd
|
||||
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov);
|
||||
|
||||
// CHECKME: edge fill rules for unswapped opaque shadow mask polygons
|
||||
if ((GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (GPU.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe)
|
||||
{
|
||||
l_filledge = true;
|
||||
r_filledge = true;
|
||||
@ -892,7 +894,7 @@ bool SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y, bool odd
|
||||
// similarly, we can perform alpha test early (checkme)
|
||||
|
||||
if (wireframe) polyalpha = 31;
|
||||
if (polyalpha <= GPU.GPU3D.RenderAlphaRef) return false; // TODO: check how this impacts timings?
|
||||
if (polyalpha <= gpu3d.RenderAlphaRef) return false; // TODO: check how this impacts timings?
|
||||
|
||||
// in wireframe mode, there are special rules for equal Z (TODO)
|
||||
|
||||
@ -1004,7 +1006,7 @@ bool SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y, bool odd
|
||||
return abortscanline;
|
||||
}
|
||||
|
||||
bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
bool SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y, bool odd)
|
||||
{
|
||||
Polygon* polygon = rp->PolyData;
|
||||
u32 polyattr = (polygon->Attr & 0x3F008000);
|
||||
@ -1077,7 +1079,7 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
// edges are always filled if antialiasing/edgemarking are enabled,
|
||||
// if the pixels are translucent and alpha blending is enabled, or if the polygon is wireframe
|
||||
// checkme: do swapped line polygons exist?
|
||||
if ((GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (GPU.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
if ((gpu.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
{
|
||||
l_filledge = true;
|
||||
r_filledge = true;
|
||||
@ -1112,7 +1114,7 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
// * edges are filled if both sides are identical and fully overlapping
|
||||
// edges are always filled if antialiasing/edgemarking are enabled,
|
||||
// if the pixels are translucent and alpha blending is enabled, or if the polygon is wireframe
|
||||
if ((GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (GPU.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
if ((gpu.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu.GPU3D.RenderDispCnt & (1<<3))) || wireframe)
|
||||
{
|
||||
l_filledge = true;
|
||||
r_filledge = true;
|
||||
@ -1222,17 +1224,17 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
s16 s = interpX.Interpolate(sl, sr);
|
||||
s16 t = interpX.Interpolate(tl, tr);
|
||||
|
||||
u32 color = RenderPixel(polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u32 color = RenderPixel(gpu, polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u8 alpha = color >> 24;
|
||||
|
||||
// alpha test
|
||||
if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
|
||||
if (alpha <= gpu.GPU3D.RenderAlphaRef) continue;
|
||||
|
||||
if (alpha == 31)
|
||||
{
|
||||
u32 attr = polyattr | edge;
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<4))
|
||||
if (gpu.GPU3D.RenderDispCnt & (1<<4))
|
||||
{
|
||||
// anti-aliasing: all edges are rendered
|
||||
|
||||
@ -1262,11 +1264,11 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
else
|
||||
{
|
||||
if (!(polygon->Attr & (1<<11))) z = -1;
|
||||
PlotTranslucentPixel(pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
|
||||
// blend with bottom pixel too, if needed
|
||||
if ((dstattr & 0xF) && (pixeladdr < BufferSize))
|
||||
PlotTranslucentPixel(pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1316,17 +1318,17 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
s16 s = interpX.Interpolate(sl, sr);
|
||||
s16 t = interpX.Interpolate(tl, tr);
|
||||
|
||||
u32 color = RenderPixel(polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u32 color = RenderPixel(gpu, polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u8 alpha = color >> 24;
|
||||
|
||||
// alpha test
|
||||
if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
|
||||
if (alpha <= gpu.GPU3D.RenderAlphaRef) continue;
|
||||
|
||||
if (alpha == 31)
|
||||
{
|
||||
u32 attr = polyattr | edge;
|
||||
|
||||
if ((GPU.GPU3D.RenderDispCnt & (1<<4)) && (attr & 0xF))
|
||||
if ((gpu.GPU3D.RenderDispCnt & (1<<4)) && (attr & 0xF))
|
||||
{
|
||||
// anti-aliasing: all edges are rendered
|
||||
|
||||
@ -1349,11 +1351,11 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
else
|
||||
{
|
||||
if (!(polygon->Attr & (1<<11))) z = -1;
|
||||
PlotTranslucentPixel(pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
|
||||
// blend with bottom pixel too, if needed
|
||||
if ((dstattr & 0xF) && (pixeladdr < BufferSize))
|
||||
PlotTranslucentPixel(pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1407,17 +1409,17 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
s16 s = interpX.Interpolate(sl, sr);
|
||||
s16 t = interpX.Interpolate(tl, tr);
|
||||
|
||||
u32 color = RenderPixel(polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u32 color = RenderPixel(gpu, polygon, vr>>3, vg>>3, vb>>3, s, t);
|
||||
u8 alpha = color >> 24;
|
||||
|
||||
// alpha test
|
||||
if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
|
||||
if (alpha <= gpu.GPU3D.RenderAlphaRef) continue;
|
||||
|
||||
if (alpha == 31)
|
||||
{
|
||||
u32 attr = polyattr | edge;
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<4))
|
||||
if (gpu.GPU3D.RenderDispCnt & (1<<4))
|
||||
{
|
||||
// anti-aliasing: all edges are rendered
|
||||
|
||||
@ -1447,18 +1449,18 @@ bool SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y, bool odd)
|
||||
else
|
||||
{
|
||||
if (!(polygon->Attr & (1<<11))) z = -1;
|
||||
PlotTranslucentPixel(pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr, color, z, polyattr, polygon->IsShadow);
|
||||
|
||||
// blend with bottom pixel too, if needed
|
||||
if ((dstattr & 0xF) && (pixeladdr < BufferSize))
|
||||
PlotTranslucentPixel(pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
PlotTranslucentPixel(gpu.GPU3D, pixeladdr+BufferSize, color, z, polyattr, polygon->IsShadow);
|
||||
}
|
||||
}
|
||||
Step(rp);
|
||||
return abortscanline;
|
||||
}
|
||||
|
||||
bool SoftRenderer::RenderScanline(s32 y, int npolys, bool odd)
|
||||
bool SoftRenderer::RenderScanline(const GPU& gpu, s32 y, int npolys, bool odd)
|
||||
{
|
||||
bool abort = false;
|
||||
bool first = true;
|
||||
@ -1487,9 +1489,9 @@ bool SoftRenderer::RenderScanline(s32 y, int npolys, bool odd)
|
||||
Step(rp);
|
||||
}
|
||||
else if (polygon->IsShadowMask)
|
||||
abort = RenderShadowMaskScanline(rp, y, odd);
|
||||
abort = RenderShadowMaskScanline(gpu.GPU3D, rp, y, odd);
|
||||
else
|
||||
abort = RenderPolygonScanline(rp, y, odd);
|
||||
abort = RenderPolygonScanline(gpu, rp, y, odd);
|
||||
|
||||
first = false;
|
||||
}
|
||||
@ -1498,12 +1500,12 @@ bool SoftRenderer::RenderScanline(s32 y, int npolys, bool odd)
|
||||
return abort;
|
||||
}
|
||||
|
||||
u32 SoftRenderer::CalculateFogDensity(u32 pixeladdr)
|
||||
u32 SoftRenderer::CalculateFogDensity(const GPU3D& gpu3d, u32 pixeladdr) const
|
||||
{
|
||||
u32 z = DepthBuffer[pixeladdr];
|
||||
u32 densityid, densityfrac;
|
||||
|
||||
if (z < GPU.GPU3D.RenderFogOffset)
|
||||
if (z < gpu3d.RenderFogOffset)
|
||||
{
|
||||
densityid = 0;
|
||||
densityfrac = 0;
|
||||
@ -1515,8 +1517,8 @@ u32 SoftRenderer::CalculateFogDensity(u32 pixeladdr)
|
||||
// on hardware, the final value can overflow the 32-bit range with a shift big enough,
|
||||
// causing fog to 'wrap around' and accidentally apply to larger Z ranges
|
||||
|
||||
z -= GPU.GPU3D.RenderFogOffset;
|
||||
z = (z >> 2) << GPU.GPU3D.RenderFogShift;
|
||||
z -= gpu3d.RenderFogOffset;
|
||||
z = (z >> 2) << gpu3d.RenderFogShift;
|
||||
|
||||
densityid = z >> 17;
|
||||
if (densityid >= 32)
|
||||
@ -1530,20 +1532,20 @@ u32 SoftRenderer::CalculateFogDensity(u32 pixeladdr)
|
||||
|
||||
// checkme (may be too precise?)
|
||||
u32 density =
|
||||
((GPU.GPU3D.RenderFogDensityTable[densityid] * (0x20000-densityfrac)) +
|
||||
(GPU.GPU3D.RenderFogDensityTable[densityid+1] * densityfrac)) >> 17;
|
||||
((gpu3d.RenderFogDensityTable[densityid] * (0x20000-densityfrac)) +
|
||||
(gpu3d.RenderFogDensityTable[densityid+1] * densityfrac)) >> 17;
|
||||
if (density >= 127) density = 128;
|
||||
|
||||
return density;
|
||||
}
|
||||
|
||||
void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uhohzone)
|
||||
void SoftRenderer::ScanlineFinalPass(const GPU3D& gpu3d, s32 y, u8 rdbufferoffset, bool odd, s32 uhohzone)
|
||||
{
|
||||
// to consider:
|
||||
// clearing all polygon fog flags if the master flag isn't set?
|
||||
// merging all final pass loops into one?
|
||||
|
||||
/*if (GPU.GPU3D.RenderDispCnt & (1<<5))
|
||||
/*if (gpu3d.RenderDispCnt & (1<<5))
|
||||
{
|
||||
// edge marking
|
||||
// only applied to topmost pixels
|
||||
@ -1563,7 +1565,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
((polyid != (AttrBuffer[pixeladdr-ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr-ScanlineWidth])) ||
|
||||
((polyid != (AttrBuffer[pixeladdr+ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr+ScanlineWidth])))
|
||||
{
|
||||
u16 edgecolor = GPU.GPU3D.RenderEdgeTable[polyid >> 3];
|
||||
u16 edgecolor = gpu3d.RenderEdgeTable[polyid >> 3];
|
||||
u32 edgeR = (edgecolor << 1) & 0x3E; if (edgeR) edgeR++;
|
||||
u32 edgeG = (edgecolor >> 4) & 0x3E; if (edgeG) edgeG++;
|
||||
u32 edgeB = (edgecolor >> 9) & 0x3E; if (edgeB) edgeB++;
|
||||
@ -1576,7 +1578,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
}
|
||||
}*/
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<7))
|
||||
if (gpu3d.RenderDispCnt & (1<<7))
|
||||
{
|
||||
// fog
|
||||
|
||||
@ -1589,12 +1591,12 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
|
||||
// TODO: check the 'fog alpha glitch with small Z' GBAtek talks about
|
||||
|
||||
bool fogcolor = !(GPU.GPU3D.RenderDispCnt & (1<<6));
|
||||
bool fogcolor = !(gpu3d.RenderDispCnt & (1<<6));
|
||||
|
||||
u32 fogR = (GPU.GPU3D.RenderFogColor << 1) & 0x3E; if (fogR) fogR++;
|
||||
u32 fogG = (GPU.GPU3D.RenderFogColor >> 4) & 0x3E; if (fogG) fogG++;
|
||||
u32 fogB = (GPU.GPU3D.RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
|
||||
u32 fogA = (GPU.GPU3D.RenderFogColor >> 16) & 0x1F;
|
||||
u32 fogR = (gpu3d.RenderFogColor << 1) & 0x3E; if (fogR) fogR++;
|
||||
u32 fogG = (gpu3d.RenderFogColor >> 4) & 0x3E; if (fogG) fogG++;
|
||||
u32 fogB = (gpu3d.RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
|
||||
u32 fogA = (gpu3d.RenderFogColor >> 16) & 0x1F;
|
||||
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
@ -1604,7 +1606,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
u32 attr = AttrBuffer[pixeladdr];
|
||||
if (attr & (1<<15))
|
||||
{
|
||||
density = CalculateFogDensity(pixeladdr);
|
||||
density = CalculateFogDensity(gpu3d, pixeladdr);
|
||||
|
||||
srccolor = ColorBuffer[pixeladdr];
|
||||
srcR = srccolor & 0x3F;
|
||||
@ -1633,7 +1635,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
attr = AttrBuffer[pixeladdr];
|
||||
if (!(attr & (1<<15))) continue;
|
||||
|
||||
density = CalculateFogDensity(pixeladdr);
|
||||
density = CalculateFogDensity(gpu3d, pixeladdr);
|
||||
|
||||
srccolor = ColorBuffer[pixeladdr];
|
||||
srcR = srccolor & 0x3F;
|
||||
@ -1654,7 +1656,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
}
|
||||
}
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<4))
|
||||
if (gpu3d.RenderDispCnt & (1<<4))
|
||||
{
|
||||
// anti-aliasing
|
||||
|
||||
@ -1719,24 +1721,24 @@ void SoftRenderer::ScanlineFinalPass(s32 y, u8 rdbufferoffset, bool odd, s32 uho
|
||||
}
|
||||
}
|
||||
|
||||
void SoftRenderer::ClearBuffers()
|
||||
void SoftRenderer::ClearBuffers(const GPU& gpu)
|
||||
{
|
||||
u32 clearz = ((GPU.GPU3D.RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
|
||||
u32 polyid = GPU.GPU3D.RenderClearAttr1 & 0x3F000000; // this sets the opaque polygonID
|
||||
u32 clearz = ((gpu.GPU3D.RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
|
||||
u32 polyid = gpu.GPU3D.RenderClearAttr1 & 0x3F000000; // this sets the opaque polygonID
|
||||
|
||||
// clear the screen
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<14))
|
||||
if (gpu.GPU3D.RenderDispCnt & (1<<14))
|
||||
{
|
||||
u8 xoff = (GPU.GPU3D.RenderClearAttr2 >> 16) & 0xFF;
|
||||
u8 yoff = ((GPU.GPU3D.RenderClearAttr2 >> 24) & 0xFF);
|
||||
u8 xoff = (gpu.GPU3D.RenderClearAttr2 >> 16) & 0xFF;
|
||||
u8 yoff = (gpu.GPU3D.RenderClearAttr2 >> 24) & 0xFF;
|
||||
|
||||
for (int y = 0; y < 192; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
u16 val2 = ReadVRAM_Texture<u16>(0x40000 + (yoff << 9) + (xoff << 1));
|
||||
u16 val3 = ReadVRAM_Texture<u16>(0x60000 + (yoff << 9) + (xoff << 1));
|
||||
u16 val2 = ReadVRAM_Texture<u16>(0x40000 + (yoff << 9) + (xoff << 1), gpu);
|
||||
u16 val3 = ReadVRAM_Texture<u16>(0x60000 + (yoff << 9) + (xoff << 1), gpu);
|
||||
|
||||
// TODO: confirm color conversion
|
||||
u32 r = (val2 << 1) & 0x3E; if (r) r++;
|
||||
@ -1761,13 +1763,13 @@ void SoftRenderer::ClearBuffers()
|
||||
else
|
||||
{
|
||||
// TODO: confirm color conversion
|
||||
u32 r = (GPU.GPU3D.RenderClearAttr1 << 1) & 0x3E; if (r) r++;
|
||||
u32 g = (GPU.GPU3D.RenderClearAttr1 >> 4) & 0x3E; if (g) g++;
|
||||
u32 b = (GPU.GPU3D.RenderClearAttr1 >> 9) & 0x3E; if (b) b++;
|
||||
u32 a = (GPU.GPU3D.RenderClearAttr1 >> 16) & 0x1F;
|
||||
u32 r = (gpu.GPU3D.RenderClearAttr1 << 1) & 0x3E; if (r) r++;
|
||||
u32 g = (gpu.GPU3D.RenderClearAttr1 >> 4) & 0x3E; if (g) g++;
|
||||
u32 b = (gpu.GPU3D.RenderClearAttr1 >> 9) & 0x3E; if (b) b++;
|
||||
u32 a = (gpu.GPU3D.RenderClearAttr1 >> 16) & 0x1F;
|
||||
u32 color = r | (g << 8) | (b << 16) | (a << 24);
|
||||
|
||||
polyid |= (GPU.GPU3D.RenderClearAttr1 & 0x8000);
|
||||
polyid |= (gpu.GPU3D.RenderClearAttr1 & 0x8000);
|
||||
|
||||
for (int y = 0; y < 192; y++)
|
||||
{
|
||||
@ -1782,7 +1784,7 @@ void SoftRenderer::ClearBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
void SoftRenderer::RenderPolygons(bool threaded, Polygon** polygons, int npolys)
|
||||
void SoftRenderer::RenderPolygons(const GPU& gpu, bool threaded, Polygon** polygons, int npolys)
|
||||
{
|
||||
int j = 0;
|
||||
for (int i = 0; i < npolys; i++)
|
||||
@ -1790,7 +1792,7 @@ void SoftRenderer::RenderPolygons(bool threaded, Polygon** polygons, int npolys)
|
||||
if (polygons[i]->Degenerate) continue;
|
||||
SetupPolygon(&PolygonList[j++], polygons[i]);
|
||||
}
|
||||
|
||||
|
||||
s32 y = 0;
|
||||
s8 prevbufferline = -2;
|
||||
|
||||
@ -1825,8 +1827,8 @@ void SoftRenderer::RenderPolygons(bool threaded, Polygon** polygons, int npolys)
|
||||
if (buffersize > 48) buffersize = 48;
|
||||
}
|
||||
|
||||
abort = RenderScanline(y, j, true);
|
||||
abort |= RenderScanline(y+1, j, false);
|
||||
abort = RenderScanline(gpu, y, j, true);
|
||||
abort |= RenderScanline(gpu, y+1, j, false);
|
||||
|
||||
buffersize += 2;
|
||||
//RasterTiming += ScanlineBreak;
|
||||
@ -1868,56 +1870,56 @@ void SoftRenderer::RenderPolygons(bool threaded, Polygon** polygons, int npolys)
|
||||
if (GPU.GPU3D.RDLines > buffersize) GPU.GPU3D.RDLines = buffersize;
|
||||
}
|
||||
|
||||
if (prevbufferline >= 0)
|
||||
for (s32 y = 1; y < 192; y++)
|
||||
{
|
||||
ScanlineFinalPass(y-2, prevbufferline, true, prev2dtime);
|
||||
ScanlineFinalPass(y-1, prevbufferline+1, false, prev2dtime);
|
||||
ScanlineFinalPass(gpu.GPU3D, y-2, prevbufferline, true, prev2dtime);
|
||||
ScanlineFinalPass(gpu.GPU3D, y-1, prevbufferline+1, false, prev2dtime);
|
||||
}
|
||||
|
||||
y += 2;
|
||||
prevbufferline = bufferline;
|
||||
prev2dtime = gpu2dtracking;
|
||||
|
||||
if (threaded)
|
||||
if (threaded)
|
||||
Platform::Semaphore_Post(Sema_ScanlineCount);
|
||||
}
|
||||
|
||||
ScanlineFinalPass(190, prevbufferline, true, prev2dtime);
|
||||
ScanlineFinalPass(191, prevbufferline+1, false, prev2dtime);
|
||||
ScanlineFinalPass(gpu.GPU3D, 190, prevbufferline, true, prev2dtime);
|
||||
ScanlineFinalPass(gpu.GPU3D, 191, prevbufferline+1, false, prev2dtime);
|
||||
|
||||
if (threaded)
|
||||
Platform::Semaphore_Post(Sema_ScanlineCount);
|
||||
}
|
||||
|
||||
void SoftRenderer::VCount144()
|
||||
void SoftRenderer::VCount144(GPU& gpu)
|
||||
{
|
||||
if (RenderThreadRunning.load(std::memory_order_relaxed) && !GPU.GPU3D.AbortFrame)
|
||||
if (RenderThreadRunning.load(std::memory_order_relaxed) && !gpu.GPU3D.AbortFrame)
|
||||
Platform::Semaphore_Wait(Sema_RenderDone);
|
||||
}
|
||||
|
||||
void SoftRenderer::RenderFrame()
|
||||
void SoftRenderer::RenderFrame(GPU& gpu)
|
||||
{
|
||||
auto textureDirty = GPU.VRAMDirty_Texture.DeriveState(GPU.VRAMMap_Texture, GPU);
|
||||
auto texPalDirty = GPU.VRAMDirty_TexPal.DeriveState(GPU.VRAMMap_TexPal, GPU);
|
||||
auto textureDirty = gpu.VRAMDirty_Texture.DeriveState(gpu.VRAMMap_Texture, gpu);
|
||||
auto texPalDirty = gpu.VRAMDirty_TexPal.DeriveState(gpu.VRAMMap_TexPal, gpu);
|
||||
|
||||
bool textureChanged = GPU.MakeVRAMFlat_TextureCoherent(textureDirty);
|
||||
bool texPalChanged = GPU.MakeVRAMFlat_TexPalCoherent(texPalDirty);
|
||||
bool textureChanged = gpu.MakeVRAMFlat_TextureCoherent(textureDirty);
|
||||
bool texPalChanged = gpu.MakeVRAMFlat_TexPalCoherent(texPalDirty);
|
||||
|
||||
FrameIdentical = !(textureChanged || texPalChanged) && GPU.GPU3D.RenderFrameIdentical;
|
||||
FrameIdentical = !(textureChanged || texPalChanged) && gpu.GPU3D.RenderFrameIdentical;
|
||||
|
||||
if (RenderThreadRunning.load(std::memory_order_relaxed))
|
||||
{
|
||||
Platform::Semaphore_Post(Sema_RenderStart);
|
||||
}
|
||||
else if (!FrameIdentical) RenderPolygons(false, &GPU.GPU3D.RenderPolygonRAM[0], GPU.GPU3D.RenderNumPolygons);
|
||||
else if (!FrameIdentical) RenderPolygons(gpu, false, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
||||
}
|
||||
|
||||
void SoftRenderer::RestartFrame()
|
||||
void SoftRenderer::RestartFrame(GPU& gpu)
|
||||
{
|
||||
SetupRenderThread();
|
||||
SetupRenderThread(gpu);
|
||||
}
|
||||
|
||||
void SoftRenderer::RenderThreadFunc()
|
||||
void SoftRenderer::RenderThreadFunc(GPU& gpu)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
@ -1929,7 +1931,7 @@ void SoftRenderer::RenderThreadFunc()
|
||||
{
|
||||
Platform::Semaphore_Post(Sema_ScanlineCount, 192);
|
||||
}
|
||||
else RenderPolygons(true, &GPU.GPU3D.RenderPolygonRAM[0], GPU.GPU3D.RenderNumPolygons);
|
||||
else RenderPolygons(gpu, true, &gpu.GPU3D.RenderPolygonRAM[0], gpu.GPU3D.RenderNumPolygons);
|
||||
|
||||
Platform::Semaphore_Post(Sema_RenderDone);
|
||||
RenderThreadRendering = false;
|
||||
|
Reference in New Issue
Block a user