[glslang] Refine implicit array size interfaces. (#3074)
authorChow <laddoc@outlook.com>
Tue, 13 Dec 2022 18:20:28 +0000 (02:20 +0800)
committerGitHub <noreply@github.com>
Tue, 13 Dec 2022 18:20:28 +0000 (11:20 -0700)
* [glslang] Refine implicit array size interfaces.

Help to check builtin and other variables if across stages.

14 files changed:
Test/baseResults/implicitArraySize.vert.out [new file with mode: 0644]
Test/baseResults/implicitArraySize1.geom.out [new file with mode: 0644]
Test/baseResults/implicitArraySizeBuiltin.vert.out [new file with mode: 0644]
Test/implicitArraySize.frag [new file with mode: 0644]
Test/implicitArraySize.vert [new file with mode: 0644]
Test/implicitArraySize1.geom [new file with mode: 0644]
Test/implicitArraySize2.geom [new file with mode: 0644]
Test/implicitArraySizeBuiltin.geom [new file with mode: 0644]
Test/implicitArraySizeBuiltin.vert [new file with mode: 0644]
glslang/Include/Types.h
glslang/Include/arrays.h
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/linkValidate.cpp
gtests/Link.FromFile.cpp

diff --git a/Test/baseResults/implicitArraySize.vert.out b/Test/baseResults/implicitArraySize.vert.out
new file mode 100644 (file)
index 0000000..9a71b87
--- /dev/null
@@ -0,0 +1,115 @@
+implicitArraySize.vert
+Shader version: 460
+0:? Sequence
+0:5  Function Definition: main( ( global void)
+0:5    Function Parameters: 
+0:6    Sequence
+0:6      move second child to first child ( temp float)
+0:6        direct index ( smooth temp float)
+0:6          'a' ( smooth out unsized 1-element array of float)
+0:6          Constant:
+0:6            0 (const int)
+0:6        Constant:
+0:6          0.100000
+0:7      move second child to first child ( temp float)
+0:7        direct index ( smooth temp float)
+0:7          'c' ( smooth out unsized 6-element array of float)
+0:7          Constant:
+0:7            5 (const int)
+0:7        Constant:
+0:7          0.100000
+0:?   Linker Objects
+0:?     'a' ( smooth out unsized 1-element array of float)
+0:?     'c' ( smooth out unsized 6-element array of float)
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+
+implicitArraySize.frag
+Shader version: 460
+0:? Sequence
+0:6  Function Definition: main( ( global void)
+0:6    Function Parameters: 
+0:7    Sequence
+0:7      move second child to first child ( temp float)
+0:7        direct index ( temp float)
+0:7          'b' ( out 5-element array of float)
+0:7          Constant:
+0:7            0 (const int)
+0:7        direct index ( smooth temp float)
+0:7          'a' ( smooth in unsized 2-element array of float)
+0:7          Constant:
+0:7            1 (const int)
+0:8      move second child to first child ( temp float)
+0:8        direct index ( temp float)
+0:8          'b' ( out 5-element array of float)
+0:8          Constant:
+0:8            1 (const int)
+0:8        direct index ( smooth temp float)
+0:8          'c' ( smooth in 3-element array of float)
+0:8          Constant:
+0:8            1 (const int)
+0:?   Linker Objects
+0:?     'a' ( smooth in unsized 2-element array of float)
+0:?     'c' ( smooth in 3-element array of float)
+0:?     'b' ( out 5-element array of float)
+
+
+Linked vertex stage:
+
+
+Linked fragment stage:
+
+ERROR: Linking vertex stage: Implicit size of unsized array doesn't match same symbol among multiple shaders.
+
+Shader version: 460
+0:? Sequence
+0:5  Function Definition: main( ( global void)
+0:5    Function Parameters: 
+0:6    Sequence
+0:6      move second child to first child ( temp float)
+0:6        direct index ( smooth temp float)
+0:6          'a' ( smooth out 1-element array of float)
+0:6          Constant:
+0:6            0 (const int)
+0:6        Constant:
+0:6          0.100000
+0:7      move second child to first child ( temp float)
+0:7        direct index ( smooth temp float)
+0:7          'c' ( smooth out 6-element array of float)
+0:7          Constant:
+0:7            5 (const int)
+0:7        Constant:
+0:7          0.100000
+0:?   Linker Objects
+0:?     'a' ( smooth out 1-element array of float)
+0:?     'c' ( smooth out 6-element array of float)
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+Shader version: 460
+0:? Sequence
+0:6  Function Definition: main( ( global void)
+0:6    Function Parameters: 
+0:7    Sequence
+0:7      move second child to first child ( temp float)
+0:7        direct index ( temp float)
+0:7          'b' ( out 5-element array of float)
+0:7          Constant:
+0:7            0 (const int)
+0:7        direct index ( smooth temp float)
+0:7          'a' ( smooth in 2-element array of float)
+0:7          Constant:
+0:7            1 (const int)
+0:8      move second child to first child ( temp float)
+0:8        direct index ( temp float)
+0:8          'b' ( out 5-element array of float)
+0:8          Constant:
+0:8            1 (const int)
+0:8        direct index ( smooth temp float)
+0:8          'c' ( smooth in 3-element array of float)
+0:8          Constant:
+0:8            1 (const int)
+0:?   Linker Objects
+0:?     'a' ( smooth in 2-element array of float)
+0:?     'c' ( smooth in 3-element array of float)
+0:?     'b' ( out 5-element array of float)
+
diff --git a/Test/baseResults/implicitArraySize1.geom.out b/Test/baseResults/implicitArraySize1.geom.out
new file mode 100644 (file)
index 0000000..d9c2f8b
--- /dev/null
@@ -0,0 +1,99 @@
+implicitArraySize1.geom
+Shader version: 460
+invocations = -1
+max_vertices = 204
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:11  Function Definition: main( ( global void)
+0:11    Function Parameters: 
+0:12    Sequence
+0:12      Function Call: f( ( global void)
+0:13      move second child to first child ( temp float)
+0:13        direct index (layout( stream=0) temp float)
+0:13          'o' (layout( stream=0) out 3-element array of float)
+0:13          Constant:
+0:13            1 (const int)
+0:13        direct index ( temp float)
+0:13          direct index ( temp 3-element array of float)
+0:13            'g' ( in 3-element array of 3-element array of float)
+0:13            Constant:
+0:13              2 (const int)
+0:13          Constant:
+0:13            1 (const int)
+0:?   Linker Objects
+0:?     'g' ( in 3-element array of 3-element array of float)
+0:?     'o' (layout( stream=0) out 3-element array of float)
+
+implicitArraySize2.geom
+Shader version: 460
+invocations = -1
+max_vertices = -1
+input primitive = none
+output primitive = none
+0:? Sequence
+0:6  Function Definition: f( ( global void)
+0:6    Function Parameters: 
+0:7    Sequence
+0:7      move second child to first child ( temp float)
+0:7        direct index (layout( stream=0) temp float)
+0:7          'o' (layout( stream=0) out unsized 2-element array of float)
+0:7          Constant:
+0:7            1 (const int)
+0:7        direct index ( temp float)
+0:7          direct index ( temp 3-element array of float)
+0:7            'g' ( in unsized 2-element array of 3-element array of float)
+0:7            Constant:
+0:7              1 (const int)
+0:7          Constant:
+0:7            1 (const int)
+0:?   Linker Objects
+0:?     'g' ( in unsized 2-element array of 3-element array of float)
+0:?     'o' (layout( stream=0) out unsized 2-element array of float)
+
+
+Linked geometry stage:
+
+ERROR: Linking geometry stage: Not all array sizes match across all geometry shaders in the program
+
+Shader version: 460
+invocations = 1
+max_vertices = 204
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:11  Function Definition: main( ( global void)
+0:11    Function Parameters: 
+0:12    Sequence
+0:12      Function Call: f( ( global void)
+0:13      move second child to first child ( temp float)
+0:13        direct index (layout( stream=0) temp float)
+0:13          'o' (layout( stream=0) out 3-element array of float)
+0:13          Constant:
+0:13            1 (const int)
+0:13        direct index ( temp float)
+0:13          direct index ( temp 3-element array of float)
+0:13            'g' ( in 3-element array of 3-element array of float)
+0:13            Constant:
+0:13              2 (const int)
+0:13          Constant:
+0:13            1 (const int)
+0:6  Function Definition: f( ( global void)
+0:6    Function Parameters: 
+0:7    Sequence
+0:7      move second child to first child ( temp float)
+0:7        direct index (layout( stream=0) temp float)
+0:7          'o' (layout( stream=0) out 2-element array of float)
+0:7          Constant:
+0:7            1 (const int)
+0:7        direct index ( temp float)
+0:7          direct index ( temp 3-element array of float)
+0:7            'g' ( in 2-element array of 3-element array of float)
+0:7            Constant:
+0:7              1 (const int)
+0:7          Constant:
+0:7            1 (const int)
+0:?   Linker Objects
+0:?     'g' ( in 3-element array of 3-element array of float)
+0:?     'o' (layout( stream=0) out 3-element array of float)
+
diff --git a/Test/baseResults/implicitArraySizeBuiltin.vert.out b/Test/baseResults/implicitArraySizeBuiltin.vert.out
new file mode 100644 (file)
index 0000000..77b41aa
--- /dev/null
@@ -0,0 +1,176 @@
+implicitArraySizeBuiltin.vert
+Shader version: 460
+0:? Sequence
+0:3  Function Definition: f1(f1; ( global void)
+0:3    Function Parameters: 
+0:3      'x' ( in float)
+0:5    Sequence
+0:5      move second child to first child ( temp float)
+0:5        direct index ( temp float ClipDistance)
+0:5          gl_ClipDistance: direct index for structure ( out unsized 7-element array of float ClipDistance)
+0:5            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 7-element array of float ClipDistance gl_ClipDistance,  out unsized 2-element array of float CullDistance gl_CullDistance})
+0:5            Constant:
+0:5              2 (const uint)
+0:5          Constant:
+0:5            6 (const int)
+0:5        'x' ( in float)
+0:6      move second child to first child ( temp float)
+0:6        direct index ( temp float CullDistance)
+0:6          gl_CullDistance: direct index for structure ( out unsized 2-element array of float CullDistance)
+0:6            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 7-element array of float ClipDistance gl_ClipDistance,  out unsized 2-element array of float CullDistance gl_CullDistance})
+0:6            Constant:
+0:6              3 (const uint)
+0:6          Constant:
+0:6            1 (const int)
+0:6        'x' ( in float)
+0:9  Function Definition: main( ( global void)
+0:9    Function Parameters: 
+0:10    Sequence
+0:10      Function Call: f1(f1; ( global void)
+0:10        Constant:
+0:10          0.100000
+0:?   Linker Objects
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 7-element array of float ClipDistance gl_ClipDistance,  out unsized 2-element array of float CullDistance gl_CullDistance})
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+
+implicitArraySizeBuiltin.geom
+Shader version: 460
+invocations = -1
+max_vertices = 204
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:6  Function Definition: f2(f1; ( global void)
+0:6    Function Parameters: 
+0:6      'x' ( in float)
+0:8    Sequence
+0:8      move second child to first child ( temp float)
+0:8        direct index (layout( stream=0) temp float ClipDistance)
+0:8          gl_ClipDistance: direct index for structure (layout( stream=0) out unsized 7-element array of float ClipDistance)
+0:8            'anon@0' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 7-element array of float ClipDistance gl_ClipDistance, layout( stream=0) out unsized 2-element array of float CullDistance gl_CullDistance})
+0:8            Constant:
+0:8              2 (const uint)
+0:8          Constant:
+0:8            6 (const int)
+0:8        direct index ( temp float ClipDistance)
+0:8          gl_ClipDistance: direct index for structure ( in unsized 7-element array of float ClipDistance)
+0:8            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 7-element array of float ClipDistance gl_ClipDistance,  in unsized 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in unsized 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:8              'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 7-element array of float ClipDistance gl_ClipDistance,  in unsized 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in unsized 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:8              Constant:
+0:8                0 (const int)
+0:8            Constant:
+0:8              2 (const int)
+0:8          Constant:
+0:8            6 (const int)
+0:10  Function Definition: f3(f1; ( global void)
+0:10    Function Parameters: 
+0:10      'x' ( in float)
+0:12    Sequence
+0:12      move second child to first child ( temp float)
+0:12        direct index (layout( stream=0) temp float CullDistance)
+0:12          gl_CullDistance: direct index for structure (layout( stream=0) out unsized 2-element array of float CullDistance)
+0:12            'anon@0' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 7-element array of float ClipDistance gl_ClipDistance, layout( stream=0) out unsized 2-element array of float CullDistance gl_CullDistance})
+0:12            Constant:
+0:12              3 (const uint)
+0:12          Constant:
+0:12            1 (const int)
+0:12        direct index ( temp float CullDistance)
+0:12          gl_CullDistance: direct index for structure ( in unsized 2-element array of float CullDistance)
+0:12            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 7-element array of float ClipDistance gl_ClipDistance,  in unsized 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in unsized 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:12              'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 7-element array of float ClipDistance gl_ClipDistance,  in unsized 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in unsized 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:12              Constant:
+0:12                0 (const int)
+0:12            Constant:
+0:12              3 (const int)
+0:12          Constant:
+0:12            1 (const int)
+0:15  Function Definition: main( ( global void)
+0:15    Function Parameters: 
+0:19    Sequence
+0:19      Function Call: f3(f1; ( global void)
+0:19        Constant:
+0:19          0.100000
+0:?   Linker Objects
+0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 7-element array of float ClipDistance gl_ClipDistance, layout( stream=0) out unsized 2-element array of float CullDistance gl_CullDistance})
+0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 7-element array of float ClipDistance gl_ClipDistance,  in unsized 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in unsized 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+
+
+Linked vertex stage:
+
+
+Linked geometry stage:
+
+
+Shader version: 460
+0:? Sequence
+0:3  Function Definition: f1(f1; ( global void)
+0:3    Function Parameters: 
+0:3      'x' ( in float)
+0:5    Sequence
+0:5      move second child to first child ( temp float)
+0:5        direct index ( temp float ClipDistance)
+0:5          gl_ClipDistance: direct index for structure ( out 7-element array of float ClipDistance)
+0:5            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 7-element array of float ClipDistance gl_ClipDistance,  out 2-element array of float CullDistance gl_CullDistance})
+0:5            Constant:
+0:5              2 (const uint)
+0:5          Constant:
+0:5            6 (const int)
+0:5        'x' ( in float)
+0:6      move second child to first child ( temp float)
+0:6        direct index ( temp float CullDistance)
+0:6          gl_CullDistance: direct index for structure ( out 2-element array of float CullDistance)
+0:6            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 7-element array of float ClipDistance gl_ClipDistance,  out 2-element array of float CullDistance gl_CullDistance})
+0:6            Constant:
+0:6              3 (const uint)
+0:6          Constant:
+0:6            1 (const int)
+0:6        'x' ( in float)
+0:9  Function Definition: main( ( global void)
+0:9    Function Parameters: 
+0:10    Sequence
+0:10      Function Call: f1(f1; ( global void)
+0:10        Constant:
+0:10          0.100000
+0:?   Linker Objects
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 7-element array of float ClipDistance gl_ClipDistance,  out 2-element array of float CullDistance gl_CullDistance})
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+Shader version: 460
+invocations = 1
+max_vertices = 204
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:10  Function Definition: f3(f1; ( global void)
+0:10    Function Parameters: 
+0:10      'x' ( in float)
+0:12    Sequence
+0:12      move second child to first child ( temp float)
+0:12        direct index (layout( stream=0) temp float CullDistance)
+0:12          gl_CullDistance: direct index for structure (layout( stream=0) out 2-element array of float CullDistance)
+0:12            'anon@0' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out 7-element array of float ClipDistance gl_ClipDistance, layout( stream=0) out 2-element array of float CullDistance gl_CullDistance})
+0:12            Constant:
+0:12              3 (const uint)
+0:12          Constant:
+0:12            1 (const int)
+0:12        direct index ( temp float CullDistance)
+0:12          gl_CullDistance: direct index for structure ( in 2-element array of float CullDistance)
+0:12            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in 7-element array of float ClipDistance gl_ClipDistance,  in 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:12              'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in 7-element array of float ClipDistance gl_ClipDistance,  in 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+0:12              Constant:
+0:12                0 (const int)
+0:12            Constant:
+0:12              3 (const int)
+0:12          Constant:
+0:12            1 (const int)
+0:15  Function Definition: main( ( global void)
+0:15    Function Parameters: 
+0:19    Sequence
+0:19      Function Call: f3(f1; ( global void)
+0:19        Constant:
+0:19          0.100000
+0:?   Linker Objects
+0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out 7-element array of float ClipDistance gl_ClipDistance, layout( stream=0) out 2-element array of float CullDistance gl_CullDistance})
+0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in 7-element array of float ClipDistance gl_ClipDistance,  in 2-element array of float CullDistance gl_CullDistance,  in 4-component vector of float SecondaryPositionNV gl_SecondaryPositionNV,  in 1-element array of 4-component vector of float PositionPerViewNV gl_PositionPerViewNV})
+
diff --git a/Test/implicitArraySize.frag b/Test/implicitArraySize.frag
new file mode 100644 (file)
index 0000000..ca3eeb3
--- /dev/null
@@ -0,0 +1,9 @@
+#version 460 core
+in float a[];
+in float c[3];
+out float b[5];
+
+void main(){
+  b[0] = a[1];
+  b[1] = c[1];
+}
\ No newline at end of file
diff --git a/Test/implicitArraySize.vert b/Test/implicitArraySize.vert
new file mode 100644 (file)
index 0000000..93e7495
--- /dev/null
@@ -0,0 +1,8 @@
+#version 460 core
+out float a[];
+out float c[];
+
+void main(){
+  a[0] = 0.1;
+  c[5] = 0.1;
+}
\ No newline at end of file
diff --git a/Test/implicitArraySize1.geom b/Test/implicitArraySize1.geom
new file mode 100644 (file)
index 0000000..b3b52ea
--- /dev/null
@@ -0,0 +1,14 @@
+#version 460 core
+
+layout(triangles) in;
+layout(line_strip, max_vertices = 204) out;
+
+void f();
+
+in float g[][3];
+out float o[3];
+
+void main(){
+  f();
+  o[1] = g[2][1];
+}
\ No newline at end of file
diff --git a/Test/implicitArraySize2.geom b/Test/implicitArraySize2.geom
new file mode 100644 (file)
index 0000000..0bb65cd
--- /dev/null
@@ -0,0 +1,8 @@
+#version 460 core
+
+in float g[][3];
+out float o[];
+
+void f(){
+  o[1] = g[1][1];
+}
\ No newline at end of file
diff --git a/Test/implicitArraySizeBuiltin.geom b/Test/implicitArraySizeBuiltin.geom
new file mode 100644 (file)
index 0000000..419b633
--- /dev/null
@@ -0,0 +1,20 @@
+#version 460 core
+
+layout(triangles) in;
+layout(line_strip, max_vertices = 204) out;
+
+void f2(float x)
+{
+    gl_ClipDistance[6] = gl_in[0].gl_ClipDistance[6];
+}
+void f3(float x)
+{
+    gl_CullDistance[1] = gl_in[0].gl_CullDistance[1];
+}
+
+void main(){
+  #if defined(CLIP)
+  f2(0.1);
+  #endif
+  f3(0.1);
+}
\ No newline at end of file
diff --git a/Test/implicitArraySizeBuiltin.vert b/Test/implicitArraySizeBuiltin.vert
new file mode 100644 (file)
index 0000000..251e975
--- /dev/null
@@ -0,0 +1,11 @@
+#version 460 core
+
+void f1(float x)
+{
+    gl_ClipDistance[6] = x;
+    gl_CullDistance[1] = x;
+}
+
+void main(){
+  f1(0.1);
+}
\ No newline at end of file
index 569c64b..59a447c 100644 (file)
@@ -1894,9 +1894,11 @@ public:
     virtual bool isArray()  const { return arraySizes != nullptr; }
     virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
     virtual bool isUnsizedArray() const { return isArray() && !arraySizes->isSized(); }
+    virtual bool isImplicitlySizedArray() const { return isArray() && arraySizes->isImplicitlySized(); }
     virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
     virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
     virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
+    virtual void setImplicitlySized(bool isImplicitSized) { arraySizes->setImplicitlySized(isImplicitSized); }
     virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; }
     virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
     virtual bool isIntegerDomain() const
@@ -2125,8 +2127,12 @@ public:
     // an explicit array.
     void adoptImplicitArraySizes(bool skipNonvariablyIndexed)
     {
-        if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
+        if (isUnsizedArray() &&
+            (qualifier.builtIn == EbvSampleMask ||
+                !(skipNonvariablyIndexed || isArrayVariablyIndexed()))) {
             changeOuterArraySize(getImplicitArraySize());
+            setImplicitlySized(true);
+        }
         // For multi-dim per-view arrays, set unsized inner dimension size to 1
         if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized())
             arraySizes->clearInnerUnsized();
@@ -2758,7 +2764,10 @@ public:
     bool sameArrayness(const TType& right) const
     {
         return ((arraySizes == nullptr && right.arraySizes == nullptr) ||
-                (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes));
+                (arraySizes != nullptr && right.arraySizes != nullptr &&
+                 (*arraySizes == *right.arraySizes ||
+                  (arraySizes->isImplicitlySized() && right.arraySizes->isDefaultImplicitlySized()) ||
+                  (right.arraySizes->isImplicitlySized() && arraySizes->isDefaultImplicitlySized()))));
     }
 
     // See if two type's arrayness match in everything except their outer dimension
index 7f047d9..1da14d0 100644 (file)
@@ -222,7 +222,7 @@ protected:
 struct TArraySizes {
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 
-    TArraySizes() : implicitArraySize(1), variablyIndexed(false) { }
+    TArraySizes() : implicitArraySize(0), implicitlySized(true), variablyIndexed(false){ }
 
     // For breaking into two non-shared copies, independently modifiable.
     TArraySizes& operator=(const TArraySizes& from)
@@ -230,6 +230,7 @@ struct TArraySizes {
         implicitArraySize = from.implicitArraySize;
         variablyIndexed = from.variablyIndexed;
         sizes = from.sizes;
+        implicitlySized = from.implicitlySized;
 
         return *this;
     }
@@ -256,11 +257,17 @@ struct TArraySizes {
     void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
     void addInnerSize(TArraySize pair) {
         sizes.push_back(pair.size, pair.node);
+        implicitlySized = false;
     }
     void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
-    void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
-    int getImplicitSize() const { return implicitArraySize; }
-    void updateImplicitSize(int s) { implicitArraySize = std::max(implicitArraySize, s); }
+    void changeOuterSize(int s) {
+        sizes.changeFront((unsigned)s);
+        implicitlySized = false;
+    }
+    int getImplicitSize() const { return implicitArraySize > 0 ? implicitArraySize : 1; }
+    void updateImplicitSize(int s) {
+        implicitArraySize = (std::max)(implicitArraySize, s);
+    }
     bool isInnerUnsized() const
     {
         for (int d = 1; d < sizes.size(); ++d) {
@@ -295,6 +302,9 @@ struct TArraySizes {
 
     bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); }
     bool isSized() const { return getOuterSize() != UnsizedArraySize; }
+    bool isImplicitlySized() const { return implicitlySized; }
+    bool isDefaultImplicitlySized() const { return implicitlySized && implicitArraySize == 0; }
+    void setImplicitlySized(bool isImplicitSizing) { implicitlySized = isImplicitSizing; }
     void dereference() { sizes.pop_front(); }
     void copyDereferenced(const TArraySizes& rhs)
     {
@@ -333,6 +343,7 @@ protected:
     // the implicit size of the array, if not variably indexed and
     // otherwise legal.
     int implicitArraySize;
+    bool implicitlySized;
     bool variablyIndexed;  // true if array is indexed with a non compile-time constant
 };
 
index 980153e..f86e78b 100644 (file)
@@ -608,6 +608,15 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
 #ifndef GLSLANG_WEB
         if (base->getType().isUnsizedArray()) {
             base->getWritableType().updateImplicitArraySize(indexValue + 1);
+            base->getWritableType().setImplicitlySized(true);
+            if (base->getQualifier().builtIn == EbvClipDistance &&
+                indexValue >= resources.maxClipDistances) {
+                error(loc, "gl_ClipDistance", "[", "array index out of range '%d'", indexValue);
+            }
+            else if (base->getQualifier().builtIn == EbvCullDistance &&
+                indexValue >= resources.maxCullDistances) {
+                error(loc, "gl_CullDistance", "[", "array index out of range '%d'", indexValue);
+            }
             // For 2D per-view builtin arrays, update the inner dimension size in parent type
             if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
                 TIntermBinary* binaryNode = base->getAsBinaryNode();
index cfcb197..3a4cb56 100644 (file)
@@ -750,6 +750,21 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
                 }
 
                 // Update implicit array sizes
+                if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isImplicitlySizedArray()) {
+                    if (unitSymbol->getType().getImplicitArraySize() > symbol->getType().getImplicitArraySize()){
+                        symbol->getWritableType().updateImplicitArraySize(unitSymbol->getType().getImplicitArraySize());
+                    }
+                }
+                else if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isSizedArray()) {
+                    if (symbol->getWritableType().getImplicitArraySize() > unitSymbol->getType().getOuterArraySize())
+                        error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
+                }
+                else if (unitSymbol->getType().isImplicitlySizedArray() && symbol->getWritableType().isSizedArray()) {
+                    if (unitSymbol->getType().getImplicitArraySize() > symbol->getWritableType().getOuterArraySize())
+                        error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
+                }
+
+                // Update implicit array sizes
                 mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
 
                 // Check for consistent types/qualification/initializers etc.
@@ -759,6 +774,19 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
             else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage)
                 error(infoSink, "Only one push_constant block is allowed per stage");
         }
+
+        // Check conflicts between preset primitives and sizes of I/O variables among multiple geometry shaders
+        if (language == EShLangGeometry && unitStage == EShLangGeometry)
+        {
+            TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
+            if (unitSymbol->isArray() && unitSymbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().builtIn == EbvNone)
+                if ((unitSymbol->getArraySizes()->isImplicitlySized() &&
+                        unitSymbol->getArraySizes()->getImplicitSize() != TQualifier::mapGeometryToSize(getInputPrimitive())) ||
+                    (! unitSymbol->getArraySizes()->isImplicitlySized() &&
+                        unitSymbol->getArraySizes()->getDimSize(0) != TQualifier::mapGeometryToSize(getInputPrimitive())))
+                    error(infoSink, "Not all array sizes match across all geometry shaders in the program");
+        }
+
         if (merge) {
             linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
 
@@ -863,7 +891,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
         else {
             arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) ||
                 (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
-                (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
+                 (symbol.getType().isImplicitlySizedArray() || unitSymbol.getType().isImplicitlySizedArray() ||
+                  symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
         }
 
         int lpidx = -1;
index 9e029fc..3b769bb 100644 (file)
@@ -90,6 +90,9 @@ INSTANTIATE_TEST_SUITE_P(
     Glsl, LinkTest,
     ::testing::ValuesIn(std::vector<std::vector<std::string>>({
         {"mains1.frag", "mains2.frag", "noMain1.geom", "noMain2.geom"},
+        {"implicitArraySize.vert", "implicitArraySize.frag"},
+        {"implicitArraySizeBuiltin.vert", "implicitArraySizeBuiltin.geom"},
+        {"implicitArraySize1.geom", "implicitArraySize2.geom"},
         {"noMain.vert", "mains.frag"},
         {"link1.frag", "link2.frag", "link3.frag"},
         {"recurse1.vert", "recurse1.frag", "recurse2.frag"},