From ad89748541159968787dce02bb9c19d9367fddc6 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 27 May 2015 20:12:42 +1000 Subject: [PATCH] glsl: fix binding validation for interface blocks V2: rebase on SSBO changes Reviewed-by: Ian Romanick --- src/glsl/ast_to_hir.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index e8b61ae3133..c7ce4096f4d 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2098,10 +2098,10 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, static bool validate_binding_qualifier(struct _mesa_glsl_parse_state *state, YYLTYPE *loc, - ir_variable *var, + const glsl_type *type, const ast_type_qualifier *qual) { - if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage) { + if (!qual->flags.q.uniform && !qual->flags.q.buffer) { _mesa_glsl_error(loc, state, "the \"binding\" qualifier only applies to uniforms and " "shader storage buffer objects"); @@ -2114,10 +2114,11 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, } const struct gl_context *const ctx = state->ctx; - unsigned elements = var->type->is_array() ? var->type->length : 1; + unsigned elements = type->is_array() ? type->length : 1; unsigned max_index = qual->binding + elements - 1; + const glsl_type *base_type = type->without_array(); - if (var->type->is_interface()) { + if (base_type->is_interface()) { /* UBOs. From page 60 of the GLSL 4.20 specification: * "If the binding point for any uniform block instance is less than zero, * or greater than or equal to the implementation-dependent maximum @@ -2128,7 +2129,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, * * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS. */ - if (var->data.mode == ir_var_uniform && + if (qual->flags.q.uniform && max_index >= ctx->Const.MaxUniformBufferBindings) { _mesa_glsl_error(loc, state, "layout(binding = %d) for %d UBOs exceeds " "the maximum number of UBO binding points (%d)", @@ -2136,6 +2137,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, ctx->Const.MaxUniformBufferBindings); return false; } + /* SSBOs. From page 67 of the GLSL 4.30 specification: * "If the binding point for any uniform or shader storage block instance * is less than zero, or greater than or equal to the @@ -2145,7 +2147,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, * N, all elements of the array from binding through binding + N – 1 must * be within this range." */ - if (var->data.mode == ir_var_shader_storage && + if (qual->flags.q.buffer && max_index >= ctx->Const.MaxShaderStorageBufferBindings) { _mesa_glsl_error(loc, state, "layout(binding = %d) for %d SSBOs exceeds " "the maximum number of SSBO binding points (%d)", @@ -2153,8 +2155,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, ctx->Const.MaxShaderStorageBufferBindings); return false; } - } else if (var->type->is_sampler() || - (var->type->is_array() && var->type->fields.array->is_sampler())) { + } else if (base_type->is_sampler()) { /* Samplers. From page 63 of the GLSL 4.20 specification: * "If the binding is less than zero, or greater than or equal to the * implementation-dependent maximum supported number of units, a @@ -2171,7 +2172,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, return false; } - } else if (var->type->contains_atomic()) { + } else if (base_type->contains_atomic()) { assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS); if (unsigned(qual->binding) >= ctx->Const.MaxAtomicBufferBindings) { _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the " @@ -2181,8 +2182,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, return false; } - } else if (state->is_version(420, 310) && - var->type->without_array()->is_image()) { + } else if (state->is_version(420, 310) && base_type->is_image()) { assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); if (max_index >= ctx->Const.MaxImageUnits) { _mesa_glsl_error(loc, state, "Image binding %d exceeds the " @@ -2783,7 +2783,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } if (qual->flags.q.explicit_binding && - validate_binding_qualifier(state, loc, var, qual)) { + validate_binding_qualifier(state, loc, var->type, qual)) { var->data.explicit_binding = true; var->data.binding = qual->binding; } @@ -6093,6 +6093,8 @@ ast_interface_block::hir(exec_list *instructions, num_variables, packing, this->block_name); + if (this->layout.flags.q.explicit_binding) + validate_binding_qualifier(state, &loc, block_type, &this->layout); if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) { YYLTYPE loc = this->get_location(); @@ -6223,6 +6225,10 @@ ast_interface_block::hir(exec_list *instructions, "not allowed"); } + if (this->layout.flags.q.explicit_binding) + validate_binding_qualifier(state, &loc, block_array_type, + &this->layout); + var = new(state) ir_variable(block_array_type, this->instance_name, var_mode);