From c47175c7bb3363151ea62c6751ef2154b7959fdb Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Mon, 17 Nov 2014 16:45:10 +0000
Subject: [PATCH] Add memory qualifiers (coherent volatile restrict) to
 imageSize(), imageLoad(), imageStore(), atomic*(), and imageAtomic*(), to
 remove errors about dropping qualifiers.

Several bugs are related to this, and this is a slightly speculative fix, bit it is certainly wrong to either do it the way it was or to reflect the current specifications.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@28968 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 Test/310.frag                             |  10 +-
 Test/baseResults/310.frag.out             | 190 ++++++++++++++--------
 glslang/MachineIndependent/Initialize.cpp |  58 ++++---
 3 files changed, 157 insertions(+), 101 deletions(-)

diff --git a/Test/310.frag b/Test/310.frag
index 87f6efcda..c1ccaaad3 100644
--- a/Test/310.frag
+++ b/Test/310.frag
@@ -62,7 +62,11 @@ void foo23()
 
 layout(binding=3) uniform sampler2D s1;
 layout(binding=3) uniform sampler2D s2; // ERROR: overlapping bindings?  Don't see that in the 310 spec.
-layout(binding=2) uniform writeonly image2D i2D;
+layout(binding=2) uniform writeonly image2D      i2D;
+layout(binding=4) uniform readonly  image3D      i3D;
+layout(binding=5) uniform           imageCube    iCube;
+layout(binding=6) uniform           image2DArray i2DA;
+layout(binding=6) uniform coherent volatile restrict image2D i2Dqualified;
 
 layout(binding = 1) uniform bb {
     int foo;
@@ -97,6 +101,10 @@ void foots()
     highp ivec3 v3 = textureSize(isamp2DA, 3);
     v2 = textureSize(s2dms);
     v2 = imageSize(i2D);
+    v3 = imageSize(i3D);
+    v2 = imageSize(iCube);
+    v3 = imageSize(i2DA);
+    v2 = imageSize(i2Dqualified);
 }
 
 out bool bout;          // ERROR
diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out
index 0d4e70e08..8bc8db670 100644
--- a/Test/baseResults/310.frag.out
+++ b/Test/baseResults/310.frag.out
@@ -17,26 +17,36 @@ ERROR: 0:44: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset,
 ERROR: 0:44: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
 ERROR: 0:45: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
 ERROR: 0:45: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
-ERROR: 0:69: 'binding' : requires block, or sampler/image, or atomic-counter type 
-ERROR: 0:73: 'location' : location is too large 
-ERROR: 0:77: 'location' : too large for fragment output 
-ERROR: 0:78: 'location' : too large for fragment output 
-ERROR: 0:78: 'location' : overlapping use of location 40
-ERROR: 0:79: 'non-literal layout-id value' : not supported with this profile: es
-ERROR: 0:79: 'layout-id value' : cannot be negative 
-ERROR: 0:99: 'writeonly' : argument cannot drop memory qualifier when passed to formal parameter 
-ERROR: 0:102: 'out' : cannot be bool 
-ERROR: 0:103: 'image2D' : sampler/image types can only be used in uniform variables or function parameters: imageOut
-ERROR: 0:103: '' : image variables not declared 'writeonly' must have a format layout qualifier 
-ERROR: 0:104: 'out' : cannot be a matrix 
-ERROR: 0:106: 'in' : cannot be bool 
-ERROR: 0:107: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: ino
-ERROR: 0:109: 'fragment-shader array-of-array input' : not supported with this profile: es
-ERROR: 0:112: 'fragment-shader array-of-struct input' : not supported with this profile: es
-ERROR: 0:113: 'fragment-shader array-of-struct input' : not supported with this profile: es
-ERROR: 0:115: 'fragment-shader struct input containing an array' : not supported with this profile: es
-ERROR: 0:117: 'fragment-shader struct input containing structure' : not supported with this profile: es
-ERROR: 36 compilation errors.  No code generated.
+ERROR: 0:66: 'sampler/image' : type requires declaration of default precision qualifier 
+ERROR: 0:66: '' : image variables not declared 'writeonly' must have a format layout qualifier 
+ERROR: 0:67: '' : image variables not declared 'writeonly' must have a format layout qualifier 
+ERROR: 0:68: 'sampler/image' : type requires declaration of default precision qualifier 
+ERROR: 0:68: '' : image variables not declared 'writeonly' must have a format layout qualifier 
+ERROR: 0:69: '' : image variables not declared 'writeonly' must have a format layout qualifier 
+ERROR: 0:73: 'binding' : requires block, or sampler/image, or atomic-counter type 
+ERROR: 0:77: 'location' : location is too large 
+ERROR: 0:81: 'location' : too large for fragment output 
+ERROR: 0:82: 'location' : too large for fragment output 
+ERROR: 0:82: 'location' : overlapping use of location 40
+ERROR: 0:83: 'non-literal layout-id value' : not supported with this profile: es
+ERROR: 0:83: 'layout-id value' : cannot be negative 
+ERROR: 0:103: 'writeonly' : argument cannot drop memory qualifier when passed to formal parameter 
+ERROR: 0:104: 'readonly' : argument cannot drop memory qualifier when passed to formal parameter 
+ERROR: 0:107: 'volatile' : argument cannot drop memory qualifier when passed to formal parameter 
+ERROR: 0:107: 'coherent' : argument cannot drop memory qualifier when passed to formal parameter 
+ERROR: 0:107: 'restrict' : argument cannot drop memory qualifier when passed to formal parameter 
+ERROR: 0:110: 'out' : cannot be bool 
+ERROR: 0:111: 'image2D' : sampler/image types can only be used in uniform variables or function parameters: imageOut
+ERROR: 0:111: '' : image variables not declared 'writeonly' must have a format layout qualifier 
+ERROR: 0:112: 'out' : cannot be a matrix 
+ERROR: 0:114: 'in' : cannot be bool 
+ERROR: 0:115: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: ino
+ERROR: 0:117: 'fragment-shader array-of-array input' : not supported with this profile: es
+ERROR: 0:120: 'fragment-shader array-of-struct input' : not supported with this profile: es
+ERROR: 0:121: 'fragment-shader array-of-struct input' : not supported with this profile: es
+ERROR: 0:123: 'fragment-shader struct input containing an array' : not supported with this profile: es
+ERROR: 0:125: 'fragment-shader struct input containing structure' : not supported with this profile: es
+ERROR: 46 compilation errors.  No code generated.
 
 
 Shader version: 310
@@ -213,31 +223,47 @@ ERROR: node is still EOpNull!
 0:60              'i' (uniform mediump int)
 0:60            Construct bvec4 (4-component vector of bool)
 0:60              'b' (bool)
-0:94  Function Definition: foots( (void)
-0:94    Function Parameters: 
-0:96    Sequence
-0:96      Sequence
-0:96        move second child to first child (highp 2-component vector of int)
-0:96          'v2' (highp 2-component vector of int)
-0:96          Function Call: textureSize(s21;i1; (highp 2-component vector of int)
-0:96            's1' (layout(binding=3 ) uniform highp sampler2D)
-0:96            Constant:
-0:96              2 (const int)
-0:97      Sequence
-0:97        move second child to first child (highp 3-component vector of int)
-0:97          'v3' (highp 3-component vector of int)
-0:97          Function Call: textureSize(isA21;i1; (highp 3-component vector of int)
-0:97            'isamp2DA' (uniform highp isampler2DArray)
-0:97            Constant:
-0:97              3 (const int)
-0:98      move second child to first child (highp 2-component vector of int)
-0:98        'v2' (highp 2-component vector of int)
-0:98        Function Call: textureSize(s21; (highp 2-component vector of int)
-0:98          's2dms' (uniform highp sampler2DMS)
-0:99      move second child to first child (highp 2-component vector of int)
-0:99        'v2' (highp 2-component vector of int)
-0:99        Function Call: imageSize(I21; (highp 2-component vector of int)
-0:99          'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:98  Function Definition: foots( (void)
+0:98    Function Parameters: 
+0:100    Sequence
+0:100      Sequence
+0:100        move second child to first child (highp 2-component vector of int)
+0:100          'v2' (highp 2-component vector of int)
+0:100          Function Call: textureSize(s21;i1; (highp 2-component vector of int)
+0:100            's1' (layout(binding=3 ) uniform highp sampler2D)
+0:100            Constant:
+0:100              2 (const int)
+0:101      Sequence
+0:101        move second child to first child (highp 3-component vector of int)
+0:101          'v3' (highp 3-component vector of int)
+0:101          Function Call: textureSize(isA21;i1; (highp 3-component vector of int)
+0:101            'isamp2DA' (uniform highp isampler2DArray)
+0:101            Constant:
+0:101              3 (const int)
+0:102      move second child to first child (highp 2-component vector of int)
+0:102        'v2' (highp 2-component vector of int)
+0:102        Function Call: textureSize(s21; (highp 2-component vector of int)
+0:102          's2dms' (uniform highp sampler2DMS)
+0:103      move second child to first child (highp 2-component vector of int)
+0:103        'v2' (highp 2-component vector of int)
+0:103        Function Call: imageSize(I21; (highp 2-component vector of int)
+0:103          'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:104      move second child to first child (highp 3-component vector of int)
+0:104        'v3' (highp 3-component vector of int)
+0:104        Function Call: imageSize(I31; (highp 3-component vector of int)
+0:104          'i3D' (layout(binding=4 ) readonly uniform mediump image3D)
+0:105      move second child to first child (highp 2-component vector of int)
+0:105        'v2' (highp 2-component vector of int)
+0:105        Function Call: imageSize(IC1; (highp 2-component vector of int)
+0:105          'iCube' (layout(binding=5 ) uniform lowp imageCube)
+0:106      move second child to first child (highp 3-component vector of int)
+0:106        'v3' (highp 3-component vector of int)
+0:106        Function Call: imageSize(IA21; (highp 3-component vector of int)
+0:106          'i2DA' (layout(binding=6 ) uniform mediump image2DArray)
+0:107      move second child to first child (highp 2-component vector of int)
+0:107        'v2' (highp 2-component vector of int)
+0:107        Function Call: imageSize(I21; (highp 2-component vector of int)
+0:107          'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
@@ -252,6 +278,10 @@ ERROR: node is still EOpNull!
 0:?     's1' (layout(binding=3 ) uniform highp sampler2D)
 0:?     's2' (layout(binding=3 ) uniform highp sampler2D)
 0:?     'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:?     'i3D' (layout(binding=4 ) readonly uniform mediump image3D)
+0:?     'iCube' (layout(binding=5 ) uniform lowp imageCube)
+0:?     'i2DA' (layout(binding=6 ) uniform mediump image2DArray)
+0:?     'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
 0:?     'bbi' (layout(binding=1 column_major shared ) uniform block{layout(column_major shared ) uniform mediump int foo, layout(binding=2 column_major shared ) uniform mediump float f})
 0:?     'centroidIn' (centroid smooth in mediump 4-component vector of float)
 0:?     'bigl' (uniform mediump 4-component vector of float)
@@ -455,31 +485,47 @@ ERROR: node is still EOpNull!
 0:60              'i' (uniform mediump int)
 0:60            Construct bvec4 (4-component vector of bool)
 0:60              'b' (bool)
-0:94  Function Definition: foots( (void)
-0:94    Function Parameters: 
-0:96    Sequence
-0:96      Sequence
-0:96        move second child to first child (highp 2-component vector of int)
-0:96          'v2' (highp 2-component vector of int)
-0:96          Function Call: textureSize(s21;i1; (highp 2-component vector of int)
-0:96            's1' (layout(binding=3 ) uniform highp sampler2D)
-0:96            Constant:
-0:96              2 (const int)
-0:97      Sequence
-0:97        move second child to first child (highp 3-component vector of int)
-0:97          'v3' (highp 3-component vector of int)
-0:97          Function Call: textureSize(isA21;i1; (highp 3-component vector of int)
-0:97            'isamp2DA' (uniform highp isampler2DArray)
-0:97            Constant:
-0:97              3 (const int)
-0:98      move second child to first child (highp 2-component vector of int)
-0:98        'v2' (highp 2-component vector of int)
-0:98        Function Call: textureSize(s21; (highp 2-component vector of int)
-0:98          's2dms' (uniform highp sampler2DMS)
-0:99      move second child to first child (highp 2-component vector of int)
-0:99        'v2' (highp 2-component vector of int)
-0:99        Function Call: imageSize(I21; (highp 2-component vector of int)
-0:99          'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:98  Function Definition: foots( (void)
+0:98    Function Parameters: 
+0:100    Sequence
+0:100      Sequence
+0:100        move second child to first child (highp 2-component vector of int)
+0:100          'v2' (highp 2-component vector of int)
+0:100          Function Call: textureSize(s21;i1; (highp 2-component vector of int)
+0:100            's1' (layout(binding=3 ) uniform highp sampler2D)
+0:100            Constant:
+0:100              2 (const int)
+0:101      Sequence
+0:101        move second child to first child (highp 3-component vector of int)
+0:101          'v3' (highp 3-component vector of int)
+0:101          Function Call: textureSize(isA21;i1; (highp 3-component vector of int)
+0:101            'isamp2DA' (uniform highp isampler2DArray)
+0:101            Constant:
+0:101              3 (const int)
+0:102      move second child to first child (highp 2-component vector of int)
+0:102        'v2' (highp 2-component vector of int)
+0:102        Function Call: textureSize(s21; (highp 2-component vector of int)
+0:102          's2dms' (uniform highp sampler2DMS)
+0:103      move second child to first child (highp 2-component vector of int)
+0:103        'v2' (highp 2-component vector of int)
+0:103        Function Call: imageSize(I21; (highp 2-component vector of int)
+0:103          'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:104      move second child to first child (highp 3-component vector of int)
+0:104        'v3' (highp 3-component vector of int)
+0:104        Function Call: imageSize(I31; (highp 3-component vector of int)
+0:104          'i3D' (layout(binding=4 ) readonly uniform mediump image3D)
+0:105      move second child to first child (highp 2-component vector of int)
+0:105        'v2' (highp 2-component vector of int)
+0:105        Function Call: imageSize(IC1; (highp 2-component vector of int)
+0:105          'iCube' (layout(binding=5 ) uniform lowp imageCube)
+0:106      move second child to first child (highp 3-component vector of int)
+0:106        'v3' (highp 3-component vector of int)
+0:106        Function Call: imageSize(IA21; (highp 3-component vector of int)
+0:106          'i2DA' (layout(binding=6 ) uniform mediump image2DArray)
+0:107      move second child to first child (highp 2-component vector of int)
+0:107        'v2' (highp 2-component vector of int)
+0:107        Function Call: imageSize(I21; (highp 2-component vector of int)
+0:107          'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
@@ -494,6 +540,10 @@ ERROR: node is still EOpNull!
 0:?     's1' (layout(binding=3 ) uniform highp sampler2D)
 0:?     's2' (layout(binding=3 ) uniform highp sampler2D)
 0:?     'i2D' (layout(binding=2 ) writeonly uniform highp image2D)
+0:?     'i3D' (layout(binding=4 ) readonly uniform mediump image3D)
+0:?     'iCube' (layout(binding=5 ) uniform lowp imageCube)
+0:?     'i2DA' (layout(binding=6 ) uniform mediump image2DArray)
+0:?     'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
 0:?     'bbi' (layout(binding=1 column_major shared ) uniform block{layout(column_major shared ) uniform mediump int foo, layout(binding=2 column_major shared ) uniform mediump float f})
 0:?     'centroidIn' (centroid smooth in mediump 4-component vector of float)
 0:?     'bigl' (uniform mediump 4-component vector of float)
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 07e38b490..eb7de1bd3 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -418,29 +418,29 @@ void TBuiltIns::initialize(int version, EProfile profile)
     if (profile == EEsProfile && version >= 310 ||
         profile != EEsProfile && version >= 430) {
         commonBuiltins.append(
-            "uint atomicAdd(coherent inout uint, uint);"
-            " int atomicAdd(coherent inout  int,  int);"
+            "uint atomicAdd(coherent volatile restrict inout uint, uint);"
+            " int atomicAdd(coherent volatile restrict inout  int,  int);"
 
-            "uint atomicMin(coherent inout uint, uint);"
-            " int atomicMin(coherent inout  int,  int);"
+            "uint atomicMin(coherent volatile restrict inout uint, uint);"
+            " int atomicMin(coherent volatile restrict inout  int,  int);"
             
-            "uint atomicMax(coherent inout uint, uint);"
-            " int atomicMax(coherent inout  int,  int);"
+            "uint atomicMax(coherent volatile restrict inout uint, uint);"
+            " int atomicMax(coherent volatile restrict inout  int,  int);"
             
-            "uint atomicAnd(coherent inout uint, uint);"
-            " int atomicAnd(coherent inout  int,  int);"
+            "uint atomicAnd(coherent volatile restrict inout uint, uint);"
+            " int atomicAnd(coherent volatile restrict inout  int,  int);"
             
-            "uint atomicOr (coherent inout uint, uint);"
-            " int atomicOr (coherent inout  int,  int);"
+            "uint atomicOr (coherent volatile restrict inout uint, uint);"
+            " int atomicOr (coherent volatile restrict inout  int,  int);"
             
-            "uint atomicXor(coherent inout uint, uint);"
-            " int atomicXor(coherent inout  int,  int);"
+            "uint atomicXor(coherent volatile restrict inout uint, uint);"
+            " int atomicXor(coherent volatile restrict inout  int,  int);"
 
-            "uint atomicExchange(coherent inout uint, uint);"
-            " int atomicExchange(coherent inout  int,  int);"
+            "uint atomicExchange(coherent volatile restrict inout uint, uint);"
+            " int atomicExchange(coherent volatile restrict inout  int,  int);"
 
-            "uint atomicCompSwap(coherent inout uint, uint, uint);"
-            " int atomicCompSwap(coherent inout  int,  int,  int);"
+            "uint atomicCompSwap(coherent volatile restrict inout uint, uint, uint);"
+            " int atomicCompSwap(coherent volatile restrict inout  int,  int,  int);"
 
             "\n");
     }
@@ -1847,7 +1847,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
         commonBuiltins.append(postfixes[dims]);
     }
     if (sampler.image)
-        commonBuiltins.append(" imageSize(");
+        commonBuiltins.append(" imageSize(readonly writeonly volatile coherent restrict ");
     else
         commonBuiltins.append(" textureSize(");
     commonBuiltins.append(typeName);
@@ -1889,11 +1889,11 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
         imageParams.append(", int");
 
     commonBuiltins.append(prefixes[sampler.type]);
-    commonBuiltins.append("vec4 imageLoad(readonly ");
+    commonBuiltins.append("vec4 imageLoad(readonly volatile coherent restrict ");
     commonBuiltins.append(imageParams);
     commonBuiltins.append(");\n");
 
-    commonBuiltins.append("void imageStore(writeonly ");
+    commonBuiltins.append("void imageStore(writeonly volatile coherent restrict ");
     commonBuiltins.append(imageParams);
     commonBuiltins.append(", ");
     commonBuiltins.append(prefixes[sampler.type]);
@@ -1906,20 +1906,18 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
             const int numBuiltins = 7;
 
             static const char* atomicFunc[numBuiltins] = {
-                " imageAtomicAdd(",
-                " imageAtomicMin(",
-                " imageAtomicMax(",
-                " imageAtomicAnd(",
-                " imageAtomicOr(",
-                " imageAtomicXor(",
-                " imageAtomicExchange("
+                " imageAtomicAdd(volatile coherent restrict ",
+                " imageAtomicMin(volatile coherent restrict ",
+                " imageAtomicMax(volatile coherent restrict ",
+                " imageAtomicAnd(volatile coherent restrict ",
+                " imageAtomicOr(volatile coherent restrict ",
+                " imageAtomicXor(volatile coherent restrict ",
+                " imageAtomicExchange(volatile coherent restrict "
             }; 
 
             for (size_t i = 0; i < numBuiltins; ++i) {
                 commonBuiltins.append(dataType);
                 commonBuiltins.append(atomicFunc[i]);
-                if (version >= 450)
-                    commonBuiltins.append("coherent ");
                 commonBuiltins.append(imageParams);
                 commonBuiltins.append(", ");
                 commonBuiltins.append(dataType);
@@ -1927,7 +1925,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
             }
 
             commonBuiltins.append(dataType);
-            commonBuiltins.append(" imageAtomicCompSwap(");
+            commonBuiltins.append(" imageAtomicCompSwap(volatile coherent restrict ");
             commonBuiltins.append(imageParams);
             commonBuiltins.append(", ");
             commonBuiltins.append(dataType);
@@ -1939,7 +1937,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
             // GL_ARB_ES3_1_compatibility
             // TODO: spec issue: are there restrictions on the kind of layout() that can be used?  what about dropping memory qualifiers?
             if (version >= 450) {
-                commonBuiltins.append("float imageAtomicExchange(coherent ");
+                commonBuiltins.append("float imageAtomicExchange(volatile coherent restrict ");
                 commonBuiltins.append(imageParams);
                 commonBuiltins.append(", float);\n");
             }
-- 
GitLab