if (gl_state.preparevertices_tempdata)
Mem_Free(gl_state.preparevertices_tempdata);
- if (gl_state.preparevertices_dynamicvertexbuffer)
- R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+ gl_state.framebufferobject = 0; // GL unbinds it for us
qglDeleteFramebuffers(1, (GLuint*)&temp);
temp = 0;
}
if (status != GL_FRAMEBUFFER_COMPLETE)
{
Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+ gl_state.framebufferobject = 0; // GL unbinds it for us
qglDeleteFramebuffers(1, (GLuint*)&temp);
temp = 0;
}
case RENDERPATH_GLES1:
case RENDERPATH_GLES2:
if (fbo)
+ {
+ // GL clears the binding if we delete something bound
+ if (gl_state.framebufferobject == fbo)
+ gl_state.framebufferobject = 0;
qglDeleteFramebuffers(1, (GLuint*)&fbo);
+ }
break;
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
memset(buffer, 0, sizeof(*buffer));
buffer->bufferobject = 0;
buffer->devicebuffer = NULL;
- buffer->size = 0;
+ buffer->size = size;
buffer->isindexbuffer = isindexbuffer;
buffer->isuniformbuffer = isuniformbuffer;
buffer->isdynamic = isdynamic;
r_refdef.stats[r_stat_vertexbufferuploadcount]++;
r_refdef.stats[r_stat_vertexbufferuploadsize] += size;
}
+ if (!subdata)
+ buffer->size = size;
switch(vid.renderpath)
{
case RENDERPATH_GL11:
case RENDERPATH_GL20:
case RENDERPATH_GLES1:
case RENDERPATH_GLES2:
+ // GL clears the binding if we delete something bound
+ if (gl_state.uniformbufferobject == buffer->bufferobject)
+ gl_state.uniformbufferobject = 0;
+ if (gl_state.vertexbufferobject == buffer->bufferobject)
+ gl_state.vertexbufferobject = 0;
+ if (gl_state.elementbufferobject == buffer->bufferobject)
+ gl_state.elementbufferobject = 0;
qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
break;
case RENDERPATH_D3D9:
Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
}
+static const char *buffertypename[R_BUFFERDATA_COUNT] = {"vertex", "index16", "index32", "uniform"};
void GL_Mesh_ListVBOs(qboolean printeach)
{
int i, endindex;
- size_t ebocount = 0, ebomemory = 0;
- size_t vbocount = 0, vbomemory = 0;
+ int type;
+ int isdynamic;
+ int index16count, index16mem;
+ int index32count, index32mem;
+ int vertexcount, vertexmem;
+ int uniformcount, uniformmem;
+ int totalcount, totalmem;
+ size_t bufferstat[R_BUFFERDATA_COUNT][2][2];
r_meshbuffer_t *buffer;
+ memset(bufferstat, 0, sizeof(bufferstat));
endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
for (i = 0;i < endindex;i++)
{
buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
if (!buffer)
continue;
- if (buffer->isindexbuffer) {ebocount++;ebomemory += buffer->size;if (printeach) Con_Printf("indexbuffer #%i %s = %i bytes%s\n", i, buffer->name, (int)buffer->size, buffer->isdynamic ? " (dynamic)" : " (static)");}
- else {vbocount++;vbomemory += buffer->size;if (printeach) Con_Printf("vertexbuffer #%i %s = %i bytes%s\n", i, buffer->name, (int)buffer->size, buffer->isdynamic ? " (dynamic)" : " (static)");}
+ if (buffer->isuniformbuffer)
+ type = R_BUFFERDATA_UNIFORM;
+ else if (buffer->isindexbuffer && buffer->isindex16)
+ type = R_BUFFERDATA_INDEX16;
+ else if (buffer->isindexbuffer)
+ type = R_BUFFERDATA_INDEX32;
+ else
+ type = R_BUFFERDATA_VERTEX;
+ isdynamic = buffer->isdynamic;
+ bufferstat[type][isdynamic][0]++;
+ bufferstat[type][isdynamic][1] += buffer->size;
+ if (printeach)
+ Con_Printf("buffer #%i %s = %i bytes (%s %s)\n", i, buffer->name, (int)buffer->size, isdynamic ? "dynamic" : "static", buffertypename[type]);
}
- Con_Printf("vertex buffers: %i indexbuffers totalling %i bytes (%.3f MB), %i vertexbuffers totalling %i bytes (%.3f MB), combined %i bytes (%.3fMB)\n", (int)ebocount, (int)ebomemory, ebomemory / 1048576.0, (int)vbocount, (int)vbomemory, vbomemory / 1048576.0, (int)(ebomemory + vbomemory), (ebomemory + vbomemory) / 1048576.0);
+ index16count = (int)(bufferstat[R_BUFFERDATA_INDEX16][0][0] + bufferstat[R_BUFFERDATA_INDEX16][1][0]);
+ index16mem = (int)(bufferstat[R_BUFFERDATA_INDEX16][0][1] + bufferstat[R_BUFFERDATA_INDEX16][1][1]);
+ index32count = (int)(bufferstat[R_BUFFERDATA_INDEX32][0][0] + bufferstat[R_BUFFERDATA_INDEX32][1][0]);
+ index32mem = (int)(bufferstat[R_BUFFERDATA_INDEX32][0][1] + bufferstat[R_BUFFERDATA_INDEX32][1][1]);
+ vertexcount = (int)(bufferstat[R_BUFFERDATA_VERTEX ][0][0] + bufferstat[R_BUFFERDATA_VERTEX ][1][0]);
+ vertexmem = (int)(bufferstat[R_BUFFERDATA_VERTEX ][0][1] + bufferstat[R_BUFFERDATA_VERTEX ][1][1]);
+ uniformcount = (int)(bufferstat[R_BUFFERDATA_UNIFORM][0][0] + bufferstat[R_BUFFERDATA_UNIFORM][1][0]);
+ uniformmem = (int)(bufferstat[R_BUFFERDATA_UNIFORM][0][1] + bufferstat[R_BUFFERDATA_UNIFORM][1][1]);
+ totalcount = index16count + index32count + vertexcount + uniformcount;
+ totalmem = index16mem + index32mem + vertexmem + uniformmem;
+ Con_Printf("%i 16bit indexbuffers totalling %i bytes (%.3f MB)\n%i 32bit indexbuffers totalling %i bytes (%.3f MB)\n%i vertexbuffers totalling %i bytes (%.3f MB)\n%i uniformbuffers totalling %i bytes (%.3f MB)\ncombined %i buffers totalling %i bytes (%.3fMB)\n", index16count, index16mem, index16mem / 10248576.0, index32count, index32mem, index32mem / 10248576.0, vertexcount, vertexmem, vertexmem / 10248576.0, uniformcount, uniformmem, uniformmem / 10248576.0, totalcount, totalmem, totalmem / 10248576.0);
}
R_SortEntities();
R_AnimCache_ClearCache();
- R_FrameData_NewFrame();
- R_BufferData_NewFrame();
/* adjust for stereo display */
if(R_Stereo_Active())
rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
}
// upload buffer data for the copytriangles batch
- if (vid.forcevbo || (r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object))
+ if ((r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
{
if (rsurface.batchelement3s)
rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
}
// upload buffer data for the dynamic batch
- if (vid.forcevbo || (r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object))
+ if ((r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
{
if (rsurface.batchvertexmesh)
rsurface.batchvertexmesh_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(r_vertexmesh_t), rsurface.batchvertexmesh, R_BUFFERDATA_VERTEX, &rsurface.batchvertexmesh_bufferoffset);
rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
if (rsurface.batchnormal3f)
rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
- if (rsurface.batchlightmapcolor4f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
+ if (rsurface.batchlightmapcolor4f)
rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
- if (rsurface.batchtexcoordtexture2f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
+ if (rsurface.batchtexcoordtexture2f)
rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
- if (rsurface.batchtexcoordlightmap2f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
+ if (rsurface.batchtexcoordlightmap2f)
rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
if (rsurface.batchskeletalindex4ub)
rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);