mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-22 03:41:45 +00:00
Optimize polygon sorting on batch renderer
This commit is contained in:
parent
35b6b21562
commit
636b3ab954
2 changed files with 25 additions and 82 deletions
|
@ -116,8 +116,30 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||||
polygonArray[polygonArraySize].texture = current_texture;
|
polygonArray[polygonArraySize].texture = current_texture;
|
||||||
polygonArray[polygonArraySize].shader = shader;
|
polygonArray[polygonArraySize].shader = shader;
|
||||||
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
||||||
|
polygonArray[polygonArraySize].hash = 0;
|
||||||
polygonArraySize++;
|
polygonArraySize++;
|
||||||
|
|
||||||
|
if (!(PolyFlags & PF_NoTexture) && !horizonSpecial)
|
||||||
|
{
|
||||||
|
// use FNV-1a to hash polygons for later sorting.
|
||||||
|
int32_t hash = 0x811c9dc5;
|
||||||
|
#define DIGEST(h, x) h ^= (x); h *= 0x01000193
|
||||||
|
DIGEST(hash, current_texture->downloaded);
|
||||||
|
DIGEST(hash, PolyFlags);
|
||||||
|
DIGEST(hash, pSurf->PolyColor.rgba);
|
||||||
|
if (cv_glshaders.value && gl_shadersavailable)
|
||||||
|
{
|
||||||
|
DIGEST(hash, shader);
|
||||||
|
DIGEST(hash, pSurf->TintColor.rgba);
|
||||||
|
DIGEST(hash, pSurf->FadeColor.rgba);
|
||||||
|
DIGEST(hash, pSurf->LightInfo.light_level);
|
||||||
|
DIGEST(hash, pSurf->LightInfo.fade_start);
|
||||||
|
DIGEST(hash, pSurf->LightInfo.fade_end);
|
||||||
|
}
|
||||||
|
#undef DIGEST
|
||||||
|
polygonArray[polygonArraySize-1].hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
|
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
|
||||||
unsortedVertexArraySize += iNumPts;
|
unsortedVertexArraySize += iNumPts;
|
||||||
}
|
}
|
||||||
|
@ -135,84 +157,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||||
unsigned int index2 = *(const unsigned int*)p2;
|
unsigned int index2 = *(const unsigned int*)p2;
|
||||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||||
int diff;
|
return poly1->hash - poly2->hash;
|
||||||
INT64 diff64;
|
|
||||||
UINT32 downloaded1 = 0;
|
|
||||||
UINT32 downloaded2 = 0;
|
|
||||||
|
|
||||||
int shader1 = poly1->shader;
|
|
||||||
int shader2 = poly2->shader;
|
|
||||||
// make skywalls and horizon lines first in order
|
|
||||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
|
||||||
shader1 = -1;
|
|
||||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
|
||||||
shader2 = -1;
|
|
||||||
diff = shader1 - shader2;
|
|
||||||
if (diff != 0) return diff;
|
|
||||||
|
|
||||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
|
||||||
if (shader1 == -1 && shader2 == -1)
|
|
||||||
return index1 - index2;
|
|
||||||
|
|
||||||
if (poly1->texture)
|
|
||||||
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
|
|
||||||
if (poly2->texture)
|
|
||||||
downloaded2 = poly2->texture->downloaded;
|
|
||||||
diff64 = downloaded1 - downloaded2;
|
|
||||||
if (diff64 != 0) return diff64;
|
|
||||||
|
|
||||||
diff = poly1->polyFlags - poly2->polyFlags;
|
|
||||||
if (diff != 0) return diff;
|
|
||||||
|
|
||||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
|
||||||
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
|
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
|
||||||
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
|
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
|
||||||
|
|
||||||
diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level;
|
|
||||||
if (diff != 0) return diff;
|
|
||||||
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
|
|
||||||
if (diff != 0) return diff;
|
|
||||||
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
|
||||||
{
|
|
||||||
unsigned int index1 = *(const unsigned int*)p1;
|
|
||||||
unsigned int index2 = *(const unsigned int*)p2;
|
|
||||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
|
||||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
|
||||||
int diff;
|
|
||||||
INT64 diff64;
|
|
||||||
|
|
||||||
GLMipmap_t *texture1 = poly1->texture;
|
|
||||||
GLMipmap_t *texture2 = poly2->texture;
|
|
||||||
UINT32 downloaded1 = 0;
|
|
||||||
UINT32 downloaded2 = 0;
|
|
||||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
|
||||||
texture1 = NULL;
|
|
||||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
|
||||||
texture2 = NULL;
|
|
||||||
if (texture1)
|
|
||||||
downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons
|
|
||||||
if (texture2)
|
|
||||||
downloaded2 = texture2->downloaded;
|
|
||||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
|
||||||
if (!texture1 && !texture2)
|
|
||||||
return index1 - index2;
|
|
||||||
diff64 = downloaded1 - downloaded2;
|
|
||||||
if (diff64 != 0) return diff64;
|
|
||||||
|
|
||||||
diff = poly1->polyFlags - poly2->polyFlags;
|
|
||||||
if (diff != 0) return diff;
|
|
||||||
|
|
||||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
|
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
|
||||||
|
@ -263,10 +208,7 @@ void HWR_RenderBatches(void)
|
||||||
|
|
||||||
// sort polygons
|
// sort polygons
|
||||||
PS_START_TIMING(ps_hw_batchsorttime);
|
PS_START_TIMING(ps_hw_batchsorttime);
|
||||||
if (cv_glshaders.value && gl_shadersavailable)
|
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
|
||||||
else
|
|
||||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
|
|
||||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||||
// sort order
|
// sort order
|
||||||
// 1. shader
|
// 1. shader
|
||||||
|
|
|
@ -26,6 +26,7 @@ typedef struct
|
||||||
int shader;
|
int shader;
|
||||||
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
|
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
|
||||||
boolean horizonSpecial;
|
boolean horizonSpecial;
|
||||||
|
uint32_t hash;
|
||||||
} PolygonArrayEntry;
|
} PolygonArrayEntry;
|
||||||
|
|
||||||
void HWR_StartBatching(void);
|
void HWR_StartBatching(void);
|
||||||
|
|
Loading…
Reference in a new issue