summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ast_to_hir.cpp7
-rw-r--r--src/glsl/link_uniform_block_active_visitor.cpp8
-rw-r--r--src/glsl/link_uniform_block_active_visitor.h3
-rw-r--r--src/glsl/link_uniform_blocks.cpp14
4 files changed, 30 insertions, 2 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 8d55ee31713..1d15e6213e7 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -5316,6 +5316,13 @@ ast_interface_block::hir(exec_list *instructions,
earlier->reinit_interface_type(block_type);
delete var;
} else {
+ /* Propagate the "binding" keyword into this UBO's fields;
+ * the UBO declaration itself doesn't get an ir_variable unless it
+ * has an instance name. This is ugly.
+ */
+ var->data.explicit_binding = this->layout.flags.q.explicit_binding;
+ var->data.binding = this->layout.binding;
+
state->symbols->add_variable(var);
instructions->push_tail(var);
}
diff --git a/src/glsl/link_uniform_block_active_visitor.cpp b/src/glsl/link_uniform_block_active_visitor.cpp
index f2f46a21130..d19ce20c782 100644
--- a/src/glsl/link_uniform_block_active_visitor.cpp
+++ b/src/glsl/link_uniform_block_active_visitor.cpp
@@ -46,6 +46,14 @@ process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)
b->type = block_type;
b->has_instance_name = var->is_interface_instance();
+ if (var->data.explicit_binding) {
+ b->has_binding = true;
+ b->binding = var->data.binding;
+ } else {
+ b->has_binding = false;
+ b->binding = 0;
+ }
+
_mesa_hash_table_insert(ht, h, var->get_interface_type()->name,
(void *) b);
return b;
diff --git a/src/glsl/link_uniform_block_active_visitor.h b/src/glsl/link_uniform_block_active_visitor.h
index fba628a8f44..d76dbcaf12b 100644
--- a/src/glsl/link_uniform_block_active_visitor.h
+++ b/src/glsl/link_uniform_block_active_visitor.h
@@ -36,7 +36,10 @@ struct link_uniform_block_active {
unsigned *array_elements;
unsigned num_array_elements;
+ unsigned binding;
+
bool has_instance_name;
+ bool has_binding;
};
class link_uniform_block_active_visitor : public ir_hierarchical_visitor {
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index 72d6c5323a6..1a0e6431805 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -251,7 +251,17 @@ link_uniform_blocks(void *mem_ctx,
blocks[i].Name = ralloc_asprintf(blocks, "%s[%u]", name,
b->array_elements[j]);
blocks[i].Uniforms = &variables[parcel.index];
- blocks[i].Binding = 0;
+
+ /* The GL_ARB_shading_language_420pack spec says:
+ *
+ * "If the binding identifier is used with a uniform block
+ * instanced as an array then the first element of the array
+ * takes the specified block binding and each subsequent
+ * element takes the next consecutive uniform block binding
+ * point."
+ */
+ blocks[i].Binding = (b->has_binding) ? b->binding + j : 0;
+
blocks[i].UniformBufferSize = 0;
blocks[i]._Packing =
gl_uniform_block_packing(block_type->interface_packing);
@@ -269,7 +279,7 @@ link_uniform_blocks(void *mem_ctx,
} else {
blocks[i].Name = ralloc_strdup(blocks, block_type->name);
blocks[i].Uniforms = &variables[parcel.index];
- blocks[i].Binding = 0;
+ blocks[i].Binding = (b->has_binding) ? b->binding : 0;
blocks[i].UniformBufferSize = 0;
blocks[i]._Packing =
gl_uniform_block_packing(block_type->interface_packing);