[Mesa-dev] [PATCH 06/25] glsl: fix binding validation for interface blocks

Ian Romanick idr at freedesktop.org
Thu Aug 20 10:44:12 PDT 2015


This patch is

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

On 08/19/2015 09:37 PM, Timothy Arceri wrote:
> V2: rebase on SSBO changes
> ---
>  src/glsl/ast_to_hir.cpp | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
> index 5ee02ed..ee5ff9d 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 "
> @@ -2749,7 +2750,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;
>     }
> @@ -6058,6 +6059,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();
> @@ -6188,6 +6191,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);
> 



More information about the mesa-dev mailing list