[Bf-blender-cvs] [33cc3344a26] blender2.8: GPU: Make changes to GPUIndexBuf and GPUVertBuf to allow multithreading

Clément Foucault noreply at git.blender.org
Mon Dec 10 19:03:32 CET 2018


Commit: 33cc3344a26d674c1283c5fd8c007a63f0d8a5fc
Author: Clément Foucault
Date:   Sat Dec 8 18:15:57 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB33cc3344a26d674c1283c5fd8c007a63f0d8a5fc

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.

===================================================================

M	source/blender/gpu/GPU_element.h
M	source/blender/gpu/intern/gpu_element.c
M	source/blender/gpu/intern/gpu_vertex_buffer.c

===================================================================

diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h
index c16a3d8b4a1..b8a42b7c880 100644
--- a/source/blender/gpu/GPU_element.h
+++ b/source/blender/gpu/GPU_element.h
@@ -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;
 
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);
 }
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c
index b6058a2cb79..a5c560fb17b 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.c
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.c
@@ -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);



More information about the Bf-blender-cvs mailing list