void RAS_InstancingBuffer::Realloc(unsigned int size) { if (m_vbo) { GPU_buffer_free(m_vbo); } m_vbo = GPU_buffer_alloc(m_stride * size); }
/* confusion: code in cdderivedmesh calls both GPU_color_setup and GPU_color3_upload; both of these set the `colors' buffer, so seems like it will just needlessly overwrite? --nicholas */ void GPU_color3_upload(DerivedMesh *dm, unsigned char *data) { if(dm->drawObject == 0) dm->drawObject = GPU_drawobject_new(dm); GPU_buffer_free(dm->drawObject->colors); dm->drawObject->colors = gpu_buffer_setup(dm, dm->drawObject, 3, sizeof(char)*3*dm->drawObject->tot_triangle_point, GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color3); }
void GPU_drawobject_free(DerivedMesh *dm) { GPUDrawObject *gdo; if(!dm || !(gdo = dm->drawObject)) return; MEM_freeN(gdo->materials); MEM_freeN(gdo->triangle_to_mface); MEM_freeN(gdo->vert_points); MEM_freeN(gdo->vert_points_mem); GPU_buffer_free(gdo->points); GPU_buffer_free(gdo->normals); GPU_buffer_free(gdo->uv); GPU_buffer_free(gdo->colors); GPU_buffer_free(gdo->edges); GPU_buffer_free(gdo->uvedges); MEM_freeN(gdo); dm->drawObject = NULL; }
RAS_InstancingBuffer::~RAS_InstancingBuffer() { if (m_vbo) { GPU_buffer_free(m_vbo); } }
static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, int vector_size, int size, GLenum target, void *user, GPUBufferCopyFunc copy_f) { GPUBufferPool *pool; GPUBuffer *buffer; float *varray; int mat_orig_to_new[MAX_MATERIALS]; int *cur_index_per_mat; int i; int success; GLboolean uploaded; pool = gpu_get_global_buffer_pool(); /* alloc a GPUBuffer; fall back to legacy mode on failure */ if(!(buffer = GPU_buffer_alloc(size))) dm->drawObject->legacy = 1; /* nothing to do for legacy mode */ if(dm->drawObject->legacy) return 0; cur_index_per_mat = MEM_mallocN(sizeof(int)*object->totmaterial, "GPU_buffer_setup.cur_index_per_mat"); for(i = 0; i < object->totmaterial; i++) { /* for each material, the current index to copy data to */ cur_index_per_mat[i] = object->materials[i].start * vector_size; /* map from original material index to new GPUBufferMaterial index */ mat_orig_to_new[object->materials[i].mat_nr] = i; } if(useVBOs) { success = 0; while(!success) { /* bind the buffer and discard previous data, avoids stalling gpu */ glBindBufferARB(target, buffer->id); glBufferDataARB(target, buffer->size, 0, GL_STATIC_DRAW_ARB); /* attempt to map the buffer */ if(!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) { /* failed to map the buffer; delete it */ GPU_buffer_free(buffer); gpu_buffer_pool_delete_last(pool); buffer= NULL; /* try freeing an entry from the pool and reallocating the buffer */ if(pool->totbuf > 0) { gpu_buffer_pool_delete_last(pool); buffer = GPU_buffer_alloc(size); } /* allocation still failed; fall back to legacy mode */ if(!buffer) { dm->drawObject->legacy = 1; success = 1; } } else { success = 1; } } /* check legacy fallback didn't happen */ if(dm->drawObject->legacy == 0) { uploaded = GL_FALSE; /* attempt to upload the data to the VBO */ while(uploaded == GL_FALSE) { (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user); /* glUnmapBuffer returns GL_FALSE if the data store is corrupted; retry in that case */ uploaded = glUnmapBufferARB(target); } } glBindBufferARB(target, 0); } else { /* VBO not supported, use vertex array fallback */ if(buffer->pointer) { varray = buffer->pointer; (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user); } else { dm->drawObject->legacy = 1; } } MEM_freeN(cur_index_per_mat); return buffer; }