diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-12-08 20:15:57 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-12-10 21:02:17 +0300 |
commit | 33cc3344a26d674c1283c5fd8c007a63f0d8a5fc (patch) | |
tree | 0aaa98b8d88a68c7b4186e8df507d6d25cdd3d06 /source/blender/gpu/intern/gpu_element.c | |
parent | a99eb0ca689c8116964032faf8425cfba16759bc (diff) |
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.
Diffstat (limited to 'source/blender/gpu/intern/gpu_element.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_element.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 5efb193c3ad..ef98e4a328b 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -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); } |