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 17:42:58 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-08-18 17:42:58 +0300
commit2dad2aa9b7d8fb8d84c8663ad81bd28d979c50fb (patch)
tree8339765c9bb19ed0ae59c55eee67370ad8af7c13 /source/blender/gpu/intern/gpu_uniformbuffer.c
parent659be38760784b51cf17c768cdf74cdd5718ba71 (diff)
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
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