diff options
Diffstat (limited to 'src/GPU3D_Soft.cpp')
-rw-r--r-- | src/GPU3D_Soft.cpp | 106 |
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); |