glsl: allow to declare bindless samplers/images as non-uniform
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 19 Apr 2017 11:43:29 +0000 (13:43 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Sat, 6 May 2017 14:40:19 +0000 (16:40 +0200)
From section 4.1.7 of the ARB_bindless_texture spec:

   "Samplers may be declared as shader inputs and outputs, as uniform
    variables, as temporary variables, and as function parameters."

From section 4.1.X of the ARB_bindless_texture spec:

   "Images may be declared as shader inputs and outputs, as uniform
    variables, as temporary variables, and as function parameters."

v3: - add validate_storage_for_sampler_image_types()
    - update spec comment
    - update the glsl error message

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/compiler/glsl/ast_to_hir.cpp

index 53dd08fe84fa7b296c219f66d4f6af27199a4b17..b8fffc1c0e76916634bec01a022b79c1120099a8 100644 (file)
@@ -3292,6 +3292,52 @@ apply_explicit_location(const struct ast_type_qualifier *qual,
    }
 }
 
+static bool
+validate_storage_for_sampler_image_types(ir_variable *var,
+                                         struct _mesa_glsl_parse_state *state,
+                                         YYLTYPE *loc)
+{
+   /* From section 4.1.7 of the GLSL 4.40 spec:
+    *
+    *    "[Opaque types] can only be declared as function
+    *     parameters or uniform-qualified variables."
+    *
+    * From section 4.1.7 of the ARB_bindless_texture spec:
+    *
+    *    "Samplers may be declared as shader inputs and outputs, as uniform
+    *     variables, as temporary variables, and as function parameters."
+    *
+    * From section 4.1.X of the ARB_bindless_texture spec:
+    *
+    *    "Images may be declared as shader inputs and outputs, as uniform
+    *     variables, as temporary variables, and as function parameters."
+    */
+   if (state->has_bindless()) {
+      if (var->data.mode != ir_var_auto &&
+          var->data.mode != ir_var_uniform &&
+          var->data.mode != ir_var_shader_in &&
+          var->data.mode != ir_var_shader_out &&
+          var->data.mode != ir_var_function_in &&
+          var->data.mode != ir_var_function_out &&
+          var->data.mode != ir_var_function_inout) {
+         _mesa_glsl_error(loc, state, "bindless image/sampler variables may "
+                         "only be declared as shader inputs and outputs, as "
+                         "uniform variables, as temporary variables and as "
+                         "function parameters");
+         return false;
+      }
+   } else {
+      if (var->data.mode != ir_var_uniform &&
+          var->data.mode != ir_var_function_in) {
+         _mesa_glsl_error(loc, state, "image/sampler variables may only be "
+                          "declared as function parameters or "
+                          "uniform-qualified global variables");
+         return false;
+      }
+   }
+   return true;
+}
+
 static bool
 validate_memory_qualifier_for_type(struct _mesa_glsl_parse_state *state,
                                    YYLTYPE *loc,
@@ -3353,12 +3399,8 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
    if (!base_type->is_image())
       return;
 
-   if (var->data.mode != ir_var_uniform &&
-       var->data.mode != ir_var_function_in) {
-      _mesa_glsl_error(loc, state, "image variables may only be declared as "
-                       "function parameters or uniform-qualified "
-                       "global variables");
-   }
+   if (!validate_storage_for_sampler_image_types(var, state, loc))
+      return;
 
    var->data.memory_read_only |= qual->flags.q.read_only;
    var->data.memory_write_only |= qual->flags.q.write_only;
@@ -3696,14 +3738,9 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
       }
    }
 
-   if (var->type->contains_sampler()) {
-      if (var->data.mode != ir_var_uniform &&
-          var->data.mode != ir_var_function_in) {
-         _mesa_glsl_error(loc, state, "sampler variables may only be declared "
-                          "as function parameters or uniform-qualified "
-                          "global variables");
-      }
-   }
+   if (var->type->contains_sampler() &&
+       !validate_storage_for_sampler_image_types(var, state, loc))
+      return;
 
    /* Is the 'layout' keyword used with parameters that allow relaxed checking.
     * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
@@ -5294,11 +5331,23 @@ ast_declarator_list::hir(exec_list *instructions,
        *
        *    "[Opaque types] can only be declared as function
        *     parameters or uniform-qualified variables."
+       *
+       * From section 4.1.7 of the ARB_bindless_texture spec:
+       *
+       *    "Samplers may be declared as shader inputs and outputs, as uniform
+       *     variables, as temporary variables, and as function parameters."
+       *
+       * From section 4.1.X of the ARB_bindless_texture spec:
+       *
+       *    "Images may be declared as shader inputs and outputs, as uniform
+       *     variables, as temporary variables, and as function parameters."
        */
-      if (var_type->contains_opaque() &&
-          !this->type->qualifier.flags.q.uniform) {
+      if (!this->type->qualifier.flags.q.uniform &&
+          (var_type->contains_atomic() ||
+           (!state->has_bindless() && var_type->contains_opaque()))) {
          _mesa_glsl_error(&loc, state,
-                          "opaque variables must be declared uniform");
+                          "%s variables must be declared uniform",
+                          state->has_bindless() ? "atomic" : "opaque");
       }
 
       /* Process the initializer and add its instructions to a temporary