GPU: Make changes to GPUIndexBuf and GPUVertBuf to allow multithreading
This is a small change. We delay all gl calls at the first use of the GPUIndexBuf / GPUVertBuf in order to be able to create multiple buffers from different threads without having many gl contexts.
This commit is contained in:
parent
a99eb0ca68
commit
33cc3344a2
|
@ -54,6 +54,7 @@ typedef struct GPUIndexBuf {
|
|||
uint base_index;
|
||||
#endif
|
||||
uint32_t ibo_id; /* 0 indicates not yet sent to VRAM */
|
||||
void *data; /* non-NULL indicates not yet sent to VRAM */
|
||||
bool use_prim_restart;
|
||||
} GPUIndexBuf;
|
||||
|
||||
|
|
|
@ -260,6 +260,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem)
|
|||
#endif
|
||||
elem->index_len = builder->index_len;
|
||||
elem->use_prim_restart = builder->use_prim_restart;
|
||||
elem->ibo_id = 0; /* Created at first use. */
|
||||
|
||||
#if GPU_TRACK_INDEX_RANGE
|
||||
uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index);
|
||||
|
@ -284,25 +285,31 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem)
|
|||
elem->gl_index_type = convert_index_type_to_gl(elem->index_type);
|
||||
#endif
|
||||
|
||||
if (elem->ibo_id == 0) {
|
||||
elem->ibo_id = GPU_buf_alloc();
|
||||
}
|
||||
/* send data to GPU */
|
||||
/* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound,
|
||||
* so we use the GL_ARRAY_BUFFER here to create a buffer without
|
||||
* interfering in the VAO state. */
|
||||
glBindBuffer(GL_ARRAY_BUFFER, elem->ibo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW);
|
||||
|
||||
/* discard builder (one-time use) */
|
||||
MEM_freeN(builder->data);
|
||||
/* Transfer data ownership to GPUIndexBuf.
|
||||
* It will be uploaded upon first use. */
|
||||
elem->data = builder->data;
|
||||
builder->data = NULL;
|
||||
/* other fields are safe to leave */
|
||||
}
|
||||
|
||||
static void indexbuf_upload_data(GPUIndexBuf *elem)
|
||||
{
|
||||
/* send data to GPU */
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), elem->data, GL_STATIC_DRAW);
|
||||
/* No need to keep copy of data in system memory. */
|
||||
MEM_freeN(elem->data);
|
||||
elem->data = NULL;
|
||||
}
|
||||
|
||||
void GPU_indexbuf_use(GPUIndexBuf *elem)
|
||||
{
|
||||
if (elem->ibo_id == 0) {
|
||||
elem->ibo_id = GPU_buf_alloc();
|
||||
}
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->ibo_id);
|
||||
if (elem->data != NULL) {
|
||||
indexbuf_upload_data(elem);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_indexbuf_discard(GPUIndexBuf *elem)
|
||||
|
@ -310,5 +317,8 @@ void GPU_indexbuf_discard(GPUIndexBuf *elem)
|
|||
if (elem->ibo_id) {
|
||||
GPU_buf_free(elem->ibo_id);
|
||||
}
|
||||
if (elem->data) {
|
||||
MEM_freeN(elem->data);
|
||||
}
|
||||
MEM_freeN(elem);
|
||||
}
|
||||
|
|
|
@ -119,10 +119,6 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len)
|
|||
/* catch any unnecessary use */
|
||||
assert(verts->vertex_alloc != v_len || verts->data == NULL);
|
||||
#endif
|
||||
/* only create the buffer the 1st time */
|
||||
if (verts->vbo_id == 0) {
|
||||
verts->vbo_id = GPU_buf_alloc();
|
||||
}
|
||||
/* discard previous data if any */
|
||||
if (verts->data) {
|
||||
MEM_freeN(verts->data);
|
||||
|
@ -260,6 +256,10 @@ static void VertBuffer_upload_data(GPUVertBuf *verts)
|
|||
|
||||
void GPU_vertbuf_use(GPUVertBuf *verts)
|
||||
{
|
||||
/* only create the buffer the 1st time */
|
||||
if (verts->vbo_id == 0) {
|
||||
verts->vbo_id = GPU_buf_alloc();
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
|
||||
if (verts->dirty) {
|
||||
VertBuffer_upload_data(verts);
|
||||
|
|
Loading…
Reference in New Issue