From df1d81a958a56e8dbcc0785fcd799dcb6a5d86b8 Mon Sep 17 00:00:00 2001 From: John Kessenich <cepheus@frii.com> Date: Wed, 13 Aug 2014 08:32:15 +0000 Subject: [PATCH] Add ES 3.1 compatibility to 4.5 and the atomic memory functions (e.g. atomicAdd). 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 | 11 +++ Test/310.frag | 15 ++++ Test/450.frag | 15 ++++ Test/baseResults/310.comp.out | 66 ++++++++++++++++ Test/baseResults/310.frag.out | 78 ++++++++++++++++++ Test/baseResults/450.frag.out | 80 +++++++++++++++++++ glslang/Include/intermediate.h | 9 +++ glslang/MachineIndependent/Initialize.cpp | 88 +++++++++++++++++---- glslang/MachineIndependent/ParseHelper.cpp | 5 ++ glslang/MachineIndependent/linkValidate.cpp | 2 + 10 files changed, 353 insertions(+), 16 deletions(-) diff --git a/Test/310.comp b/Test/310.comp index 345224f22..7c010ead6 100644 --- a/Test/310.comp +++ b/Test/310.comp @@ -150,3 +150,14 @@ void opac() countArr[2]; countArr[i]; } + +shared int atomi; +shared uint atomu; + +void atoms() +{ + int origi = atomicAdd(atomi, 3); + uint origu = atomicAnd(atomu, 7u); + origi = atomicExchange(atomi, 4); + origu = atomicCompSwap(atomu, 10u, 8u); +} diff --git a/Test/310.frag b/Test/310.frag index 7399159ef..183d91130 100644 --- a/Test/310.frag +++ b/Test/310.frag @@ -43,4 +43,19 @@ void foo23() textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[1]); textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[2]); // ERROR, offset out of range textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range + + if (gl_HelperInvocation) + ++outp; + + int sum = gl_MaxVertexImageUniforms + + gl_MaxFragmentImageUniforms + + gl_MaxComputeImageUniforms + + gl_MaxCombinedImageUniforms + + gl_MaxCombinedShaderOutputResources; + + bool b1, b2, b3, b; + + b1 = mix(b2, b3, b); + uvec3 um3 = mix(uvec3(i), uvec3(i), bvec3(b)); + ivec4 im4 = mix(ivec4(i), ivec4(i), bvec4(b)); } diff --git a/Test/450.frag b/Test/450.frag index 73f497eca..b321dc131 100644 --- a/Test/450.frag +++ b/Test/450.frag @@ -17,4 +17,19 @@ void main() float cull = gl_CullDistance[2]; float consts = gl_MaxCullDistances + gl_MaxCombinedClipAndCullDistances; + + if (gl_HelperInvocation) + ++v4; + + int sum = gl_MaxVertexImageUniforms + + gl_MaxFragmentImageUniforms + + gl_MaxComputeImageUniforms + + gl_MaxCombinedImageUniforms + + gl_MaxCombinedShaderOutputResources; + + bool b1, b3, b; + uint uin; + bvec2 b2 = mix(bvec2(b1), bvec2(b3), bvec2(b)); + uint um = mix(uin, uin, b); + ivec3 im3 = mix(ivec3(uin), ivec3(uin), bvec3(b)); } diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out index 9f7040d83..97cca31c9 100644 --- a/Test/baseResults/310.comp.out +++ b/Test/baseResults/310.comp.out @@ -187,6 +187,37 @@ ERROR: node is still EOpNull! 0:151 indirect index (layout(binding=2 offset=4 ) highp atomic_uint) 0:151 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) 0:151 'i' (uniform highp int) +0:157 Function Definition: atoms( (void) +0:157 Function Parameters: +0:159 Sequence +0:159 Sequence +0:159 move second child to first child (highp int) +0:159 'origi' (highp int) +0:159 Function Call: atomicAdd(i1;i1; (highp int) +0:159 'atomi' (shared highp int) +0:159 Constant: +0:159 3 (const int) +0:160 Sequence +0:160 move second child to first child (highp uint) +0:160 'origu' (highp uint) +0:160 Function Call: atomicAnd(u1;u1; (highp uint) +0:160 'atomu' (shared highp uint) +0:160 Constant: +0:160 7 (const uint) +0:161 move second child to first child (highp int) +0:161 'origi' (highp int) +0:161 Function Call: atomicExchange(i1;i1; (highp int) +0:161 'atomi' (shared highp int) +0:161 Constant: +0:161 4 (const int) +0:162 move second child to first child (highp uint) +0:162 'origu' (highp uint) +0:162 Function Call: atomicCompSwap(u1;u1;u1; (highp uint) +0:162 'atomu' (shared highp uint) +0:162 Constant: +0:162 10 (const uint) +0:162 Constant: +0:162 8 (const uint) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const highp 3-component vector of uint) 0:? 2 (const uint) @@ -229,6 +260,8 @@ ERROR: node is still EOpNull! 0:? 'counterBad' (layout(binding=1 ) uniform mediump atomic_uint) 0:? 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) 0:? 'i' (uniform highp int) +0:? 'atomi' (shared highp int) +0:? 'atomu' (shared highp uint) Linked compute stage: @@ -376,6 +409,37 @@ ERROR: node is still EOpNull! 0:151 indirect index (layout(binding=2 offset=4 ) highp atomic_uint) 0:151 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) 0:151 'i' (uniform highp int) +0:157 Function Definition: atoms( (void) +0:157 Function Parameters: +0:159 Sequence +0:159 Sequence +0:159 move second child to first child (highp int) +0:159 'origi' (highp int) +0:159 Function Call: atomicAdd(i1;i1; (highp int) +0:159 'atomi' (shared highp int) +0:159 Constant: +0:159 3 (const int) +0:160 Sequence +0:160 move second child to first child (highp uint) +0:160 'origu' (highp uint) +0:160 Function Call: atomicAnd(u1;u1; (highp uint) +0:160 'atomu' (shared highp uint) +0:160 Constant: +0:160 7 (const uint) +0:161 move second child to first child (highp int) +0:161 'origi' (highp int) +0:161 Function Call: atomicExchange(i1;i1; (highp int) +0:161 'atomi' (shared highp int) +0:161 Constant: +0:161 4 (const int) +0:162 move second child to first child (highp uint) +0:162 'origu' (highp uint) +0:162 Function Call: atomicCompSwap(u1;u1;u1; (highp uint) +0:162 'atomu' (shared highp uint) +0:162 Constant: +0:162 10 (const uint) +0:162 Constant: +0:162 8 (const uint) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const highp 3-component vector of uint) 0:? 2 (const uint) @@ -418,4 +482,6 @@ ERROR: node is still EOpNull! 0:? 'counterBad' (layout(binding=1 ) uniform mediump atomic_uint) 0:? 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) 0:? 'i' (uniform highp int) +0:? 'atomi' (shared highp int) +0:? 'atomu' (shared highp uint) diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out index 1057528bb..eb7b53c33 100644 --- a/Test/baseResults/310.frag.out +++ b/Test/baseResults/310.frag.out @@ -153,6 +153,45 @@ ERROR: node is still EOpNull! 0:45 Constant: 0:45 -10 (const int) 0:45 20 (const int) +0:47 Test condition and select (void) +0:47 Condition +0:47 'gl_HelperInvocation' (in bool) +0:47 true case +0:48 Pre-Increment (mediump 4-component vector of float) +0:48 'outp' (out mediump 4-component vector of float) +0:50 Sequence +0:50 move second child to first child (mediump int) +0:50 'sum' (mediump int) +0:50 Constant: +0:50 32 (const int) +0:58 move second child to first child (bool) +0:58 'b1' (bool) +0:58 mix (bool) +0:58 'b2' (bool) +0:58 'b3' (bool) +0:58 'b' (bool) +0:59 Sequence +0:59 move second child to first child (mediump 3-component vector of uint) +0:59 'um3' (mediump 3-component vector of uint) +0:59 mix (mediump 3-component vector of uint) +0:59 Construct uvec3 (mediump 3-component vector of uint) +0:59 Convert int to uint (mediump uint) +0:59 'i' (uniform mediump int) +0:59 Construct uvec3 (mediump 3-component vector of uint) +0:59 Convert int to uint (mediump uint) +0:59 'i' (uniform mediump int) +0:59 Construct bvec3 (3-component vector of bool) +0:59 'b' (bool) +0:60 Sequence +0:60 move second child to first child (mediump 4-component vector of int) +0:60 'im4' (mediump 4-component vector of int) +0:60 mix (mediump 4-component vector of int) +0:60 Construct ivec4 (mediump 4-component vector of int) +0:60 'i' (uniform mediump int) +0:60 Construct ivec4 (mediump 4-component vector of int) +0:60 'i' (uniform mediump int) +0:60 Construct bvec4 (4-component vector of bool) +0:60 'b' (bool) 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) @@ -303,6 +342,45 @@ ERROR: node is still EOpNull! 0:45 Constant: 0:45 -10 (const int) 0:45 20 (const int) +0:47 Test condition and select (void) +0:47 Condition +0:47 'gl_HelperInvocation' (in bool) +0:47 true case +0:48 Pre-Increment (mediump 4-component vector of float) +0:48 'outp' (out mediump 4-component vector of float) +0:50 Sequence +0:50 move second child to first child (mediump int) +0:50 'sum' (mediump int) +0:50 Constant: +0:50 32 (const int) +0:58 move second child to first child (bool) +0:58 'b1' (bool) +0:58 mix (bool) +0:58 'b2' (bool) +0:58 'b3' (bool) +0:58 'b' (bool) +0:59 Sequence +0:59 move second child to first child (mediump 3-component vector of uint) +0:59 'um3' (mediump 3-component vector of uint) +0:59 mix (mediump 3-component vector of uint) +0:59 Construct uvec3 (mediump 3-component vector of uint) +0:59 Convert int to uint (mediump uint) +0:59 'i' (uniform mediump int) +0:59 Construct uvec3 (mediump 3-component vector of uint) +0:59 Convert int to uint (mediump uint) +0:59 'i' (uniform mediump int) +0:59 Construct bvec3 (3-component vector of bool) +0:59 'b' (bool) +0:60 Sequence +0:60 move second child to first child (mediump 4-component vector of int) +0:60 'im4' (mediump 4-component vector of int) +0:60 mix (mediump 4-component vector of int) +0:60 Construct ivec4 (mediump 4-component vector of int) +0:60 'i' (uniform mediump int) +0:60 Construct ivec4 (mediump 4-component vector of int) +0:60 'i' (uniform mediump int) +0:60 Construct bvec4 (4-component vector of bool) +0:60 'b' (bool) 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) diff --git a/Test/baseResults/450.frag.out b/Test/baseResults/450.frag.out index a928c298d..4f5256910 100644 --- a/Test/baseResults/450.frag.out +++ b/Test/baseResults/450.frag.out @@ -59,6 +59,46 @@ Shader version: 450 0:19 'consts' (float) 0:19 Constant: 0:19 16.000000 +0:21 Test condition and select (void) +0:21 Condition +0:21 'gl_HelperInvocation' (in bool) +0:21 true case +0:22 Pre-Increment (4-component vector of float) +0:22 'v4' (4-component vector of float) +0:24 Sequence +0:24 move second child to first child (int) +0:24 'sum' (int) +0:24 Constant: +0:24 32 (const int) +0:32 Sequence +0:32 move second child to first child (2-component vector of bool) +0:32 'b2' (2-component vector of bool) +0:32 mix (2-component vector of bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b1' (bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b3' (bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b' (bool) +0:33 Sequence +0:33 move second child to first child (uint) +0:33 'um' (uint) +0:33 mix (uint) +0:33 'uin' (uint) +0:33 'uin' (uint) +0:33 'b' (bool) +0:34 Sequence +0:34 move second child to first child (3-component vector of int) +0:34 'im3' (3-component vector of int) +0:34 mix (3-component vector of int) +0:34 Construct ivec3 (3-component vector of int) +0:34 Convert uint to int (int) +0:34 'uin' (uint) +0:34 Construct ivec3 (3-component vector of int) +0:34 Convert uint to int (int) +0:34 'uin' (uint) +0:34 Construct bvec3 (3-component vector of bool) +0:34 'b' (bool) 0:? Linker Objects 0:? 'in1' (smooth in float) 0:? 'in2' (smooth in 2-component vector of float) @@ -128,6 +168,46 @@ Shader version: 450 0:19 'consts' (float) 0:19 Constant: 0:19 16.000000 +0:21 Test condition and select (void) +0:21 Condition +0:21 'gl_HelperInvocation' (in bool) +0:21 true case +0:22 Pre-Increment (4-component vector of float) +0:22 'v4' (4-component vector of float) +0:24 Sequence +0:24 move second child to first child (int) +0:24 'sum' (int) +0:24 Constant: +0:24 32 (const int) +0:32 Sequence +0:32 move second child to first child (2-component vector of bool) +0:32 'b2' (2-component vector of bool) +0:32 mix (2-component vector of bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b1' (bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b3' (bool) +0:32 Construct bvec2 (2-component vector of bool) +0:32 'b' (bool) +0:33 Sequence +0:33 move second child to first child (uint) +0:33 'um' (uint) +0:33 mix (uint) +0:33 'uin' (uint) +0:33 'uin' (uint) +0:33 'b' (bool) +0:34 Sequence +0:34 move second child to first child (3-component vector of int) +0:34 'im3' (3-component vector of int) +0:34 mix (3-component vector of int) +0:34 Construct ivec3 (3-component vector of int) +0:34 Convert uint to int (int) +0:34 'uin' (uint) +0:34 Construct ivec3 (3-component vector of int) +0:34 Convert uint to int (int) +0:34 'uin' (uint) +0:34 Construct bvec3 (3-component vector of bool) +0:34 'b' (bool) 0:? Linker Objects 0:? 'in1' (smooth in float) 0:? 'in2' (smooth in 2-component vector of float) diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 19e0c41b9..0647a7620 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -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, diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 778057681..8f363d989 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -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); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index bdbe7752f..eb8c5238a 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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 diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 310350d85..9361bdc45 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -229,6 +229,8 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin } } +// TODO 4.5 link functionality: cull distance array size checking + // Recursively merge the implicit array sizes through the objects' respective type trees. void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) { -- GitLab