[Mesa-dev] [PATCH v3 (part2) 46/56] glsl: Allow memory layout qualifiers on shader storage buffer objects

Iago Toral Quiroga itoral at igalia.com
Tue Jul 14 00:46:48 PDT 2015


Since memory qualifiers are also keywords we need to do the same
trick we use for other keywords that can be used as layout qualifiers
to handle alternate capitalizations in desktop GLSL, like row_major, etc.
---
 src/glsl/ast_to_hir.cpp | 31 ++++++++++++++++----
 src/glsl/glsl_parser.yy | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 5 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 92bf414..ab62599 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -6142,11 +6142,32 @@ ast_interface_block::hir(exec_list *instructions,
          var->data.stream = this->layout.stream;
 
          if (var->data.mode == ir_var_shader_storage) {
-            var->data.image_read_only = fields[i].image_read_only;
-            var->data.image_write_only = fields[i].image_write_only;
-            var->data.image_coherent = fields[i].image_coherent;
-            var->data.image_volatile = fields[i].image_volatile;
-            var->data.image_restrict = fields[i].image_restrict;
+            /* For readonly and writeonly qualifiers the field definition,
+             * if set, overwrites the layout qualifier.
+             */
+            bool read_only = this->layout.flags.q.read_only;
+            bool write_only = this->layout.flags.q.write_only;
+
+            if (fields[i].image_read_only) {
+               read_only = true;
+               write_only = false;
+            } else if (fields[i].image_write_only) {
+               read_only = false;
+               write_only = true;
+            }
+
+            var->data.image_read_only = read_only;
+            var->data.image_write_only = write_only;
+
+            /* For other qualifiers, we set   the flag if either the layout
+             * qualifier or the field qualifier are set
+             */
+            var->data.image_coherent = fields[i].image_coherent ||
+                                        this->layout.flags.q.coherent;
+            var->data.image_volatile = fields[i].image_volatile ||
+                                        this->layout.flags.q._volatile;
+            var->data.image_restrict = fields[i].image_restrict ||
+                                        this->layout.flags.q.restrict_flag;
          }
 
          /* Examine var name here since var may get deleted in the next call */
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 4ef946b..de41415 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1278,6 +1278,26 @@ layout_qualifier_id:
          }
       }
 
+      /* See also interface_block_layout_qualifier. */
+      if (!$$.flags.i && state->has_shader_storage_buffer_objects()) {
+         /* Memory qualifiers are reserved words. Its token is parsed
+          * below in the interface_block_layout_qualifier rule. This takes
+          * care of alternate capitalizations (which is necessary because
+          * layout qualifiers are case-insensitive in desktop GLSL).
+          */
+         if (match_layout_qualifier($1, "volatile", state) == 0) {
+            $$.flags.q._volatile = 1;
+         } else if (match_layout_qualifier($1, "restrict", state) == 0) {
+            $$.flags.q.restrict_flag = 1;
+         } else if (match_layout_qualifier($1, "coherent", state) == 0) {
+            $$.flags.q.coherent = 1;
+         } else if (match_layout_qualifier($1, "readonly", state) == 0) {
+            $$.flags.q.read_only = 1;
+         } else if (match_layout_qualifier($1, "writeonly", state) == 0) {
+            $$.flags.q.write_only = 1;
+         }
+      }
+
       /* Layout qualifiers for GLSL 1.50 geometry shaders. */
       if (!$$.flags.i) {
          static const struct {
@@ -1569,6 +1589,61 @@ interface_block_layout_qualifier:
       memset(& $$, 0, sizeof($$));
       $$.flags.q.packed = 1;
    }
+   | VOLATILE
+   {
+      memset(& $$, 0, sizeof($$));
+      if (state->has_shader_storage_buffer_objects()) {
+         $$.flags.q._volatile = 1;
+      } else {
+         _mesa_glsl_error(& @1, state,
+                          "Layout qualifier `volatile' is only "
+                          "allowed with shader storage buffer objects");
+      }
+   }
+   | COHERENT
+   {
+      memset(& $$, 0, sizeof($$));
+      if (state->has_shader_storage_buffer_objects()) {
+         $$.flags.q.coherent = 1;
+      } else {
+         _mesa_glsl_error(& @1, state,
+                          "Layout qualifier `coherent' is only "
+                          "allowed with shader storage buffer objects");
+      }
+   }
+   | RESTRICT
+   {
+      memset(& $$, 0, sizeof($$));
+      if (state->has_shader_storage_buffer_objects()) {
+         $$.flags.q.restrict_flag = 1;
+      } else {
+         _mesa_glsl_error(& @1, state,
+                          "Layout qualifier `restrict' is only "
+                          "allowed with shader storage buffer objects");
+      }
+   }
+   | READONLY
+   {
+      memset(& $$, 0, sizeof($$));
+      if (state->has_shader_storage_buffer_objects()) {
+         $$.flags.q.read_only = 1;
+      } else {
+         _mesa_glsl_error(& @1, state,
+                          "Layout qualifier `readonly' is only "
+                          "allowed with shader storage buffer objects");
+      }
+   }
+   | WRITEONLY
+   {
+      memset(& $$, 0, sizeof($$));
+      if (state->has_shader_storage_buffer_objects()) {
+         $$.flags.q.write_only = 1;
+      } else {
+         _mesa_glsl_error(& @1, state,
+                          "Layout qualifier `writeonly' is only "
+                          "allowed with shader storage buffer objects");
+      }
+   }
    ;
 
 interpolation_qualifier:
-- 
1.9.1



More information about the mesa-dev mailing list