glsl: buffer variables can be readonly and writeonly
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Thu, 14 Sep 2017 16:21:24 +0000 (16:21 +0000)
committerJuan A. Suarez Romero <jasuarez@igalia.com>
Tue, 19 Sep 2017 16:45:56 +0000 (18:45 +0200)
In GLSL ES 3.10 session 4.9 [Memory Access Qualifiers], it has the
following description:

"A variable could be qualified as both readonly and writeonly,
disallowing both read and write, but still be passed to
imageSize() to have the size queried.".

This is for image variable, but not for buffer variables.

According to https://github.com/KhronosGroup/OpenGL-API/issues/7 Khronos
intent is to allow both readonly and writeonly in buffer variables, and
as such it will update the GLSL specification.

This commit address this issue, and fixes:

KHR-GL{43,44,45}.shader_storage_buffer_object.basic-readonly-writeonly
KHR-GLES31.core.shader_storage_buffer_object.basic-readonly-writeonly

v2: set correctly fields[i] memory flags (Samuel Pitoiset).

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/compiler/glsl/ast_to_hir.cpp

index 45c8ca2a5d9dc3c8c159100591f6689e89bf66d0..c46454956d7572d28d6e8cab7bb58ecc9206a240 100644 (file)
@@ -7254,11 +7254,6 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
             validate_matrix_layout_for_type(state, &loc, decl_type, NULL);
       }
 
-      if (qual->flags.q.read_only && qual->flags.q.write_only) {
-         _mesa_glsl_error(&loc, state, "buffer variable can't be both "
-                          "readonly and writeonly.");
-      }
-
       foreach_list_typed (ast_declaration, decl, link,
                           &decl_list->declarations) {
          YYLTYPE loc = decl->get_location();
@@ -7434,12 +7429,9 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
             /* For readonly and writeonly qualifiers the field definition,
              * if set, overwrites the layout qualifier.
              */
-            if (qual->flags.q.read_only) {
-               fields[i].memory_read_only = true;
-               fields[i].memory_write_only = false;
-            } else if (qual->flags.q.write_only) {
-               fields[i].memory_read_only = false;
-               fields[i].memory_write_only = true;
+            if (qual->flags.q.read_only || qual->flags.q.write_only) {
+               fields[i].memory_read_only = qual->flags.q.read_only;
+               fields[i].memory_write_only = qual->flags.q.write_only;
             } else {
                fields[i].memory_read_only =
                   layout ? layout->flags.q.read_only : 0;