OpenGL2: Add run-time support for unsigned short indexes

OpenGL ES 2 is only required to support unsigned short for indexes.
This commit is contained in:
Zack Middleton 2024-06-05 21:34:36 -05:00
parent 3b984d2b51
commit b25a3c6e4d
4 changed files with 88 additions and 24 deletions

View file

@ -45,6 +45,17 @@ void GLimp_InitExtraExtensions(void)
if (strstr((char *)qglGetString(GL_RENDERER), "Intel"))
glRefConfig.intelGraphics = qtrue;
if (qglesMajorVersion)
{
glRefConfig.vaoCacheGlIndexType = GL_UNSIGNED_SHORT;
glRefConfig.vaoCacheGlIndexSize = sizeof(unsigned short);
}
else
{
glRefConfig.vaoCacheGlIndexType = GL_UNSIGNED_INT;
glRefConfig.vaoCacheGlIndexSize = sizeof(unsigned int);
}
// set DSA fallbacks
#define GLE(ret, name, ...) qgl##name = GLDSA_##name;
QGL_EXT_direct_state_access_PROCS;
@ -124,6 +135,19 @@ void GLimp_InitExtraExtensions(void)
ri.Printf(PRINT_ALL, result[2], extension);
}
// GL_OES_element_index_uint
extension = "GL_OES_element_index_uint";
if (SDL_GL_ExtensionSupported(extension))
{
glRefConfig.vaoCacheGlIndexType = GL_UNSIGNED_INT;
glRefConfig.vaoCacheGlIndexSize = sizeof(unsigned int);
ri.Printf(PRINT_ALL, result[1], extension);
}
else
{
ri.Printf(PRINT_ALL, result[2], extension);
}
goto done;
}

View file

@ -49,8 +49,10 @@ QGL_ARB_vertex_array_object_PROCS;
QGL_EXT_direct_state_access_PROCS;
#undef GLE
#define GL_INDEX_TYPE GL_UNSIGNED_INT
typedef unsigned int glIndex_t;
#define GL_INDEX_TYPE GL_UNSIGNED_SHORT
typedef unsigned short glIndex_t;
typedef unsigned int vaoCacheGlIndex_t;
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
@ -1431,6 +1433,9 @@ typedef struct {
qboolean vertexArrayObject;
qboolean directStateAccess;
GLenum vaoCacheGlIndexType; // GL_UNSIGNED_INT or GL_UNSIGNED_SHORT
size_t vaoCacheGlIndexSize; // must be <= sizeof( vaoCacheGlIndex_t )
// OpenGL ES extensions
qboolean readDepth;
qboolean readStencil;
@ -2220,6 +2225,7 @@ void R_VaoList_f(void);
void RB_UpdateTessVao(unsigned int attribBits);
void VaoCache_Commit(void);
void VaoCache_DrawElements(int numIndexes, int firstIndex);
void VaoCache_Init(void);
void VaoCache_BindVao(void);
void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboolean *recycleIndexBuffer, int numVerts, int numIndexes);

View file

@ -40,7 +40,14 @@ R_DrawElements
void R_DrawElements( int numIndexes, int firstIndex )
{
qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
if (tess.useCacheVao)
{
VaoCache_DrawElements(numIndexes, firstIndex);
}
else
{
qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
}
}
@ -1720,6 +1727,8 @@ void RB_EndSurface( void ) {
tess.numIndexes = 0;
tess.numVertexes = 0;
tess.firstIndex = 0;
tess.useCacheVao = qfalse;
tess.useInternalVao = qfalse;
GLimp_LogComment( "----------\n" );
}

View file

@ -676,7 +676,7 @@ static struct
srfVert_t vertexes[VAOCACHE_QUEUE_MAX_VERTEXES];
int vertexCommitSize;
glIndex_t indexes[VAOCACHE_QUEUE_MAX_INDEXES];
vaoCacheGlIndex_t indexes[VAOCACHE_QUEUE_MAX_INDEXES];
int indexCommitSize;
}
vcq;
@ -687,18 +687,13 @@ vcq;
// srfVert_t is 60 bytes
// assuming each vert is referenced 4 times, need 16 bytes (4 glIndex_t) per vert
// -> need about 4/15ths the space for indexes as vertexes
#if GL_INDEX_TYPE == GL_UNSIGNED_SHORT
#define VAOCACHE_VERTEX_BUFFER_SIZE (sizeof(srfVert_t) * USHRT_MAX)
#define VAOCACHE_INDEX_BUFFER_SIZE (sizeof(glIndex_t) * USHRT_MAX * 4)
#else // GL_UNSIGNED_INT
#define VAOCACHE_VERTEX_BUFFER_SIZE (16 * 1024 * 1024)
#define VAOCACHE_INDEX_BUFFER_SIZE (5 * 1024 * 1024)
#endif
typedef struct buffered_s
{
void *data;
int size;
glIndex_t *indexes;
int numIndexes;
int bufferOffset;
}
buffered_t;
@ -736,7 +731,7 @@ void VaoCache_Commit(void)
buffered_t *indexSet2 = indexSet;
for (surf = vcq.surfaces; surf < end; surf++, indexSet2++)
{
if (surf->indexes != indexSet2->data || (surf->numIndexes * sizeof(glIndex_t)) != indexSet2->size)
if (surf->indexes != indexSet2->indexes || surf->numIndexes != indexSet2->numIndexes)
break;
}
@ -750,7 +745,7 @@ void VaoCache_Commit(void)
// If found, use it
if (indexSet < vc.surfaceIndexSets + vc.numSurfaces)
{
tess.firstIndex = indexSet->bufferOffset / sizeof(glIndex_t);
tess.firstIndex = indexSet->bufferOffset / glRefConfig.vaoCacheGlIndexSize;
//ri.Printf(PRINT_ALL, "firstIndex %d numIndexes %d as %d\n", tess.firstIndex, tess.numIndexes, (int)(batchLength - vc.batchLengths));
//ri.Printf(PRINT_ALL, "vc.numSurfaces %d vc.numBatches %d\n", vc.numSurfaces, vc.numBatches);
}
@ -759,20 +754,21 @@ void VaoCache_Commit(void)
else
{
srfVert_t *dstVertex = vcq.vertexes;
glIndex_t *dstIndex = vcq.indexes;
vaoCacheGlIndex_t *dstIndex = vcq.indexes;
unsigned short *dstIndexUshort = (unsigned short *)vcq.indexes;
batchLength = vc.batchLengths + vc.numBatches;
*batchLength = vcq.numSurfaces;
vc.numBatches++;
tess.firstIndex = vc.indexOffset / sizeof(glIndex_t);
tess.firstIndex = vc.indexOffset / glRefConfig.vaoCacheGlIndexSize;
vcq.vertexCommitSize = 0;
vcq.indexCommitSize = 0;
for (surf = vcq.surfaces; surf < end; surf++)
{
glIndex_t *srcIndex = surf->indexes;
int vertexesSize = surf->numVerts * sizeof(srfVert_t);
int indexesSize = surf->numIndexes * sizeof(glIndex_t);
int indexesSize = surf->numIndexes * glRefConfig.vaoCacheGlIndexSize;
int i, indexOffset = (vc.vertexOffset + vcq.vertexCommitSize) / sizeof(srfVert_t);
Com_Memcpy(dstVertex, surf->vertexes, vertexesSize);
@ -781,13 +777,21 @@ void VaoCache_Commit(void)
vcq.vertexCommitSize += vertexesSize;
indexSet = vc.surfaceIndexSets + vc.numSurfaces;
indexSet->data = surf->indexes;
indexSet->size = indexesSize;
indexSet->indexes = surf->indexes;
indexSet->numIndexes = surf->numIndexes;
indexSet->bufferOffset = vc.indexOffset + vcq.indexCommitSize;
vc.numSurfaces++;
for (i = 0; i < surf->numIndexes; i++)
*dstIndex++ = *srcIndex++ + indexOffset;
if (glRefConfig.vaoCacheGlIndexType == GL_UNSIGNED_SHORT)
{
for (i = 0; i < surf->numIndexes; i++)
*dstIndexUshort++ = *srcIndex++ + indexOffset;
}
else
{
for (i = 0; i < surf->numIndexes; i++)
*dstIndex++ = *srcIndex++ + indexOffset;
}
vcq.indexCommitSize += indexesSize;
}
@ -810,9 +814,30 @@ void VaoCache_Commit(void)
}
}
void VaoCache_DrawElements(int numIndexes, int firstIndex)
{
assert( glState.currentVao == vc.vao );
qglDrawElements(GL_TRIANGLES, numIndexes, glRefConfig.vaoCacheGlIndexType, BUFFER_OFFSET(firstIndex * glRefConfig.vaoCacheGlIndexSize));
}
void VaoCache_Init(void)
{
vc.vao = R_CreateVao("VaoCache", NULL, VAOCACHE_VERTEX_BUFFER_SIZE, NULL, VAOCACHE_INDEX_BUFFER_SIZE, VAO_USAGE_DYNAMIC);
int vertexBufferSize;
int indexBufferSize;
if (glRefConfig.vaoCacheGlIndexType == GL_UNSIGNED_SHORT)
{
vertexBufferSize = sizeof(srfVert_t) * USHRT_MAX;
indexBufferSize = sizeof(unsigned short) * USHRT_MAX * 4;
}
else
{
vertexBufferSize = VAOCACHE_VERTEX_BUFFER_SIZE;
indexBufferSize = VAOCACHE_INDEX_BUFFER_SIZE;
}
vc.vao = R_CreateVao("VaoCache", NULL, vertexBufferSize, NULL, indexBufferSize, VAO_USAGE_DYNAMIC);
vc.vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
vc.vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
@ -881,7 +906,7 @@ void VaoCache_BindVao(void)
void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboolean *recycleIndexBuffer, int numVerts, int numIndexes)
{
int vertexesSize = sizeof(srfVert_t) * numVerts;
int indexesSize = sizeof(glIndex_t) * numIndexes;
int indexesSize = glRefConfig.vaoCacheGlIndexSize * numIndexes;
if (vc.vao->vertexesSize < vc.vertexOffset + vcq.vertexCommitSize + vertexesSize)
{
@ -924,7 +949,7 @@ void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboo
*endSurface = qtrue;
}
if (VAOCACHE_QUEUE_MAX_INDEXES * sizeof(glIndex_t) < vcq.indexCommitSize + indexesSize)
if (VAOCACHE_QUEUE_MAX_INDEXES * glRefConfig.vaoCacheGlIndexSize < vcq.indexCommitSize + indexesSize)
{
//ri.Printf(PRINT_ALL, "out of queued indexes\n");
*endSurface = qtrue;
@ -964,5 +989,5 @@ void VaoCache_AddSurface(srfVert_t *verts, int numVerts, glIndex_t *indexes, int
vcq.numSurfaces++;
vcq.vertexCommitSize += sizeof(srfVert_t) * numVerts;
vcq.indexCommitSize += sizeof(glIndex_t) * numIndexes;
vcq.indexCommitSize += glRefConfig.vaoCacheGlIndexSize * numIndexes;
}