Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2017-08-18 13:00:30 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-08-18 13:21:02 +0300
commitf4bd416b342ba840b5c3660526e0a938b7730cce (patch)
tree6b3bbfc91b096e0ec98f64c9f45e4a69e8768a50 /source/blender/gpu/intern/gpu_uniformbuffer.c
parent6fe38bf1ccce70b40d7a69bbb4bf3d1a0fbef9ab (diff)
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
Diffstat (limited to 'source/blender/gpu/intern/gpu_uniformbuffer.c')
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c31
1 files changed, 25 insertions, 6 deletions
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__);
@@ -225,6 +227,26 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
}
/**
+ * 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;