[Bf-blender-cvs] [f4bd416b342] blender2.8: Fix ubo vec3 alignment issue

Dalai Felinto noreply at git.blender.org
Fri Aug 18 12:21:24 CEST 2017


Commit: f4bd416b342ba840b5c3660526e0a938b7730cce
Author: Dalai Felinto
Date:   Fri Aug 18 12:00:30 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBf4bd416b342ba840b5c3660526e0a938b7730cce

Fix ubo vec3 alignment issue

This fixes the Principled shader in Eevee, among other nodes.

Basically before we were treating all the vec3 as vec4 as far as memory
goes. We now only do it when required (aka, when the vec3 is not
followed by a float).

We can be even smarter about that and move the floats around to provide
padding for the vec3s. However this is for a separate patch.

That said, there seems to be some strong consensus in corners of the
internet against using vec3 at all [1]. Basically even if we get all the
padding correct, we may still suffer from poor driver implementations in
some consumer graphic cards.

It's not hard to move to vec4, but I think we can avoid doing it as much
as possible. By the time 2.8 is out hopefully most drivers will be
implementing things correctly.

[1] - https://stackoverflow.com/questions/38172696

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

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 9e786844270..affff54d407 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -76,6 +76,7 @@ struct GPUUniformBufferDynamicItem {
 
 
 /* Prototypes */
+static GPUType get_padded_gpu_type(struct LinkData *link);
 static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
 
 static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
@@ -153,7 +154,8 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou
 
 	for (LinkData *link = inputs->first; link; link = link->next) {
 		GPUInput *input = link->data;
-		gpu_uniformbuffer_populate(ubo, input->type, input->dynamicvec);
+		GPUType gputype = get_padded_gpu_type(link);
+		gpu_uniformbuffer_populate(ubo, gputype, input->dynamicvec);
 	}
 
 	ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
@@ -224,6 +226,26 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
 	ubo->flag &= ~GPU_UBO_FLAG_DIRTY;
 }
 
+/**
+ * We need to pad some data types (vec3) on the C side
+ * To match the GPU expected memory block alignment.
+ */
+static GPUType get_padded_gpu_type(LinkData *link)
+{
+	GPUInput *input = link->data;
+	GPUType gputype = input->type;
+
+	/* Unless the vec3 is followed by a float we need to treat it as a vec4. */
+	if (gputype == GPU_VEC3 &&
+		(link->next != NULL) &&
+		(((GPUInput *)link->next->data)->type != GPU_FLOAT))
+	{
+		gputype = GPU_VEC4;
+	}
+
+	return gputype;
+}
+
 /**
  * Returns 1 if the first item shold be after second item.
  * We make sure the vec4 uniforms come first.
@@ -254,12 +276,9 @@ static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
 	BLI_assert(gputype <= GPU_VEC4);
 	GPUUniformBufferDynamicItem *item = MEM_callocN(sizeof(GPUUniformBufferDynamicItem), __func__);
 
-	/* Treat VEC3 as VEC4 because of UBO struct alignment requirements. */
-	GPUType type = gputype == GPU_VEC3 ? GPU_VEC4 : gputype;
-
-	item->gputype = type;
+	item->gputype = gputype;
 	item->data = num;
-	item->size = type * sizeof(float);
+	item->size = gputype * sizeof(float);
 	ubo->buffer.size += item->size;
 
 	ubo->flag |= GPU_UBO_FLAG_DIRTY;



More information about the Bf-blender-cvs mailing list