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.
This commit is contained in:
rogerman 2019-01-23 16:03:09 -08:00
parent b8e85e0c9d
commit e06d11f6df
8 changed files with 221 additions and 156 deletions

View File

@ -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<ClipperMode_DetermineClipOnly>(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<ClipperMode_DetermineClipOnly>(engine.vertList, engine.polylist, &engine.indexlist);
this->_renderNeedsDepthEqualsTest = false;
for (size_t i = 0, vertIndexCount = 0; i < this->_clippedPolyCount; i++)
{

View File

@ -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<ClipperMode_DetermineClipOnly>(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

View File

@ -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<ClipperMode_DetermineClipOnly>(thePoly, vertTable);
const bool isPolyUnclipped = boxtestClipper.ClipPoly<ClipperMode_DetermineClipOnly>(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 <ClipperMode CLIPPERMODE>
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<CLIPPERMODE>(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<ClipperMode_Full>(gfx3d.vertList, gfx3d.polylist);
break;
case ClipperMode_FullColorInterpolate:
gfx3d_PerformClipping<ClipperMode_FullColorInterpolate>(gfx3d.vertList, gfx3d.polylist);
break;
case ClipperMode_DetermineClipOnly:
gfx3d_PerformClipping<ClipperMode_DetermineClipOnly>(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<ClipperMode_Full, 0,-1,Stage2> Stage1; static Stage1
// Interpolated clippers
static ClipperOutput clipperOuti;
typedef ClipperPlane<ClipperMode_InterpolateFull, 2, 1,ClipperOutput> Stage6i; static Stage6 clipper6i (clipperOuti); // back plane //TODO - we need to parameterize back plane clipping
typedef ClipperPlane<ClipperMode_InterpolateFull, 2,-1,Stage6i> Stage5i; static Stage5 clipper5i (clipper6i); // front plane
typedef ClipperPlane<ClipperMode_InterpolateFull, 1, 1,Stage5i> Stage4i; static Stage4 clipper4i (clipper5i); // top plane
typedef ClipperPlane<ClipperMode_InterpolateFull, 1,-1,Stage4i> Stage3i; static Stage3 clipper3i (clipper4i); // bottom plane
typedef ClipperPlane<ClipperMode_InterpolateFull, 0, 1,Stage3i> Stage2i; static Stage2 clipper2i (clipper3i); // right plane
typedef ClipperPlane<ClipperMode_InterpolateFull, 0,-1,Stage2i> Stage1i; static Stage1 clipper1i (clipper2i); // left plane
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 2, 1,ClipperOutput> Stage6i; static Stage6 clipper6i (clipperOuti); // back plane //TODO - we need to parameterize back plane clipping
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 2,-1,Stage6i> Stage5i; static Stage5 clipper5i (clipper6i); // front plane
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 1, 1,Stage5i> Stage4i; static Stage4 clipper4i (clipper5i); // top plane
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 1,-1,Stage4i> Stage3i; static Stage3 clipper3i (clipper4i); // bottom plane
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 0, 1,Stage3i> Stage2i; static Stage2 clipper2i (clipper3i); // right plane
typedef ClipperPlane<ClipperMode_FullColorInterpolate, 0,-1,Stage2i> Stage1i; static Stage1 clipper1i (clipper2i); // left plane
// Determine's clip status only
static ClipperOutput clipperOutd;
@ -3252,7 +3348,7 @@ void GFX3D_Clipper::Reset()
}
template <ClipperMode CLIPPERMODE>
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<ClipperMode_Full>(const POLY &poly, const VERT **verts);
template void GFX3D_Clipper::ClipPoly<ClipperMode_InterpolateFull>(const POLY &poly, const VERT **verts);
template void GFX3D_Clipper::ClipPoly<ClipperMode_DetermineClipOnly>(const POLY &poly, const VERT **verts);

View File

@ -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<ClipperMode CLIPPERMODE> void ClipPoly(const POLY &poly, const VERT **verts); // the entry point for poly clipping
template<ClipperMode CLIPPERMODE> 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.
};

View File

@ -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<ClipperMode_InterpolateFull>(engine.vertList, engine.polylist, &engine.indexlist);
}
else
{
this->_PerformClipping<ClipperMode_Full>(engine.vertList, engine.polylist, &engine.indexlist);
}
this->_clippedPolyCount = engine.clippedPolyCount;
this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount;
this->_clippedPolyList = engine.clippedPolyList;
const bool doMultithreadedStateSetup = (this->_threadCount >= 2);

View File

@ -191,6 +191,8 @@ public:
SoftRasterizerRenderer();
virtual ~SoftRasterizerRenderer();
virtual ClipperMode GetPreferredPolygonClippingMode() const;
void performViewportTransforms();
void performBackfaceTests();
void performCoordAdjustment();

View File

@ -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 <ClipperMode CLIPPERMODE>
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<CLIPPERMODE>(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<CLIPPERMODE>(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<ClipperMode_Full>(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
template void Render3D::_PerformClipping<ClipperMode_InterpolateFull>(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
template void Render3D::_PerformClipping<ClipperMode_DetermineClipOnly>(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
template Render3D_SIMD<16>::Render3D_SIMD();
template Render3D_SIMD<32>::Render3D_SIMD();

View File

@ -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<ClipperMode CLIPPERMODE> void _PerformClipping(const VERT *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
template<bool ISCOLORBLANK, bool ISDEPTHBLANK> 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;
};