[Bf-blender-cvs] [18e316bcb9f] blender2.8: Uniform Buffer Objects: Simplification refactor

Dalai Felinto noreply at git.blender.org
Thu Jun 7 20:38:35 CEST 2018


Commit: 18e316bcb9f4aa7221f82a40fd3307cde7eaffbb
Author: Dalai Felinto
Date:   Thu Jun 7 20:02:34 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB18e316bcb9f4aa7221f82a40fd3307cde7eaffbb

Uniform Buffer Objects: Simplification refactor

Since we are only creating this and never updating, there is no need for
the original approach with the individual data to be updated.

Note we only populate the GPU data when binding the UBO, so we can in the
future easily create the UBOs in a separate thread than the main drawing one.

Also at the moment animated materials are not working. To fix that we need
to free/tag for free the GPUMaterials in BKE_material_eval.

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

M	source/blender/gpu/GPU_uniformbuffer.h
M	source/blender/gpu/intern/gpu_uniformbuffer.c

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

diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
index 4c5d52e5c4e..2f422fa1a92 100644
--- a/source/blender/gpu/GPU_uniformbuffer.h
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -35,7 +35,6 @@
 struct ListBase;
 
 typedef struct GPUUniformBuffer GPUUniformBuffer;
-typedef struct GPUUniformBufferDynamicItem GPUUniformBufferDynamicItem;
 
 GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]);
 GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(struct ListBase *inputs, char err_out[256]);
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
index a5cae1813c2..1e39b2ea5b7 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -62,26 +62,14 @@ struct GPUUniformBuffer {
 
 typedef struct GPUUniformBufferDynamic {
 	GPUUniformBuffer buffer;
-	ListBase items;				/* GPUUniformBufferDynamicItem */
-	void *data;
+	void *data;                  /* Continuous memory block to copy to GPU. */
 	char flag;
 } GPUUniformBufferDynamic;
 
-struct GPUUniformBufferDynamicItem {
-	struct GPUUniformBufferDynamicItem *next, *prev;
-	GPUType gputype;
-	float *data;
-	int size;
-};
-
-
 /* Prototypes */
 static GPUType get_padded_gpu_type(struct LinkData *link);
 static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
 
-static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
-        GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num);
-
 /* Only support up to this type, if you want to extend it, make sure the
  * padding logic is correct for the new types. */
 #define MAX_UBO_GPU_TYPE GPU_VEC4
@@ -159,34 +147,47 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou
 	gpu_uniformbuffer_inputs_sort(inputs);
 
 	for (LinkData *link = inputs->first; link; link = link->next) {
-		GPUInput *input = link->data;
-		GPUType gputype = get_padded_gpu_type(link);
-		gpu_uniformbuffer_populate(ubo, gputype, input->dynamicvec);
+		const GPUType gputype = get_padded_gpu_type(link);
+		ubo->buffer.size += gputype * sizeof(float);
 	}
 
+	/* Allocate the data. */
 	ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
 
-	/* Initialize buffer data. */
-	GPU_uniformbuffer_dynamic_update(&ubo->buffer);
+	/* Now that we know the total ubo size we can start populating it. */
+	float *offset = ubo->data;
+	for (LinkData *link = inputs->first; link; link = link->next) {
+		GPUInput *input = link->data;
+		const GPUType gputype = get_padded_gpu_type(link);
+		memcpy(offset, input->dynamicvec, gputype * sizeof(float));
+		offset += gputype;
+	}
+
+	/* Note since we may create the UBOs in the CPU in a different thread than the main drawing one,
+	 * we don't create the UBO in the GPU here. This will happen when we first bind the UBO.
+	 */
+
 	return &ubo->buffer;
 }
 
 /**
- * Free the data, and clean the items list.
+ * Free the data
  */
-static void gpu_uniformbuffer_dynamic_reset(GPUUniformBufferDynamic *ubo)
+static void gpu_uniformbuffer_dynamic_free(GPUUniformBuffer *ubo_)
 {
+	BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
+	GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
+
 	ubo->buffer.size = 0;
 	if (ubo->data) {
 		MEM_freeN(ubo->data);
 	}
-	BLI_freelistN(&ubo->items);
 }
 
 void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
 {
 	if (ubo->type == GPU_UBO_DYNAMIC) {
-		gpu_uniformbuffer_dynamic_reset((GPUUniformBufferDynamic *)ubo);
+		gpu_uniformbuffer_dynamic_free(ubo);
 	}
 
 	glDeleteBuffers(1, &ubo->bindcode);
@@ -215,12 +216,6 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
 	BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
 	GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
 
-	float *offset = ubo->data;
-	for (GPUUniformBufferDynamicItem *item = ubo->items.first; item; item = item->next) {
-		memcpy(offset, item->data, item->size);
-		offset += item->gputype;
-	}
-
 	if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
 		gpu_uniformbuffer_update(ubo_, ubo->data);
 	}
@@ -316,27 +311,6 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
 	}
 }
 
-/**
- * This may now happen from the main thread, so we can't update the UBO
- * We simply flag it as dirty
- */
-static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
-        GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num)
-{
-	BLI_assert(gputype <= MAX_UBO_GPU_TYPE);
-	GPUUniformBufferDynamicItem *item = MEM_callocN(sizeof(GPUUniformBufferDynamicItem), __func__);
-
-	item->gputype = gputype;
-	item->data = num;
-	item->size = gputype * sizeof(float);
-	ubo->buffer.size += item->size;
-
-	ubo->flag |= GPU_UBO_FLAG_DIRTY;
-	BLI_addtail(&ubo->items, item);
-
-	return item;
-}
-
 void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
 {
 	if (number >= GPU_max_ubo_binds()) {



More information about the Bf-blender-cvs mailing list