aboutsummaryrefslogtreecommitdiff
path: root/src/GPU3D_Soft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GPU3D_Soft.cpp')
-rw-r--r--src/GPU3D_Soft.cpp106
1 files changed, 53 insertions, 53 deletions
diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp
index 19154ba..823f752 100644
--- a/src/GPU3D_Soft.cpp
+++ b/src/GPU3D_Soft.cpp
@@ -72,8 +72,8 @@ void SoftRenderer::SetupRenderThread()
}
-SoftRenderer::SoftRenderer() noexcept
- : Renderer3D(false)
+SoftRenderer::SoftRenderer(Melon::GPU& gpu) noexcept
+ : Renderer3D(false), GPU(gpu)
{
Sema_RenderStart = Platform::Semaphore_Create();
Sema_RenderDone = Platform::Semaphore_Create();
@@ -105,7 +105,7 @@ void SoftRenderer::Reset()
SetupRenderThread();
}
-void SoftRenderer::SetRenderSettings(GPU::RenderSettings& settings)
+void SoftRenderer::SetRenderSettings(const Melon::RenderSettings& settings) noexcept
{
Threaded = settings.Soft_Threaded;
SetupRenderThread();
@@ -387,7 +387,7 @@ bool DepthTest_LessThan_FrontFacing(s32 dstz, s32 z, u32 dstattr)
return false;
}
-u32 AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha)
+u32 SoftRenderer::AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha) noexcept
{
u32 dstalpha = dstcolor >> 24;
@@ -398,7 +398,7 @@ u32 AlphaBlend(u32 srccolor, u32 dstcolor, u32 alpha)
u32 srcG = (srccolor >> 8) & 0x3F;
u32 srcB = (srccolor >> 16) & 0x3F;
- if (RenderDispCnt & (1<<3))
+ if (GPU.GPU3D.RenderDispCnt & (1<<3))
{
u32 dstR = dstcolor & 0x3F;
u32 dstG = (dstcolor >> 8) & 0x3F;
@@ -427,7 +427,7 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
if (blendmode == 2)
{
- if (RenderDispCnt & (1<<1))
+ if (GPU.GPU3D.RenderDispCnt & (1<<1))
{
// highlight mode: color is calculated normally
// except all vertex color components are set
@@ -441,7 +441,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 = RenderToonTable[vr >> 1];
+ u16 tooncolor = GPU.GPU3D.RenderToonTable[vr >> 1];
vr = (tooncolor << 1) & 0x3E; if (vr) vr++;
vg = (tooncolor >> 4) & 0x3E; if (vg) vg++;
@@ -449,7 +449,7 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
}
}
- if ((RenderDispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0))
+ if ((GPU.GPU3D.RenderDispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0))
{
u8 tr, tg, tb;
@@ -502,9 +502,9 @@ u32 SoftRenderer::RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16
a = polyalpha;
}
- if ((blendmode == 2) && (RenderDispCnt & (1<<1)))
+ if ((blendmode == 2) && (GPU.GPU3D.RenderDispCnt & (1<<1)))
{
- u16 tooncolor = RenderToonTable[vr >> 1];
+ u16 tooncolor = GPU.GPU3D.RenderToonTable[vr >> 1];
vr = (tooncolor << 1) & 0x3E; if (vr) vr++;
vg = (tooncolor >> 4) & 0x3E; if (vg) vg++;
@@ -748,7 +748,7 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
std::swap(zl, zr);
// CHECKME: edge fill rules for swapped opaque shadow mask polygons
- if ((polyalpha < 31) || (RenderDispCnt & (3<<4)))
+ if ((polyalpha < 31) || (GPU.GPU3D.RenderDispCnt & (3<<4)))
{
l_filledge = true;
r_filledge = true;
@@ -776,7 +776,7 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov);
// CHECKME: edge fill rules for unswapped opaque shadow mask polygons
- if ((polyalpha < 31) || (RenderDispCnt & (3<<4)))
+ if ((polyalpha < 31) || (GPU.GPU3D.RenderDispCnt & (3<<4)))
{
l_filledge = true;
r_filledge = true;
@@ -797,7 +797,7 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
// similarly, we can perform alpha test early (checkme)
if (wireframe) polyalpha = 31;
- if (polyalpha <= RenderAlphaRef) return;
+ if (polyalpha <= GPU.GPU3D.RenderAlphaRef) return;
// in wireframe mode, there are special rules for equal Z (TODO)
@@ -982,7 +982,7 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
// * the bottom-most pixel of negative x-major slopes are filled if they are next to a flat bottom edge
// edges are always filled if antialiasing/edgemarking are enabled or if the pixels are translucent
// checkme: do swapped line polygons exist?
- if ((polyalpha < 31) || wireframe || (RenderDispCnt & ((1<<4)|(1<<5))))
+ if ((polyalpha < 31) || wireframe || (GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))))
{
l_filledge = true;
r_filledge = true;
@@ -1016,7 +1016,7 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
// * the bottom-most pixel of negative x-major slopes are filled if they are next to a flat bottom edge
// * edges are filled if both sides are identical and fully overlapping
// edges are always filled if antialiasing/edgemarking are enabled or if the pixels are translucent
- if ((polyalpha < 31) || wireframe || (RenderDispCnt & ((1<<4)|(1<<5))))
+ if ((polyalpha < 31) || wireframe || (GPU.GPU3D.RenderDispCnt & ((1<<4)|(1<<5))))
{
l_filledge = true;
r_filledge = true;
@@ -1119,13 +1119,13 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
u8 alpha = color >> 24;
// alpha test
- if (alpha <= RenderAlphaRef) continue;
+ if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
if (alpha == 31)
{
u32 attr = polyattr | edge;
- if (RenderDispCnt & (1<<4))
+ if (GPU.GPU3D.RenderDispCnt & (1<<4))
{
// anti-aliasing: all edges are rendered
@@ -1215,13 +1215,13 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
u8 alpha = color >> 24;
// alpha test
- if (alpha <= RenderAlphaRef) continue;
+ if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
if (alpha == 31)
{
u32 attr = polyattr | edge;
- if ((RenderDispCnt & (1<<4)) && (attr & 0xF))
+ if ((GPU.GPU3D.RenderDispCnt & (1<<4)) && (attr & 0xF))
{
// anti-aliasing: all edges are rendered
@@ -1307,13 +1307,13 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
u8 alpha = color >> 24;
// alpha test
- if (alpha <= RenderAlphaRef) continue;
+ if (alpha <= GPU.GPU3D.RenderAlphaRef) continue;
if (alpha == 31)
{
u32 attr = polyattr | edge;
- if (RenderDispCnt & (1<<4))
+ if (GPU.GPU3D.RenderDispCnt & (1<<4))
{
// anti-aliasing: all edges are rendered
@@ -1377,7 +1377,7 @@ u32 SoftRenderer::CalculateFogDensity(u32 pixeladdr)
u32 z = DepthBuffer[pixeladdr];
u32 densityid, densityfrac;
- if (z < RenderFogOffset)
+ if (z < GPU.GPU3D.RenderFogOffset)
{
densityid = 0;
densityfrac = 0;
@@ -1389,8 +1389,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 -= RenderFogOffset;
- z = (z >> 2) << RenderFogShift;
+ z -= GPU.GPU3D.RenderFogOffset;
+ z = (z >> 2) << GPU.GPU3D.RenderFogShift;
densityid = z >> 17;
if (densityid >= 32)
@@ -1404,8 +1404,8 @@ u32 SoftRenderer::CalculateFogDensity(u32 pixeladdr)
// checkme (may be too precise?)
u32 density =
- ((RenderFogDensityTable[densityid] * (0x20000-densityfrac)) +
- (RenderFogDensityTable[densityid+1] * densityfrac)) >> 17;
+ ((GPU.GPU3D.RenderFogDensityTable[densityid] * (0x20000-densityfrac)) +
+ (GPU.GPU3D.RenderFogDensityTable[densityid+1] * densityfrac)) >> 17;
if (density >= 127) density = 128;
return density;
@@ -1417,7 +1417,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
// clearing all polygon fog flags if the master flag isn't set?
// merging all final pass loops into one?
- if (RenderDispCnt & (1<<5))
+ if (GPU.GPU3D.RenderDispCnt & (1<<5))
{
// edge marking
// only applied to topmost pixels
@@ -1437,7 +1437,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
((polyid != (AttrBuffer[pixeladdr-ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr-ScanlineWidth])) ||
((polyid != (AttrBuffer[pixeladdr+ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr+ScanlineWidth])))
{
- u16 edgecolor = RenderEdgeTable[polyid >> 3];
+ u16 edgecolor = GPU.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++;
@@ -1450,7 +1450,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
}
}
- if (RenderDispCnt & (1<<7))
+ if (GPU.GPU3D.RenderDispCnt & (1<<7))
{
// fog
@@ -1463,12 +1463,12 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
// TODO: check the 'fog alpha glitch with small Z' GBAtek talks about
- bool fogcolor = !(RenderDispCnt & (1<<6));
+ bool fogcolor = !(GPU.GPU3D.RenderDispCnt & (1<<6));
- u32 fogR = (RenderFogColor << 1) & 0x3E; if (fogR) fogR++;
- u32 fogG = (RenderFogColor >> 4) & 0x3E; if (fogG) fogG++;
- u32 fogB = (RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
- u32 fogA = (RenderFogColor >> 16) & 0x1F;
+ 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;
for (int x = 0; x < 256; x++)
{
@@ -1528,7 +1528,7 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
}
}
- if (RenderDispCnt & (1<<4))
+ if (GPU.GPU3D.RenderDispCnt & (1<<4))
{
// anti-aliasing
@@ -1583,8 +1583,8 @@ void SoftRenderer::ScanlineFinalPass(s32 y)
void SoftRenderer::ClearBuffers()
{
- u32 clearz = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
- u32 polyid = 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
// fill screen borders for edge marking
@@ -1614,10 +1614,10 @@ void SoftRenderer::ClearBuffers()
// clear the screen
- if (RenderDispCnt & (1<<14))
+ if (GPU.GPU3D.RenderDispCnt & (1<<14))
{
- u8 xoff = (RenderClearAttr2 >> 16) & 0xFF;
- u8 yoff = (RenderClearAttr2 >> 24) & 0xFF;
+ u8 xoff = (GPU.GPU3D.RenderClearAttr2 >> 16) & 0xFF;
+ u8 yoff = (GPU.GPU3D.RenderClearAttr2 >> 24) & 0xFF;
for (int y = 0; y < ScanlineWidth*192; y+=ScanlineWidth)
{
@@ -1649,13 +1649,13 @@ void SoftRenderer::ClearBuffers()
else
{
// TODO: confirm color conversion
- u32 r = (RenderClearAttr1 << 1) & 0x3E; if (r) r++;
- u32 g = (RenderClearAttr1 >> 4) & 0x3E; if (g) g++;
- u32 b = (RenderClearAttr1 >> 9) & 0x3E; if (b) b++;
- u32 a = (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 |= (RenderClearAttr1 & 0x8000);
+ polyid |= (GPU.GPU3D.RenderClearAttr1 & 0x8000);
for (int y = 0; y < ScanlineWidth*192; y+=ScanlineWidth)
{
@@ -1698,19 +1698,19 @@ void SoftRenderer::RenderPolygons(bool threaded, Polygon** polygons, int npolys)
void SoftRenderer::VCount144()
{
- if (RenderThreadRunning.load(std::memory_order_relaxed) && !GPU3D::AbortFrame)
+ if (RenderThreadRunning.load(std::memory_order_relaxed) && !GPU.GPU3D.AbortFrame)
Platform::Semaphore_Wait(Sema_RenderDone);
}
void SoftRenderer::RenderFrame()
{
- auto textureDirty = GPU::VRAMDirty_Texture.DeriveState(GPU::VRAMMap_Texture);
- auto texPalDirty = GPU::VRAMDirty_TexPal.DeriveState(GPU::VRAMMap_TexPal);
+ 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) && RenderFrameIdentical;
+ FrameIdentical = !(textureChanged || texPalChanged) && GPU.GPU3D.RenderFrameIdentical;
if (RenderThreadRunning.load(std::memory_order_relaxed))
{
@@ -1719,7 +1719,7 @@ void SoftRenderer::RenderFrame()
else if (!FrameIdentical)
{
ClearBuffers();
- RenderPolygons(false, &RenderPolygonRAM[0], RenderNumPolygons);
+ RenderPolygons(false, &GPU.GPU3D.RenderPolygonRAM[0], GPU.GPU3D.RenderNumPolygons);
}
}
@@ -1743,7 +1743,7 @@ void SoftRenderer::RenderThreadFunc()
else
{
ClearBuffers();
- RenderPolygons(true, &RenderPolygonRAM[0], RenderNumPolygons);
+ RenderPolygons(true, &GPU.GPU3D.RenderPolygonRAM[0], GPU.GPU3D.RenderNumPolygons);
}
Platform::Semaphore_Post(Sema_RenderDone);