mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-09 23:01:51 +00:00
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
4 changed files with 88 additions and 24 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue