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:
Diffstat (limited to 'source/blender/gpu/intern/gpu_uniformbuffer.c')
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c52
1 files changed, 51 insertions, 1 deletions
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