another attempt at fixing the VBO buffer deletion bugs

This commit is contained in:
2010-02-17 18:48:02 +00:00
parent 3c2d59e032
commit 1a6f683b43
2 changed files with 32 additions and 42 deletions

View File

@@ -42,6 +42,12 @@
#define DEBUG_VBO(X)
#endif
#ifdef _DEBUG
#define ERROR_VBO(X) printf(X)
#else
#define ERROR_VBO(X)
#endif
struct DerivedMesh;
struct GHash;
@@ -64,10 +70,6 @@ typedef struct GPUBuffer
typedef struct GPUBufferPool
{
int size; /* number of allocated buffers stored */
int start; /* for a queue like structure */
/* when running out of space for storing buffers,
the last one used will be thrown away */
GPUBuffer* buffers[MAX_FREE_GPU_BUFFERS];
} GPUBufferPool;

View File

@@ -88,7 +88,7 @@ GPUBufferPool *GPU_buffer_pool_new()
void GPU_buffer_pool_free(GPUBufferPool *pool)
{
int i, index;
int i;
DEBUG_VBO("GPU_buffer_pool_free\n");
@@ -97,21 +97,17 @@ void GPU_buffer_pool_free(GPUBufferPool *pool)
if( pool == 0 )
return;
while( pool->start < 0 )
pool->start += MAX_FREE_GPU_BUFFERS;
for( i = 0; i < pool->size; i++ ) {
index = (pool->start+i)%MAX_FREE_GPU_BUFFERS;
if( pool->buffers[index] != 0 ) {
if( pool->buffers[i] != 0 ) {
if( useVBOs ) {
glDeleteBuffersARB( 1, &pool->buffers[index]->id );
glDeleteBuffersARB( 1, &pool->buffers[i]->id );
}
else {
MEM_freeN( pool->buffers[index]->pointer );
MEM_freeN( pool->buffers[i]->pointer );
}
MEM_freeN(pool->buffers[index]);
MEM_freeN(pool->buffers[i]);
} else {
DEBUG_VBO("Why are we accessing a null buffer?\n");
ERROR_VBO("Why are we accessing a null buffer in GPU_buffer_pool_free?\n");
}
}
MEM_freeN(pool);
@@ -121,15 +117,17 @@ void GPU_buffer_pool_remove( int index, GPUBufferPool *pool )
{
int i;
if( index >= pool->size || index < 0 ) {
ERROR_VBO("Wrong index, out of bounds in call to GPU_buffer_pool_remove");
return;
}
DEBUG_VBO("GPU_buffer_pool_remove\n");
while( pool->start < 0 )
pool->start += MAX_FREE_GPU_BUFFERS;
for( i = index; i < pool->size; i++ ) {
pool->buffers[(pool->start+i)%MAX_FREE_GPU_BUFFERS] = pool->buffers[(pool->start+i+1)%MAX_FREE_GPU_BUFFERS];
for( i = index; i < pool->size-1; i++ ) {
pool->buffers[i] = pool->buffers[i+1];
}
if( pool->size < MAX_FREE_GPU_BUFFERS )
pool->buffers[(pool->start+pool->size)%MAX_FREE_GPU_BUFFERS] = 0;
if( pool->size > 0 )
pool->buffers[pool->size-1] = 0;
pool->size--;
}
@@ -140,13 +138,10 @@ void GPU_buffer_pool_delete_last( GPUBufferPool *pool )
DEBUG_VBO("GPU_buffer_pool_delete_last\n");
if( pool->size == 0 )
if( pool->size <= 0 )
return;
last = pool->start+pool->size-1;
while( last < 0 )
last += MAX_FREE_GPU_BUFFERS;
last = last%MAX_FREE_GPU_BUFFERS;
last = pool->size-1;
if( pool->buffers[last] != 0 ) {
if( useVBOs ) {
@@ -180,14 +175,10 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
pool = globalPool;
}
while( pool->start < 0 )
pool->start += MAX_FREE_GPU_BUFFERS;
for( i = 0; i < pool->size; i++ ) {
int actuali = (pool->start+i)%MAX_FREE_GPU_BUFFERS;
cursize = pool->buffers[actuali]->size;
cursize = pool->buffers[i]->size;
if( cursize == size ) {
allocated = pool->buffers[actuali];
allocated = pool->buffers[i];
GPU_buffer_pool_remove(i,pool);
DEBUG_VBO("free buffer of exact size found\n");
return allocated;
@@ -195,7 +186,7 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
/* smaller buffers won't fit data and buffers at least twice as big are a waste of memory */
else if( cursize > size && size > cursize/2 ) {
/* is it closer to the required size than the last appropriate buffer found. try to save memory */
if( bestfit == -1 || pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS]->size > cursize ) {
if( bestfit == -1 || pool->buffers[bestfit]->size > cursize ) {
bestfit = i;
}
}
@@ -223,10 +214,10 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
}
}
else {
sprintf(buffer,"free buffer found. Wasted %d bytes\n", pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS]->size-size);
sprintf(buffer,"free buffer found. Wasted %d bytes\n", pool->buffers[bestfit]->size-size);
DEBUG_VBO(buffer);
allocated = pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS];
allocated = pool->buffers[bestfit];
GPU_buffer_pool_remove(bestfit,pool);
}
return allocated;
@@ -234,8 +225,7 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool )
{
int place;
int i;
DEBUG_VBO("GPU_buffer_free\n");
if( buffer == 0 )
@@ -245,18 +235,16 @@ void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool )
if( pool == 0 )
globalPool = GPU_buffer_pool_new();
while( pool->start < 0 )
pool->start += MAX_FREE_GPU_BUFFERS;
/* free the last used buffer in the queue if no more space */
if( pool->size == MAX_FREE_GPU_BUFFERS ) {
GPU_buffer_pool_delete_last( pool );
}
place = (pool->start + pool->size)%MAX_FREE_GPU_BUFFERS;
for( i =pool->size; i > 0; i-- ) {
pool->buffers[i] = pool->buffers[i-1];
}
pool->buffers[0] = buffer;
pool->size++;
pool->buffers[place] = buffer;
}
GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm )