glsl: enable binding layout qualifier usage for shader storage buffer objects
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Wed, 18 Mar 2015 08:02:51 +0000 (09:02 +0100)
committerSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Tue, 14 Jul 2015 05:04:04 +0000 (07:04 +0200)
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 <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/glsl/ast_to_hir.cpp
src/glsl/glsl_parser.yy

index f9f1c083f72cf23500928a7a3949c11faffa2c9b..e887ac25fbbb6c932a052cef213b4364be8161d3 100644 (file)
@@ -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;
index 8564cb99374c415b47f32ab7deb8e56a2618f9fb..37c44014ba7e3944fca7984bc974c9647e1dbdb0 100644 (file)
@@ -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;