From fa0a86c057ac9bff9b208f93db75c5ce5bd7136f Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 18 Mar 2015 09:02:51 +0100 Subject: [PATCH] glsl: enable binding layout qualifier usage for shader storage buffer objects See GLSL 4.30 spec, section 4.4.5 "Uniform and Shader Storage Block Layout Qualifiers". v2: - Add whitespace in an error message. Delete period '.' at the end of that error message (Jordan). Signed-off-by: Samuel Iglesias Gonsalvez Reviewed-by: Jordan Justen --- src/glsl/ast_to_hir.cpp | 29 ++++++++++++++++++++++++----- src/glsl/glsl_parser.yy | 3 ++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f9f1c083f72..e887ac25fbb 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2044,9 +2044,10 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, ir_variable *var, const ast_type_qualifier *qual) { - if (var->data.mode != ir_var_uniform) { + if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage) { _mesa_glsl_error(loc, state, - "the \"binding\" qualifier only applies to uniforms"); + "the \"binding\" qualifier only applies to uniforms and " + "shader storage buffer objects"); return false; } @@ -2070,13 +2071,31 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, * * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS. */ - if (max_index >= ctx->Const.MaxUniformBufferBindings) { + if (var->data.mode == ir_var_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)", qual->binding, elements, 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 + * implementation-dependent maximum number of uniform buffer bindings, a + * compile-time error will occur. When the binding identifier is used + * with a uniform or shader storage block instanced as an array of size + * 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 && + 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)", + qual->binding, elements, + ctx->Const.MaxShaderStorageBufferBindings); + return false; + } } else if (var->type->is_sampler() || (var->type->is_array() && var->type->fields.array->is_sampler())) { /* Samplers. From page 63 of the GLSL 4.20 specification: @@ -5955,8 +5974,8 @@ ast_interface_block::hir(exec_list *instructions, if (state->symbols->get_variable(var->name) != NULL) _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); - /* Propagate the "binding" keyword into this UBO's fields; - * the UBO declaration itself doesn't get an ir_variable unless it + /* Propagate the "binding" keyword into this UBO/SSBO'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; diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 8564cb99374..37c44014ba7 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -1425,7 +1425,8 @@ layout_qualifier_id: } if ((state->ARB_shading_language_420pack_enable || - state->has_atomic_counters()) && + state->has_atomic_counters() || + state->ARB_shader_storage_buffer_object_enable) && match_layout_qualifier("binding", $1, state) == 0) { $$.flags.q.explicit_binding = 1; $$.binding = $3; -- 2.30.2