summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/ast_array_index.cpp14
-rw-r--r--src/compiler/glsl/link_uniform_blocks.cpp8
2 files changed, 15 insertions, 7 deletions
diff --git a/src/compiler/glsl/ast_array_index.cpp b/src/compiler/glsl/ast_array_index.cpp
index e29dafb7907..dfa44b703d4 100644
--- a/src/compiler/glsl/ast_array_index.cpp
+++ b/src/compiler/glsl/ast_array_index.cpp
@@ -233,6 +233,20 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
else if (array->variable_referenced()->data.mode !=
ir_var_shader_storage) {
_mesa_glsl_error(&loc, state, "unsized array index must be constant");
+ } else {
+ /* Unsized array non-constant indexing on SSBO is allowed only for
+ * the last member of the SSBO definition.
+ */
+ ir_variable *var = array->variable_referenced();
+ const glsl_type *iface_type = var->get_interface_type();
+ int field_index = iface_type->field_index(var->name);
+ /* Field index can be < 0 for instance arrays */
+ if (field_index >= 0 &&
+ field_index != (int) iface_type->length - 1) {
+ _mesa_glsl_error(&loc, state, "Indirect access on unsized "
+ "array is limited to the last member of "
+ "SSBO.");
+ }
}
} else if (array->type->without_array()->is_interface()
&& ((array->variable_referenced()->data.mode == ir_var_uniform
diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp
index 5b0dff6aa19..bb423c55410 100644
--- a/src/compiler/glsl/link_uniform_blocks.cpp
+++ b/src/compiler/glsl/link_uniform_blocks.cpp
@@ -150,13 +150,7 @@ private:
*/
const glsl_type *type_for_size = type;
if (type->is_unsized_array()) {
- if (!last_field) {
- linker_error(prog, "unsized array `%s' definition: "
- "only last member of a shader storage block "
- "can be defined as unsized array",
- name);
- }
-
+ assert(last_field);
type_for_size = type->without_array();
}