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:
parent
3b984d2b51
commit
b25a3c6e4d
|
|
@ -45,6 +45,17 @@ void GLimp_InitExtraExtensions(void)
|
||||||
if (strstr((char *)qglGetString(GL_RENDERER), "Intel"))
|
if (strstr((char *)qglGetString(GL_RENDERER), "Intel"))
|
||||||
glRefConfig.intelGraphics = qtrue;
|
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
|
// set DSA fallbacks
|
||||||
#define GLE(ret, name, ...) qgl##name = GLDSA_##name;
|
#define GLE(ret, name, ...) qgl##name = GLDSA_##name;
|
||||||
QGL_EXT_direct_state_access_PROCS;
|
QGL_EXT_direct_state_access_PROCS;
|
||||||
|
|
@ -124,6 +135,19 @@ void GLimp_InitExtraExtensions(void)
|
||||||
ri.Printf(PRINT_ALL, result[2], extension);
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,10 @@ QGL_ARB_vertex_array_object_PROCS;
|
||||||
QGL_EXT_direct_state_access_PROCS;
|
QGL_EXT_direct_state_access_PROCS;
|
||||||
#undef GLE
|
#undef GLE
|
||||||
|
|
||||||
#define GL_INDEX_TYPE GL_UNSIGNED_INT
|
#define GL_INDEX_TYPE GL_UNSIGNED_SHORT
|
||||||
typedef unsigned int glIndex_t;
|
typedef unsigned short glIndex_t;
|
||||||
|
|
||||||
|
typedef unsigned int vaoCacheGlIndex_t;
|
||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||||
|
|
||||||
|
|
@ -1431,6 +1433,9 @@ typedef struct {
|
||||||
qboolean vertexArrayObject;
|
qboolean vertexArrayObject;
|
||||||
qboolean directStateAccess;
|
qboolean directStateAccess;
|
||||||
|
|
||||||
|
GLenum vaoCacheGlIndexType; // GL_UNSIGNED_INT or GL_UNSIGNED_SHORT
|
||||||
|
size_t vaoCacheGlIndexSize; // must be <= sizeof( vaoCacheGlIndex_t )
|
||||||
|
|
||||||
// OpenGL ES extensions
|
// OpenGL ES extensions
|
||||||
qboolean readDepth;
|
qboolean readDepth;
|
||||||
qboolean readStencil;
|
qboolean readStencil;
|
||||||
|
|
@ -2220,6 +2225,7 @@ void R_VaoList_f(void);
|
||||||
void RB_UpdateTessVao(unsigned int attribBits);
|
void RB_UpdateTessVao(unsigned int attribBits);
|
||||||
|
|
||||||
void VaoCache_Commit(void);
|
void VaoCache_Commit(void);
|
||||||
|
void VaoCache_DrawElements(int numIndexes, int firstIndex);
|
||||||
void VaoCache_Init(void);
|
void VaoCache_Init(void);
|
||||||
void VaoCache_BindVao(void);
|
void VaoCache_BindVao(void);
|
||||||
void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboolean *recycleIndexBuffer, int numVerts, int numIndexes);
|
void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboolean *recycleIndexBuffer, int numVerts, int numIndexes);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,14 @@ R_DrawElements
|
||||||
|
|
||||||
void R_DrawElements( int numIndexes, int firstIndex )
|
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.numIndexes = 0;
|
||||||
tess.numVertexes = 0;
|
tess.numVertexes = 0;
|
||||||
tess.firstIndex = 0;
|
tess.firstIndex = 0;
|
||||||
|
tess.useCacheVao = qfalse;
|
||||||
|
tess.useInternalVao = qfalse;
|
||||||
|
|
||||||
GLimp_LogComment( "----------\n" );
|
GLimp_LogComment( "----------\n" );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -676,7 +676,7 @@ static struct
|
||||||
srfVert_t vertexes[VAOCACHE_QUEUE_MAX_VERTEXES];
|
srfVert_t vertexes[VAOCACHE_QUEUE_MAX_VERTEXES];
|
||||||
int vertexCommitSize;
|
int vertexCommitSize;
|
||||||
|
|
||||||
glIndex_t indexes[VAOCACHE_QUEUE_MAX_INDEXES];
|
vaoCacheGlIndex_t indexes[VAOCACHE_QUEUE_MAX_INDEXES];
|
||||||
int indexCommitSize;
|
int indexCommitSize;
|
||||||
}
|
}
|
||||||
vcq;
|
vcq;
|
||||||
|
|
@ -687,18 +687,13 @@ vcq;
|
||||||
// srfVert_t is 60 bytes
|
// srfVert_t is 60 bytes
|
||||||
// assuming each vert is referenced 4 times, need 16 bytes (4 glIndex_t) per vert
|
// 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
|
// -> 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_VERTEX_BUFFER_SIZE (16 * 1024 * 1024)
|
||||||
#define VAOCACHE_INDEX_BUFFER_SIZE (5 * 1024 * 1024)
|
#define VAOCACHE_INDEX_BUFFER_SIZE (5 * 1024 * 1024)
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct buffered_s
|
typedef struct buffered_s
|
||||||
{
|
{
|
||||||
void *data;
|
glIndex_t *indexes;
|
||||||
int size;
|
int numIndexes;
|
||||||
int bufferOffset;
|
int bufferOffset;
|
||||||
}
|
}
|
||||||
buffered_t;
|
buffered_t;
|
||||||
|
|
@ -736,7 +731,7 @@ void VaoCache_Commit(void)
|
||||||
buffered_t *indexSet2 = indexSet;
|
buffered_t *indexSet2 = indexSet;
|
||||||
for (surf = vcq.surfaces; surf < end; surf++, indexSet2++)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -750,7 +745,7 @@ void VaoCache_Commit(void)
|
||||||
// If found, use it
|
// If found, use it
|
||||||
if (indexSet < vc.surfaceIndexSets + vc.numSurfaces)
|
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, "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);
|
//ri.Printf(PRINT_ALL, "vc.numSurfaces %d vc.numBatches %d\n", vc.numSurfaces, vc.numBatches);
|
||||||
}
|
}
|
||||||
|
|
@ -759,20 +754,21 @@ void VaoCache_Commit(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srfVert_t *dstVertex = vcq.vertexes;
|
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 = vc.batchLengths + vc.numBatches;
|
||||||
*batchLength = vcq.numSurfaces;
|
*batchLength = vcq.numSurfaces;
|
||||||
vc.numBatches++;
|
vc.numBatches++;
|
||||||
|
|
||||||
tess.firstIndex = vc.indexOffset / sizeof(glIndex_t);
|
tess.firstIndex = vc.indexOffset / glRefConfig.vaoCacheGlIndexSize;
|
||||||
vcq.vertexCommitSize = 0;
|
vcq.vertexCommitSize = 0;
|
||||||
vcq.indexCommitSize = 0;
|
vcq.indexCommitSize = 0;
|
||||||
for (surf = vcq.surfaces; surf < end; surf++)
|
for (surf = vcq.surfaces; surf < end; surf++)
|
||||||
{
|
{
|
||||||
glIndex_t *srcIndex = surf->indexes;
|
glIndex_t *srcIndex = surf->indexes;
|
||||||
int vertexesSize = surf->numVerts * sizeof(srfVert_t);
|
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);
|
int i, indexOffset = (vc.vertexOffset + vcq.vertexCommitSize) / sizeof(srfVert_t);
|
||||||
|
|
||||||
Com_Memcpy(dstVertex, surf->vertexes, vertexesSize);
|
Com_Memcpy(dstVertex, surf->vertexes, vertexesSize);
|
||||||
|
|
@ -781,13 +777,21 @@ void VaoCache_Commit(void)
|
||||||
vcq.vertexCommitSize += vertexesSize;
|
vcq.vertexCommitSize += vertexesSize;
|
||||||
|
|
||||||
indexSet = vc.surfaceIndexSets + vc.numSurfaces;
|
indexSet = vc.surfaceIndexSets + vc.numSurfaces;
|
||||||
indexSet->data = surf->indexes;
|
indexSet->indexes = surf->indexes;
|
||||||
indexSet->size = indexesSize;
|
indexSet->numIndexes = surf->numIndexes;
|
||||||
indexSet->bufferOffset = vc.indexOffset + vcq.indexCommitSize;
|
indexSet->bufferOffset = vc.indexOffset + vcq.indexCommitSize;
|
||||||
vc.numSurfaces++;
|
vc.numSurfaces++;
|
||||||
|
|
||||||
for (i = 0; i < surf->numIndexes; i++)
|
if (glRefConfig.vaoCacheGlIndexType == GL_UNSIGNED_SHORT)
|
||||||
*dstIndex++ = *srcIndex++ + indexOffset;
|
{
|
||||||
|
for (i = 0; i < surf->numIndexes; i++)
|
||||||
|
*dstIndexUshort++ = *srcIndex++ + indexOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < surf->numIndexes; i++)
|
||||||
|
*dstIndex++ = *srcIndex++ + indexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
vcq.indexCommitSize += indexesSize;
|
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)
|
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_POSITION].enabled = 1;
|
||||||
vc.vao->attribs[ATTR_INDEX_TEXCOORD].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)
|
void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboolean *recycleIndexBuffer, int numVerts, int numIndexes)
|
||||||
{
|
{
|
||||||
int vertexesSize = sizeof(srfVert_t) * numVerts;
|
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)
|
if (vc.vao->vertexesSize < vc.vertexOffset + vcq.vertexCommitSize + vertexesSize)
|
||||||
{
|
{
|
||||||
|
|
@ -924,7 +949,7 @@ void VaoCache_CheckAdd(qboolean *endSurface, qboolean *recycleVertexBuffer, qboo
|
||||||
*endSurface = qtrue;
|
*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");
|
//ri.Printf(PRINT_ALL, "out of queued indexes\n");
|
||||||
*endSurface = qtrue;
|
*endSurface = qtrue;
|
||||||
|
|
@ -964,5 +989,5 @@ void VaoCache_AddSurface(srfVert_t *verts, int numVerts, glIndex_t *indexes, int
|
||||||
vcq.numSurfaces++;
|
vcq.numSurfaces++;
|
||||||
|
|
||||||
vcq.vertexCommitSize += sizeof(srfVert_t) * numVerts;
|
vcq.vertexCommitSize += sizeof(srfVert_t) * numVerts;
|
||||||
vcq.indexCommitSize += sizeof(glIndex_t) * numIndexes;
|
vcq.indexCommitSize += glRefConfig.vaoCacheGlIndexSize * numIndexes;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user