[Bf-blender-cvs] [2dad2aa9b7d] blender2.8: Uniform Buffer Objects: More complete padding solution

Dalai Felinto noreply at git.blender.org
Fri Aug 18 16:43:10 CEST 2017


Commit: 2dad2aa9b7d8fb8d84c8663ad81bd28d979c50fb
Author: Dalai Felinto
Date:   Fri Aug 18 16:42:58 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB2dad2aa9b7d8fb8d84c8663ad81bd28d979c50fb

Uniform Buffer Objects: More complete padding solution

Move floats around when needed to accomodate vec3 arrays efficiently.

With this we use slightly less memory when possible. Basically vec3s are not
treated as vec4 unless we have no float to use for padding).

Reviewers: fclem, sergey

Differential Revision: https://developer.blender.org/D2800

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

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

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

diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
index affff54d407..46cf9d19a47 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -82,6 +82,10 @@ 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
+
 static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data)
 {
 	glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
@@ -263,7 +267,51 @@ static int inputs_cmp(const void *a, const void *b)
  */
 static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
 {
+	/* Order them as vec4, vec3, vec2, float. */
 	BLI_listbase_sort(inputs, inputs_cmp);
+
+	/* Creates a lookup table for the different types; */
+	LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL};
+	GPUType cur_type = MAX_UBO_GPU_TYPE + 1;
+
+	for (LinkData *link = inputs->first; link; link = link->next) {
+		GPUInput *input = link->data;
+		if (input->type == cur_type) {
+			continue;
+		}
+		else {
+			inputs_lookup[input->type] = link;
+			cur_type = input->type;
+		}
+	}
+
+	/* If there is no GPU_VEC3 there is no need for alignment. */
+	if (inputs_lookup[GPU_VEC3] == NULL) {
+		return;
+	}
+
+	LinkData *link = inputs_lookup[GPU_VEC3];
+	while (link != NULL && ((GPUInput *)link->data)->type == GPU_VEC3) {
+		LinkData *link_next = link->next;
+
+		/* If GPU_VEC3 is followed by nothing or a GPU_FLOAT, no need for aligment. */
+		if ((link_next == NULL) ||
+		    ((GPUInput *)link_next->data)->type == GPU_FLOAT)
+		{
+			break;
+		}
+
+		/* If there is a float, move it next to current vec3. */
+		if (inputs_lookup[GPU_FLOAT] != NULL) {
+			LinkData *float_input = inputs_lookup[GPU_FLOAT];
+			inputs_lookup[GPU_FLOAT] = float_input->next;
+
+			BLI_remlink(inputs, float_input);
+			BLI_insertlinkafter(inputs, link, float_input);
+		}
+
+		link = link_next;
+	}
 }
 
 /**
@@ -273,7 +321,7 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
 static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
         GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num)
 {
-	BLI_assert(gputype <= GPU_VEC4);
+	BLI_assert(gputype <= MAX_UBO_GPU_TYPE);
 	GPUUniformBufferDynamicItem *item = MEM_callocN(sizeof(GPUUniformBufferDynamicItem), __func__);
 
 	item->gputype = gputype;
@@ -318,3 +366,5 @@ void GPU_uniformbuffer_tag_dirty(GPUUniformBuffer *ubo_) {
 	GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
 	ubo->flag |= GPU_UBO_FLAG_DIRTY;
 }
+
+#undef MAX_UBO_GPU_TYPE



More information about the Bf-blender-cvs mailing list