From e06d11f6df8c2e35d570412c45f5a63e5e7c031d Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 23 Jan 2019 16:03:09 -0800 Subject: [PATCH] GFX3D: The polygon clipping stage now occurs before any polygon sorting, allowing for the sorting of smaller lists. This can be a significant performance improvement for some 3D scenes with high polygon counts. - 3D renderers no longer perform polygon clipping themselves, instead relying on GFX3D to do it. By default, the clipping mode is ClipperMode_DetermineClipOnly, but 3D renderers can change this by overriding the virtual method Render3D::GetPreferredPolygonClippingMode() and returning their preferred clipping mode. --- desmume/src/OGLRender.cpp | 12 +- desmume/src/OGLRender_3_2.cpp | 6 +- desmume/src/gfx3d.cpp | 271 +++++++++++++++++++++++----------- desmume/src/gfx3d.h | 13 +- desmume/src/rasterize.cpp | 17 +-- desmume/src/rasterize.h | 2 + desmume/src/render3D.cpp | 52 +------ desmume/src/render3D.h | 4 +- 8 files changed, 221 insertions(+), 156 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 92f8333d9..182ae9eca 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -4239,6 +4239,10 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) return OGLERROR_BEGINGL_FAILED; } + this->_clippedPolyCount = engine.clippedPolyCount; + this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount; + this->_clippedPolyList = engine.clippedPolyList; + if (this->isVBOSupported) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID); @@ -4256,8 +4260,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) } // Generate the clipped polygon list. - this->_PerformClipping(engine.vertList, engine.polylist, &engine.indexlist); - this->_renderNeedsDepthEqualsTest = false; for (size_t i = 0, vertIndexCount = 0; i < this->_clippedPolyCount; i++) { @@ -5531,6 +5533,10 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) return OGLERROR_BEGINGL_FAILED; } + this->_clippedPolyCount = engine.clippedPolyCount; + this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount; + this->_clippedPolyList = engine.clippedPolyList; + glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); @@ -5538,8 +5544,6 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertListCount, engine.vertList); // Generate the clipped polygon list. - this->_PerformClipping(engine.vertList, engine.polylist, &engine.indexlist); - this->_renderNeedsDepthEqualsTest = false; for (size_t i = 0, vertIndexCount = 0; i < this->_clippedPolyCount; i++) { diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 4eec99319..090a66e10 100755 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -2153,6 +2153,10 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) return OGLERROR_BEGINGL_FAILED; } + this->_clippedPolyCount = engine.clippedPolyCount; + this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount; + this->_clippedPolyList = engine.clippedPolyList; + glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); @@ -2213,8 +2217,6 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(this->_pendingRenderStates), &this->_pendingRenderStates); // Generate the clipped polygon list. - this->_PerformClipping(engine.vertList, engine.polylist, &engine.indexlist); - if ( (OGLRef.uboPolyStatesID != 0) && (this->_clippedPolyCount > MAX_CLIPPED_POLY_COUNT_FOR_UBO) ) { // In practice, there shouldn't be any game scene with a clipped polygon count that diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 9c52892a7..33ed4e405 100755 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -371,6 +371,11 @@ POLYLIST* polylist = NULL; VERT *vertLists = NULL; VERT *vertList = NULL; +GFX3D_Clipper *_clipper = NULL; +CPoly _clippedPolyWorkingList[POLYLIST_SIZE * 2]; +CPoly _clippedPolyUnsortedList[POLYLIST_SIZE]; +CPoly _clippedPolySortedList[POLYLIST_SIZE]; + size_t vertListCount[2] = {0, 0}; int polygonListCompleted = 0; @@ -502,6 +507,9 @@ void VERT::load(EMUFILE &is) void gfx3d_init() { + _clipper = new GFX3D_Clipper; + _clipper->SetClippedPolyBufferPtr(_clippedPolyWorkingList); + polyAttrInProcess.value = 0; currentPolyAttr.value = 0; currentPolyTexParam.value = 0; @@ -564,6 +572,8 @@ void gfx3d_deinit() free_aligned(vertLists); vertLists = NULL; vertList = NULL; + + delete _clipper; } void gfx3d_reset() @@ -594,6 +604,9 @@ void gfx3d_reset() gfx3d.polylist = polylist; gfx3d.vertList = vertList; gfx3d.vertListCount = vertListCount[listTwiddle]; + gfx3d.clippedPolyCount = 0; + gfx3d.clippedPolyOpaqueCount = 0; + gfx3d.clippedPolyList = _clippedPolySortedList; polyAttrInProcess.value = 0; currentPolyAttr.value = 0; @@ -1800,10 +1813,10 @@ static BOOL gfx3d_glBoxTest(u32 v) &verts[thePoly.vertIndexes[3]] }; - boxtestClipper.ClipPoly(thePoly, vertTable); + const bool isPolyUnclipped = boxtestClipper.ClipPoly(0, thePoly, vertTable); //if any portion of this poly was retained, then the test passes. - if (boxtestClipper.GetPolyCount() > 0) + if (isPolyUnclipped) { //printf("%06d PASS %d\n",gxFIFO.size, i); MMU_new.gxstat.tr = 1; @@ -2280,8 +2293,8 @@ void gfx3d_glFlush(u32 v) static bool gfx3d_ysort_compare(int num1, int num2) { - const POLY &poly1 = polylist->list[num1]; - const POLY &poly2 = polylist->list[num2]; + const POLY &poly1 = gfx3d.polylist->list[num1]; + const POLY &poly2 = gfx3d.polylist->list[num2]; //this may be verified by checking the game create menus in harvest moon island of happiness //also the buttons in the knights in the nightmare frontend depend on this and the perspective division @@ -2301,6 +2314,145 @@ static bool gfx3d_ysort_compare(int num1, int num2) return (num1 < num2); } +template +void gfx3d_PerformClipping(const VERT *vtxList, const POLYLIST *polyList) +{ + bool isPolyUnclipped = false; + _clipper->Reset(); + + for (size_t polyIndex = 0, clipCount = 0; polyIndex < polyList->count; polyIndex++) + { + const POLY &poly = polyList->list[polyIndex]; + + const VERT *clipVerts[4] = { + &vtxList[poly.vertIndexes[0]], + &vtxList[poly.vertIndexes[1]], + &vtxList[poly.vertIndexes[2]], + (poly.type == POLYGON_TYPE_QUAD) ? &vtxList[poly.vertIndexes[3]] : NULL + }; + + isPolyUnclipped = _clipper->ClipPoly(polyIndex, poly, clipVerts); + + if (CLIPPERMODE == ClipperMode_DetermineClipOnly) + { + if (isPolyUnclipped) + { + _clippedPolyUnsortedList[polyIndex].index = _clipper->GetClippedPolyByIndex(clipCount).index; + _clippedPolyUnsortedList[polyIndex].poly = _clipper->GetClippedPolyByIndex(clipCount).poly; + clipCount++; + } + } + else + { + if (isPolyUnclipped) + { + _clippedPolyUnsortedList[polyIndex] = _clipper->GetClippedPolyByIndex(clipCount); + clipCount++; + } + } + } +} + +void gfx3d_GenerateRenderLists(const ClipperMode clippingMode) +{ + switch (clippingMode) + { + case ClipperMode_Full: + gfx3d_PerformClipping(gfx3d.vertList, gfx3d.polylist); + break; + + case ClipperMode_FullColorInterpolate: + gfx3d_PerformClipping(gfx3d.vertList, gfx3d.polylist); + break; + + case ClipperMode_DetermineClipOnly: + gfx3d_PerformClipping(gfx3d.vertList, gfx3d.polylist); + break; + } + + gfx3d.clippedPolyCount = _clipper->GetPolyCount(); + +#ifdef _SHOW_VTX_COUNTERS + max_polys = max((u32)polycount, max_polys); + max_verts = max((u32)vertListCount[listTwiddle], max_verts); + osd->addFixed(180, 20, "%i/%i", polycount, vertListCount[listTwiddle]); // current + osd->addFixed(180, 35, "%i/%i", max_polys, max_verts); // max +#endif + + //we need to sort the poly list with alpha polys last + //first, look for opaque polys + size_t ctr = 0; + for (size_t i = 0; i < gfx3d.clippedPolyCount; i++) + { + const CPoly &clippedPoly = _clipper->GetClippedPolyByIndex(i); + if (!clippedPoly.poly->isTranslucent()) + gfx3d.indexlist.list[ctr++] = clippedPoly.index; + } + gfx3d.clippedPolyOpaqueCount = ctr; + + //then look for translucent polys + for (size_t i = 0; i < gfx3d.clippedPolyCount; i++) + { + const CPoly &clippedPoly = _clipper->GetClippedPolyByIndex(i); + if (clippedPoly.poly->isTranslucent()) + gfx3d.indexlist.list[ctr++] = clippedPoly.index; + } + + //find the min and max y values for each poly. + //the w-division here is just an approximation to fix the shop in harvest moon island of happiness + //also the buttons in the knights in the nightmare frontend depend on this + size_t ysortCount = (gfx3d.state.sortmode) ? gfx3d.clippedPolyOpaqueCount : gfx3d.clippedPolyCount; + for (size_t i = 0; i < ysortCount; i++) + { + // TODO: Possible divide by zero with the w-coordinate. + // Is the vertex being read correctly? Is 0 a valid value for w? + // If both of these questions answer to yes, then how does the NDS handle a NaN? + // For now, simply prevent w from being zero. + POLY &poly = *_clipper->GetClippedPolyByIndex(i).poly; + float verty = gfx3d.vertList[poly.vertIndexes[0]].y; + float vertw = (gfx3d.vertList[poly.vertIndexes[0]].w != 0.0f) ? gfx3d.vertList[poly.vertIndexes[0]].w : 0.00000001f; + verty = 1.0f-(verty+vertw)/(2*vertw); + poly.miny = poly.maxy = verty; + + for (size_t j = 1; j < poly.type; j++) + { + verty = gfx3d.vertList[poly.vertIndexes[j]].y; + vertw = (gfx3d.vertList[poly.vertIndexes[j]].w != 0.0f) ? gfx3d.vertList[poly.vertIndexes[j]].w : 0.00000001f; + verty = 1.0f-(verty+vertw)/(2*vertw); + poly.miny = min(poly.miny, verty); + poly.maxy = max(poly.maxy, verty); + } + } + + //now we have to sort the opaque polys by y-value. + //(test case: harvest moon island of happiness character creator UI) + //should this be done after clipping?? + std::sort(gfx3d.indexlist.list, gfx3d.indexlist.list + gfx3d.clippedPolyOpaqueCount, gfx3d_ysort_compare); + + if (!gfx3d.state.sortmode) + { + //if we are autosorting translucent polys, we need to do this also + //TODO - this is unverified behavior. need a test case + std::sort(gfx3d.indexlist.list + gfx3d.clippedPolyOpaqueCount, gfx3d.indexlist.list + gfx3d.clippedPolyCount, gfx3d_ysort_compare); + } + + // Reorder the clipped polygon list to match our sorted index list. + if (clippingMode == ClipperMode_DetermineClipOnly) + { + for (size_t i = 0; i < gfx3d.clippedPolyCount; i++) + { + _clippedPolySortedList[i].poly = _clippedPolyUnsortedList[gfx3d.indexlist.list[i]].poly; + } + } + else + { + for (size_t i = 0; i < gfx3d.clippedPolyCount; i++) + { + _clippedPolySortedList[i] = _clippedPolyUnsortedList[gfx3d.indexlist.list[i]]; + } + } +} + static void gfx3d_doFlush() { gfx3d.render3DFrameCount++; @@ -2320,75 +2472,10 @@ static void gfx3d_doFlush() gfx3d.renderState = gfx3d.state; gfx3d.state.activeFlushCommand = gfx3d.state.pendingFlushCommand; - - const size_t polycount = polylist->count; -#ifdef _SHOW_VTX_COUNTERS - max_polys = max((u32)polycount, max_polys); - max_verts = max((u32)vertListCount[listTwiddle], max_verts); - osd->addFixed(180, 20, "%i/%i", polycount, vertListCount[listTwiddle]); // current - osd->addFixed(180, 35, "%i/%i", max_polys, max_verts); // max -#endif - - //find the min and max y values for each poly. - //TODO - this could be a small waste of time if we are manual sorting the translucent polys - //TODO - this _MUST_ be moved later in the pipeline, after clipping. - //the w-division here is just an approximation to fix the shop in harvest moon island of happiness - //also the buttons in the knights in the nightmare frontend depend on this - for (size_t i = 0; i < polycount; i++) - { - // TODO: Possible divide by zero with the w-coordinate. - // Is the vertex being read correctly? Is 0 a valid value for w? - // If both of these questions answer to yes, then how does the NDS handle a NaN? - // For now, simply prevent w from being zero. - POLY &poly = polylist->list[i]; - float verty = vertList[poly.vertIndexes[0]].y; - float vertw = (vertList[poly.vertIndexes[0]].w != 0.0f) ? vertList[poly.vertIndexes[0]].w : 0.00000001f; - verty = 1.0f-(verty+vertw)/(2*vertw); - poly.miny = poly.maxy = verty; - - for (size_t j = 1; j < poly.type; j++) - { - verty = vertList[poly.vertIndexes[j]].y; - vertw = (vertList[poly.vertIndexes[j]].w != 0.0f) ? vertList[poly.vertIndexes[j]].w : 0.00000001f; - verty = 1.0f-(verty+vertw)/(2*vertw); - poly.miny = min(poly.miny, verty); - poly.maxy = max(poly.maxy, verty); - } - - } - - //we need to sort the poly list with alpha polys last - //first, look for opaque polys - size_t ctr = 0; - for (size_t i = 0; i < polycount; i++) - { - const POLY &poly = polylist->list[i]; - if (!poly.isTranslucent()) - gfx3d.indexlist.list[ctr++] = i; - } - polylist->opaqueCount = ctr; + const ClipperMode clippingMode = CurrentRenderer->GetPreferredPolygonClippingMode(); + gfx3d_GenerateRenderLists(clippingMode); - //then look for translucent polys - for (size_t i = 0; i < polycount; i++) - { - const POLY &poly = polylist->list[i]; - if (poly.isTranslucent()) - gfx3d.indexlist.list[ctr++] = i; - } - - //now we have to sort the opaque polys by y-value. - //(test case: harvest moon island of happiness character creator UI) - //should this be done after clipping?? - std::sort(gfx3d.indexlist.list, gfx3d.indexlist.list + polylist->opaqueCount, gfx3d_ysort_compare); - - if (!gfx3d.state.sortmode) - { - //if we are autosorting translucent polys, we need to do this also - //TODO - this is unverified behavior. need a test case - std::sort(gfx3d.indexlist.list + polylist->opaqueCount, gfx3d.indexlist.list + polycount, gfx3d_ysort_compare); - } - //switch to the new lists twiddleLists(); @@ -2470,7 +2557,16 @@ void gfx3d_VBlankEndSignal(bool skipFrame) drawPending = FALSE; GPU->GetEventHandler()->DidApplyRender3DSettingsBegin(); + + const ClipperMode oldClippingMode = CurrentRenderer->GetPreferredPolygonClippingMode(); GPU->Change3DRendererIfNeeded(); + const ClipperMode newClippingMode = CurrentRenderer->GetPreferredPolygonClippingMode(); + + if (oldClippingMode != newClippingMode) + { + gfx3d_GenerateRenderLists(newClippingMode); + } + CurrentRenderer->ApplyRenderingSettings(gfx3d.renderState); GPU->GetEventHandler()->DidApplyRender3DSettingsEnd(); @@ -3059,7 +3155,7 @@ static FORCEINLINE VERT clipPoint(const VERT *inside, const VERT *outside) ret.color_to_float(); break; - case ClipperMode_InterpolateFull: + case ClipperMode_FullColorInterpolate: INTERP(texcoord[0]); INTERP(texcoord[1]); INTERP(fcolor[0]); INTERP(fcolor[1]); INTERP(fcolor[2]); break; @@ -3204,12 +3300,12 @@ typedef ClipperPlane Stage1; static Stage1 // Interpolated clippers static ClipperOutput clipperOuti; -typedef ClipperPlane Stage6i; static Stage6 clipper6i (clipperOuti); // back plane //TODO - we need to parameterize back plane clipping -typedef ClipperPlane Stage5i; static Stage5 clipper5i (clipper6i); // front plane -typedef ClipperPlane Stage4i; static Stage4 clipper4i (clipper5i); // top plane -typedef ClipperPlane Stage3i; static Stage3 clipper3i (clipper4i); // bottom plane -typedef ClipperPlane Stage2i; static Stage2 clipper2i (clipper3i); // right plane -typedef ClipperPlane Stage1i; static Stage1 clipper1i (clipper2i); // left plane +typedef ClipperPlane Stage6i; static Stage6 clipper6i (clipperOuti); // back plane //TODO - we need to parameterize back plane clipping +typedef ClipperPlane Stage5i; static Stage5 clipper5i (clipper6i); // front plane +typedef ClipperPlane Stage4i; static Stage4 clipper4i (clipper5i); // top plane +typedef ClipperPlane Stage3i; static Stage3 clipper3i (clipper4i); // bottom plane +typedef ClipperPlane Stage2i; static Stage2 clipper2i (clipper3i); // right plane +typedef ClipperPlane Stage1i; static Stage1 clipper1i (clipper2i); // left plane // Determine's clip status only static ClipperOutput clipperOutd; @@ -3252,7 +3348,7 @@ void GFX3D_Clipper::Reset() } template -void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts) +bool GFX3D_Clipper::ClipPoly(const u16 polyIndex, const POLY &poly, const VERT **verts) { CLIPLOG("==Begin poly==\n"); @@ -3272,7 +3368,7 @@ void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts) break; } - case ClipperMode_InterpolateFull: + case ClipperMode_FullColorInterpolate: { clipper1i.init(this->_clippedPolyList[this->_clippedPolyCounter].clipVerts); for (size_t i = 0; i < type; i++) @@ -3298,16 +3394,17 @@ void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts) { //a totally clipped poly. discard it. //or, a degenerate poly. we're not handling these right now + return false; } else { - this->_clippedPolyList[this->_clippedPolyCounter].type = outType; - this->_clippedPolyList[this->_clippedPolyCounter].poly = (POLY *)&poly; + CPoly &thePoly = this->_clippedPolyList[this->_clippedPolyCounter]; + thePoly.index = polyIndex; + thePoly.type = outType; + thePoly.poly = (POLY *)&poly; + this->_clippedPolyCounter++; } + + return true; } - -//these templates needed to be instantiated manually -template void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts); -template void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts); -template void GFX3D_Clipper::ClipPoly(const POLY &poly, const VERT **verts); diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 36f347a13..8d41b6105 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -479,13 +479,14 @@ struct VIEWPORT { enum ClipperMode { - ClipperMode_Full = 0, - ClipperMode_InterpolateFull = 1, - ClipperMode_DetermineClipOnly = 2 + ClipperMode_DetermineClipOnly = 0, // Retains only the pointer to the original polygon info. All other information in CPoly is considered undefined. + ClipperMode_Full = 1, // Retains all of the modified polygon's info in CPoly, including the clipped vertex info. + ClipperMode_FullColorInterpolate = 2 // Same as ClipperMode_Full, but the vertex color attribute is better interpolated. }; struct CPoly { + u16 index; // The index number of this polygon in the full polygon list. PolygonType type; //otherwise known as "count" of verts POLY *poly; VERT clipVerts[MAX_CLIPPED_VERTS]; @@ -507,7 +508,7 @@ public: size_t GetPolyCount() const; void Reset(); - template void ClipPoly(const POLY &poly, const VERT **verts); // the entry point for poly clipping + template bool ClipPoly(const u16 polyIndex, const POLY &poly, const VERT **verts); // the entry point for poly clipping }; //used to communicate state to the renderer @@ -601,6 +602,10 @@ struct GFX3D VERT *vertList; INDEXLIST indexlist; + size_t clippedPolyCount; + size_t clippedPolyOpaqueCount; + CPoly *clippedPolyList; + size_t vertListCount; u32 render3DFrameCount; // Increments when gfx3d_doFlush() is called. Resets every 60 video frames. }; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index e1dc8726f..e42ef2566 100755 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -1867,6 +1867,11 @@ Render3DError SoftRasterizerRenderer::InitTables() return RENDER3DERROR_NOERR; } +ClipperMode SoftRasterizerRenderer::GetPreferredPolygonClippingMode() const +{ + return (this->_enableHighPrecisionColorInterpolation) ? ClipperMode_FullColorInterpolate : ClipperMode_Full; +} + void SoftRasterizerRenderer::performViewportTransforms() { const float wScalar = (float)this->_framebufferWidth / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; @@ -2020,15 +2025,9 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine) // Keep the current render states for later use this->currentRenderState = (GFX3D_State *)&engine.renderState; - - if (this->_enableHighPrecisionColorInterpolation) - { - this->_PerformClipping(engine.vertList, engine.polylist, &engine.indexlist); - } - else - { - this->_PerformClipping(engine.vertList, engine.polylist, &engine.indexlist); - } + this->_clippedPolyCount = engine.clippedPolyCount; + this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount; + this->_clippedPolyList = engine.clippedPolyList; const bool doMultithreadedStateSetup = (this->_threadCount >= 2); diff --git a/desmume/src/rasterize.h b/desmume/src/rasterize.h index 59d328a76..becafc0eb 100644 --- a/desmume/src/rasterize.h +++ b/desmume/src/rasterize.h @@ -191,6 +191,8 @@ public: SoftRasterizerRenderer(); virtual ~SoftRasterizerRenderer(); + virtual ClipperMode GetPreferredPolygonClippingMode() const; + void performViewportTransforms(); void performBackfaceTests(); void performCoordAdjustment(); diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 029c9cc5c..cd37ded25 100755 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -249,9 +249,6 @@ Render3D::Render3D() _textureList[i] = NULL; } - _clippedPolyList = (CPoly *)malloc_alignedCacheLine(POLYLIST_SIZE * 2 * sizeof(CPoly)); - _clipper.SetClippedPolyBufferPtr(_clippedPolyList); - memset(this->clearImageColor16Buffer, 0, sizeof(this->clearImageColor16Buffer)); memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer)); memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer)); @@ -267,8 +264,6 @@ Render3D::~Render3D() this->_textureDeposterizeDstSurface.Surface = NULL; this->_textureDeposterizeDstSurface.workingSurface[0] = NULL; } - - free_aligned(this->_clippedPolyList); } const Render3DDeviceInfo& Render3D::GetDeviceInfo() @@ -404,6 +399,11 @@ Render3DTexture* Render3D::GetTextureByPolygonRenderIndex(size_t polyRenderIndex return this->_textureList[polyRenderIndex]; } +ClipperMode Render3D::GetPreferredPolygonClippingMode() const +{ + return ClipperMode_DetermineClipOnly; +} + const CPoly& Render3D::GetClippedPolyByIndex(size_t index) const { return this->_clippedPolyList[index]; @@ -414,44 +414,6 @@ size_t Render3D::GetClippedPolyCount() const return this->_clippedPolyCount; } -template -void Render3D::_PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) -{ - //submit all polys to clipper - this->_clipper.Reset(); - - size_t i = 0; - for (; i < polyList->opaqueCount; i++) - { - const POLY &poly = polyList->list[indexList->list[i]]; - const VERT *clipVerts[4] = { - &vertList[poly.vertIndexes[0]], - &vertList[poly.vertIndexes[1]], - &vertList[poly.vertIndexes[2]], - (poly.type == POLYGON_TYPE_QUAD) ? &vertList[poly.vertIndexes[3]] : NULL - }; - - this->_clipper.ClipPoly(poly, clipVerts); - } - - this->_clippedPolyOpaqueCount = this->_clipper.GetPolyCount(); - - for (; i < polyList->count; i++) - { - const POLY &poly = polyList->list[indexList->list[i]]; - const VERT *clipVerts[4] = { - &vertList[poly.vertIndexes[0]], - &vertList[poly.vertIndexes[1]], - &vertList[poly.vertIndexes[2]], - (poly.type == POLYGON_TYPE_QUAD) ? &vertList[poly.vertIndexes[3]] : NULL - }; - - this->_clipper.ClipPoly(poly, clipVerts); - } - - this->_clippedPolyCount = this->_clipper.GetPolyCount(); -} - Render3DError Render3D::ApplyRenderingSettings(const GFX3D_State &renderState) { this->_enableEdgeMark = (CommonSettings.GFX3D_EdgeMark) ? renderState.enableEdgeMarking : false; @@ -1019,9 +981,5 @@ Render3DError Render3D_SSE2::ClearFramebuffer(const GFX3D_State &renderState) #endif // defined(ENABLE_AVX2) || defined(ENABLE_SSE2) -template void Render3D::_PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); -template void Render3D::_PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); -template void Render3D::_PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); - template Render3D_SIMD<16>::Render3D_SIMD(); template Render3D_SIMD<32>::Render3D_SIMD(); diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index 34fc623c8..d5fad8d70 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -187,15 +187,12 @@ protected: size_t _clippedPolyCount; size_t _clippedPolyOpaqueCount; - GFX3D_Clipper _clipper; CPoly *_clippedPolyList; CACHE_ALIGN u16 clearImageColor16Buffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u32 clearImageDepthBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u8 clearImageFogBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; - template void _PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); - template void _ClearImageScrolledLoop(const u8 xScroll, const u8 yScroll, const u16 *__restrict inColor16, const u16 *__restrict inDepth16, u16 *__restrict outColor16, u32 *__restrict outDepth24, u8 *__restrict outFog); @@ -272,6 +269,7 @@ public: void SetTextureProcessingProperties(); Render3DTexture* GetTextureByPolygonRenderIndex(size_t polyRenderIndex) const; + virtual ClipperMode GetPreferredPolygonClippingMode() const; const CPoly& GetClippedPolyByIndex(size_t index) const; size_t GetClippedPolyCount() const; };