Add ES 3.1 compatibility to 4.5 and the atomic memory functions (e.g. atomicAdd).
authorJohn Kessenich <cepheus@frii.com>
Wed, 13 Aug 2014 08:32:15 +0000 (08:32 +0000)
committerJohn Kessenich <cepheus@frii.com>
Wed, 13 Aug 2014 08:32:15 +0000 (08:32 +0000)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27715 e7fa87d3-cd2b-0410-9028-fcbf551c1848

Test/310.comp
Test/310.frag
Test/450.frag
Test/baseResults/310.comp.out
Test/baseResults/310.frag.out
Test/baseResults/450.frag.out
glslang/Include/intermediate.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/linkValidate.cpp

index 345224f..7c010ea 100644 (file)
@@ -150,3 +150,14 @@ void opac()
     countArr[2];\r
     countArr[i];\r
 }\r
+\r
+shared int atomi;\r
+shared uint atomu;\r
+\r
+void atoms()\r
+{\r
+    int origi = atomicAdd(atomi, 3);\r
+    uint origu = atomicAnd(atomu, 7u);\r
+    origi = atomicExchange(atomi, 4);\r
+    origu = atomicCompSwap(atomu, 10u, 8u);\r
+}\r
index 7399159..183d911 100644 (file)
@@ -43,4 +43,19 @@ void foo23()
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[1]);\r
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[2]);     // ERROR, offset out of range\r
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range\r
+\r
+    if (gl_HelperInvocation)\r
+        ++outp;\r
+\r
+    int sum = gl_MaxVertexImageUniforms +\r
+              gl_MaxFragmentImageUniforms +\r
+              gl_MaxComputeImageUniforms +\r
+              gl_MaxCombinedImageUniforms +\r
+              gl_MaxCombinedShaderOutputResources;\r
+\r
+    bool b1, b2, b3, b;\r
+\r
+    b1 = mix(b2, b3, b);\r
+    uvec3 um3 = mix(uvec3(i), uvec3(i), bvec3(b));\r
+    ivec4 im4 = mix(ivec4(i), ivec4(i), bvec4(b));\r
 }\r
index 73f497e..b321dc1 100644 (file)
@@ -17,4 +17,19 @@ void main()
 \r
     float cull = gl_CullDistance[2];\r
     float consts = gl_MaxCullDistances + gl_MaxCombinedClipAndCullDistances;\r
+\r
+    if (gl_HelperInvocation)\r
+        ++v4;\r
+\r
+    int sum = gl_MaxVertexImageUniforms +\r
+              gl_MaxFragmentImageUniforms +\r
+              gl_MaxComputeImageUniforms +\r
+              gl_MaxCombinedImageUniforms +\r
+              gl_MaxCombinedShaderOutputResources;\r
+\r
+    bool b1, b3, b;\r
+    uint uin;\r
+    bvec2 b2 = mix(bvec2(b1), bvec2(b3), bvec2(b));\r
+    uint um = mix(uin, uin, b);\r
+    ivec3 im3 = mix(ivec3(uin), ivec3(uin), bvec3(b));\r
 }\r
index 9f7040d..97cca31 100644 (file)
@@ -187,6 +187,37 @@ ERROR: node is still EOpNull!
 0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)\r
 0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
 0:151        'i' (uniform highp int)\r
+0:157  Function Definition: atoms( (void)\r
+0:157    Function Parameters: \r
+0:159    Sequence\r
+0:159      Sequence\r
+0:159        move second child to first child (highp int)\r
+0:159          'origi' (highp int)\r
+0:159          Function Call: atomicAdd(i1;i1; (highp int)\r
+0:159            'atomi' (shared highp int)\r
+0:159            Constant:\r
+0:159              3 (const int)\r
+0:160      Sequence\r
+0:160        move second child to first child (highp uint)\r
+0:160          'origu' (highp uint)\r
+0:160          Function Call: atomicAnd(u1;u1; (highp uint)\r
+0:160            'atomu' (shared highp uint)\r
+0:160            Constant:\r
+0:160              7 (const uint)\r
+0:161      move second child to first child (highp int)\r
+0:161        'origi' (highp int)\r
+0:161        Function Call: atomicExchange(i1;i1; (highp int)\r
+0:161          'atomi' (shared highp int)\r
+0:161          Constant:\r
+0:161            4 (const int)\r
+0:162      move second child to first child (highp uint)\r
+0:162        'origu' (highp uint)\r
+0:162        Function Call: atomicCompSwap(u1;u1;u1; (highp uint)\r
+0:162          'atomu' (shared highp uint)\r
+0:162          Constant:\r
+0:162            10 (const uint)\r
+0:162          Constant:\r
+0:162            8 (const uint)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -229,6 +260,8 @@ ERROR: node is still EOpNull!
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
 0:?     'i' (uniform highp int)\r
+0:?     'atomi' (shared highp int)\r
+0:?     'atomu' (shared highp uint)\r
 \r
 \r
 Linked compute stage:\r
@@ -376,6 +409,37 @@ ERROR: node is still EOpNull!
 0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)\r
 0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
 0:151        'i' (uniform highp int)\r
+0:157  Function Definition: atoms( (void)\r
+0:157    Function Parameters: \r
+0:159    Sequence\r
+0:159      Sequence\r
+0:159        move second child to first child (highp int)\r
+0:159          'origi' (highp int)\r
+0:159          Function Call: atomicAdd(i1;i1; (highp int)\r
+0:159            'atomi' (shared highp int)\r
+0:159            Constant:\r
+0:159              3 (const int)\r
+0:160      Sequence\r
+0:160        move second child to first child (highp uint)\r
+0:160          'origu' (highp uint)\r
+0:160          Function Call: atomicAnd(u1;u1; (highp uint)\r
+0:160            'atomu' (shared highp uint)\r
+0:160            Constant:\r
+0:160              7 (const uint)\r
+0:161      move second child to first child (highp int)\r
+0:161        'origi' (highp int)\r
+0:161        Function Call: atomicExchange(i1;i1; (highp int)\r
+0:161          'atomi' (shared highp int)\r
+0:161          Constant:\r
+0:161            4 (const int)\r
+0:162      move second child to first child (highp uint)\r
+0:162        'origu' (highp uint)\r
+0:162        Function Call: atomicCompSwap(u1;u1;u1; (highp uint)\r
+0:162          'atomu' (shared highp uint)\r
+0:162          Constant:\r
+0:162            10 (const uint)\r
+0:162          Constant:\r
+0:162            8 (const uint)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -418,4 +482,6 @@ ERROR: node is still EOpNull!
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
 0:?     'i' (uniform highp int)\r
+0:?     'atomi' (shared highp int)\r
+0:?     'atomu' (shared highp uint)\r
 \r
index 1057528..eb7b53c 100644 (file)
@@ -153,6 +153,45 @@ ERROR: node is still EOpNull!
 0:45        Constant:\r
 0:45          -10 (const int)\r
 0:45          20 (const int)\r
+0:47      Test condition and select (void)\r
+0:47        Condition\r
+0:47        'gl_HelperInvocation' (in bool)\r
+0:47        true case\r
+0:48        Pre-Increment (mediump 4-component vector of float)\r
+0:48          'outp' (out mediump 4-component vector of float)\r
+0:50      Sequence\r
+0:50        move second child to first child (mediump int)\r
+0:50          'sum' (mediump int)\r
+0:50          Constant:\r
+0:50            32 (const int)\r
+0:58      move second child to first child (bool)\r
+0:58        'b1' (bool)\r
+0:58        mix (bool)\r
+0:58          'b2' (bool)\r
+0:58          'b3' (bool)\r
+0:58          'b' (bool)\r
+0:59      Sequence\r
+0:59        move second child to first child (mediump 3-component vector of uint)\r
+0:59          'um3' (mediump 3-component vector of uint)\r
+0:59          mix (mediump 3-component vector of uint)\r
+0:59            Construct uvec3 (mediump 3-component vector of uint)\r
+0:59              Convert int to uint (mediump uint)\r
+0:59                'i' (uniform mediump int)\r
+0:59            Construct uvec3 (mediump 3-component vector of uint)\r
+0:59              Convert int to uint (mediump uint)\r
+0:59                'i' (uniform mediump int)\r
+0:59            Construct bvec3 (3-component vector of bool)\r
+0:59              'b' (bool)\r
+0:60      Sequence\r
+0:60        move second child to first child (mediump 4-component vector of int)\r
+0:60          'im4' (mediump 4-component vector of int)\r
+0:60          mix (mediump 4-component vector of int)\r
+0:60            Construct ivec4 (mediump 4-component vector of int)\r
+0:60              'i' (uniform mediump int)\r
+0:60            Construct ivec4 (mediump 4-component vector of int)\r
+0:60              'i' (uniform mediump int)\r
+0:60            Construct bvec4 (4-component vector of bool)\r
+0:60              'b' (bool)\r
 0:?   Linker Objects\r
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)\r
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)\r
@@ -303,6 +342,45 @@ ERROR: node is still EOpNull!
 0:45        Constant:\r
 0:45          -10 (const int)\r
 0:45          20 (const int)\r
+0:47      Test condition and select (void)\r
+0:47        Condition\r
+0:47        'gl_HelperInvocation' (in bool)\r
+0:47        true case\r
+0:48        Pre-Increment (mediump 4-component vector of float)\r
+0:48          'outp' (out mediump 4-component vector of float)\r
+0:50      Sequence\r
+0:50        move second child to first child (mediump int)\r
+0:50          'sum' (mediump int)\r
+0:50          Constant:\r
+0:50            32 (const int)\r
+0:58      move second child to first child (bool)\r
+0:58        'b1' (bool)\r
+0:58        mix (bool)\r
+0:58          'b2' (bool)\r
+0:58          'b3' (bool)\r
+0:58          'b' (bool)\r
+0:59      Sequence\r
+0:59        move second child to first child (mediump 3-component vector of uint)\r
+0:59          'um3' (mediump 3-component vector of uint)\r
+0:59          mix (mediump 3-component vector of uint)\r
+0:59            Construct uvec3 (mediump 3-component vector of uint)\r
+0:59              Convert int to uint (mediump uint)\r
+0:59                'i' (uniform mediump int)\r
+0:59            Construct uvec3 (mediump 3-component vector of uint)\r
+0:59              Convert int to uint (mediump uint)\r
+0:59                'i' (uniform mediump int)\r
+0:59            Construct bvec3 (3-component vector of bool)\r
+0:59              'b' (bool)\r
+0:60      Sequence\r
+0:60        move second child to first child (mediump 4-component vector of int)\r
+0:60          'im4' (mediump 4-component vector of int)\r
+0:60          mix (mediump 4-component vector of int)\r
+0:60            Construct ivec4 (mediump 4-component vector of int)\r
+0:60              'i' (uniform mediump int)\r
+0:60            Construct ivec4 (mediump 4-component vector of int)\r
+0:60              'i' (uniform mediump int)\r
+0:60            Construct bvec4 (4-component vector of bool)\r
+0:60              'b' (bool)\r
 0:?   Linker Objects\r
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)\r
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)\r
index a928c29..4f52569 100644 (file)
@@ -59,6 +59,46 @@ Shader version: 450
 0:19          'consts' (float)\r
 0:19          Constant:\r
 0:19            16.000000\r
+0:21      Test condition and select (void)\r
+0:21        Condition\r
+0:21        'gl_HelperInvocation' (in bool)\r
+0:21        true case\r
+0:22        Pre-Increment (4-component vector of float)\r
+0:22          'v4' (4-component vector of float)\r
+0:24      Sequence\r
+0:24        move second child to first child (int)\r
+0:24          'sum' (int)\r
+0:24          Constant:\r
+0:24            32 (const int)\r
+0:32      Sequence\r
+0:32        move second child to first child (2-component vector of bool)\r
+0:32          'b2' (2-component vector of bool)\r
+0:32          mix (2-component vector of bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b1' (bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b3' (bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b' (bool)\r
+0:33      Sequence\r
+0:33        move second child to first child (uint)\r
+0:33          'um' (uint)\r
+0:33          mix (uint)\r
+0:33            'uin' (uint)\r
+0:33            'uin' (uint)\r
+0:33            'b' (bool)\r
+0:34      Sequence\r
+0:34        move second child to first child (3-component vector of int)\r
+0:34          'im3' (3-component vector of int)\r
+0:34          mix (3-component vector of int)\r
+0:34            Construct ivec3 (3-component vector of int)\r
+0:34              Convert uint to int (int)\r
+0:34                'uin' (uint)\r
+0:34            Construct ivec3 (3-component vector of int)\r
+0:34              Convert uint to int (int)\r
+0:34                'uin' (uint)\r
+0:34            Construct bvec3 (3-component vector of bool)\r
+0:34              'b' (bool)\r
 0:?   Linker Objects\r
 0:?     'in1' (smooth in float)\r
 0:?     'in2' (smooth in 2-component vector of float)\r
@@ -128,6 +168,46 @@ Shader version: 450
 0:19          'consts' (float)\r
 0:19          Constant:\r
 0:19            16.000000\r
+0:21      Test condition and select (void)\r
+0:21        Condition\r
+0:21        'gl_HelperInvocation' (in bool)\r
+0:21        true case\r
+0:22        Pre-Increment (4-component vector of float)\r
+0:22          'v4' (4-component vector of float)\r
+0:24      Sequence\r
+0:24        move second child to first child (int)\r
+0:24          'sum' (int)\r
+0:24          Constant:\r
+0:24            32 (const int)\r
+0:32      Sequence\r
+0:32        move second child to first child (2-component vector of bool)\r
+0:32          'b2' (2-component vector of bool)\r
+0:32          mix (2-component vector of bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b1' (bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b3' (bool)\r
+0:32            Construct bvec2 (2-component vector of bool)\r
+0:32              'b' (bool)\r
+0:33      Sequence\r
+0:33        move second child to first child (uint)\r
+0:33          'um' (uint)\r
+0:33          mix (uint)\r
+0:33            'uin' (uint)\r
+0:33            'uin' (uint)\r
+0:33            'b' (bool)\r
+0:34      Sequence\r
+0:34        move second child to first child (3-component vector of int)\r
+0:34          'im3' (3-component vector of int)\r
+0:34          mix (3-component vector of int)\r
+0:34            Construct ivec3 (3-component vector of int)\r
+0:34              Convert uint to int (int)\r
+0:34                'uin' (uint)\r
+0:34            Construct ivec3 (3-component vector of int)\r
+0:34              Convert uint to int (int)\r
+0:34                'uin' (uint)\r
+0:34            Construct bvec3 (3-component vector of bool)\r
+0:34              'b' (bool)\r
 0:?   Linker Objects\r
 0:?     'in1' (smooth in float)\r
 0:?     'in2' (smooth in 2-component vector of float)\r
index 19e0c41..0647a76 100644 (file)
@@ -234,6 +234,15 @@ enum TOperator {
     EOpMemoryBarrierShared,  // compute only
     EOpGroupMemoryBarrier,   // compute only
 
+    EOpAtomicAdd,            // TODO: AST functionality: hook these up
+    EOpAtomicMin,
+    EOpAtomicMax,
+    EOpAtomicAnd,
+    EOpAtomicOr,
+    EOpAtomicXor,
+    EOpAtomicExchange,
+    EOpAtomicCompSwap,
+
     EOpAny,
     EOpAll,
 
index 7780576..8f363d9 100644 (file)
@@ -372,7 +372,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "ivec2 max(ivec2  x, ivec2  y);"
             "ivec3 max(ivec3  x, ivec3  y);"
             "ivec4 max(ivec4  x, ivec4  y);"
-                     
+
             " uint max(uint   x, uint y);"
             "uvec2 max(uvec2  x, uint y);"
             "uvec3 max(uvec3  x, uint y);"
@@ -380,7 +380,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "uvec2 max(uvec2  x, uvec2  y);"
             "uvec3 max(uvec3  x, uvec3  y);"
             "uvec4 max(uvec4  x, uvec4  y);"
-                     
+
             "int    clamp(int x, int minVal, int maxVal);"
             "ivec2  clamp(ivec2  x, int minVal, int maxVal);"
             "ivec3  clamp(ivec3  x, int minVal, int maxVal);"
@@ -388,7 +388,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "ivec2  clamp(ivec2  x, ivec2  minVal, ivec2  maxVal);"
             "ivec3  clamp(ivec3  x, ivec3  minVal, ivec3  maxVal);"
             "ivec4  clamp(ivec4  x, ivec4  minVal, ivec4  maxVal);"
-                     
+
             "uint   clamp(uint x, uint minVal, uint maxVal);"
             "uvec2  clamp(uvec2  x, uint minVal, uint maxVal);"
             "uvec3  clamp(uvec3  x, uint minVal, uint maxVal);"
@@ -396,22 +396,73 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "uvec2  clamp(uvec2  x, uvec2  minVal, uvec2  maxVal);"
             "uvec3  clamp(uvec3  x, uvec3  minVal, uvec3  maxVal);"
             "uvec4  clamp(uvec4  x, uvec4  minVal, uvec4  maxVal);"
-                     
+
             "float mix(float x, float y, bool  a);"
             "vec2  mix(vec2  x, vec2  y, bvec2 a);"
             "vec3  mix(vec3  x, vec3  y, bvec3 a);"
             "vec4  mix(vec4  x, vec4  y, bvec4 a);"
-                     
+
             "bool  isnan(float x);"
             "bvec2 isnan(vec2  x);"
             "bvec3 isnan(vec3  x);"
             "bvec4 isnan(vec4  x);"
-                     
+
             "bool  isinf(float x);"
             "bvec2 isinf(vec2  x);"
             "bvec3 isinf(vec3  x);"
             "bvec4 isinf(vec4  x);"
+
+            "\n");
+    }
+
+    if (profile == EEsProfile && version >= 310 ||
+        profile != EEsProfile && version >= 430) {
+        commonBuiltins.append(
+            "uint atomicAdd(coherent inout uint, uint);"
+            " int atomicAdd(coherent inout  int,  int);"
+
+            "uint atomicMin(coherent inout uint, uint);"
+            " int atomicMin(coherent inout  int,  int);"
+            
+            "uint atomicMax(coherent inout uint, uint);"
+            " int atomicMax(coherent inout  int,  int);"
+            
+            "uint atomicAnd(coherent inout uint, uint);"
+            " int atomicAnd(coherent inout  int,  int);"
             
+            "uint atomicOr (coherent inout uint, uint);"
+            " int atomicOr (coherent inout  int,  int);"
+            
+            "uint atomicXor(coherent inout uint, uint);"
+            " int atomicXor(coherent inout  int,  int);"
+
+            "uint atomicExchange(coherent inout uint, uint);"
+            " int atomicExchange(coherent inout  int,  int);"
+
+            "uint atomicCompSwap(coherent inout uint, uint, uint);"
+            " int atomicCompSwap(coherent inout  int,  int,  int);"
+
+            "\n");
+    }
+
+    if (profile == EEsProfile && version >= 310 ||
+        profile != EEsProfile && version >= 450) {
+        commonBuiltins.append(
+            "int    mix(int    x, int    y, bool  a);"
+            "ivec2  mix(ivec2  x, ivec2  y, bvec2 a);"
+            "ivec3  mix(ivec3  x, ivec3  y, bvec3 a);"
+            "ivec4  mix(ivec4  x, ivec4  y, bvec4 a);"
+
+            "uint   mix(uint   x, uint   y, bool  a);"
+            "uvec2  mix(uvec2  x, uvec2  y, bvec2 a);"
+            "uvec3  mix(uvec3  x, uvec3  y, bvec3 a);"
+            "uvec4  mix(uvec4  x, uvec4  y, bvec4 a);"
+
+            "bool   mix(bool   x, bool   y, bool  a);"
+            "bvec2  mix(bvec2  x, bvec2  y, bvec2 a);"
+            "bvec3  mix(bvec3  x, bvec3  y, bvec3 a);"
+            "bvec4  mix(bvec4  x, bvec4  y, bvec4 a);"
+
             "\n");
     }
 
@@ -2238,26 +2289,16 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
 
         // images
         if (version >= 130) {
-            snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.maxCombinedImageUnitsAndFragmentOutputs);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.maxImageSamples);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms);
             s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms);
             s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms);
-            s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms);
-            s.append(builtInConstant);
         }
 
         // enhanced layouts
@@ -2269,6 +2310,21 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
         }
     }
 
+    // images (some in compute below)
+    if (profile == EEsProfile && version >= 310 || profile != EEsProfile && version >= 130) {
+        snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms);
+        s.append(builtInConstant);
+    }
+
+    // atomic counters (some in compute below)
     if (profile == EEsProfile && version >= 310 || profile != EEsProfile && version >= 420) {
         snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.               maxVertexAtomicCounters);
         s.append(builtInConstant);
index bdbe775..eb8c523 100644 (file)
@@ -994,6 +994,11 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
                             error(arguments->getLoc(), message, "writeonly", "");
                     }
+                    // TODO 4.5 functionality:  A shader will fail to compile 
+                    // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
+                    // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the 
+                    // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or 
+                    // shared variable.
                 }
 
                 // Convert 'in' arguments
index 310350d..9361bdc 100644 (file)
@@ -229,6 +229,8 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
     }\r
 }\r
 \r
+// TODO 4.5 link functionality: cull distance array size checking\r
+\r
 // Recursively merge the implicit array sizes through the objects' respective type trees.\r
 void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)\r
 {\r