GL_ARB_enhanced_layouts, part 2: Full implementation of location/component, plus the parsing for xfb* and align/offset (but not yet full semantics for align/offset).

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24692 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2014-01-08 23:25:18 +00:00
parent b76d6d6496
commit 68546c6ca4
22 changed files with 617 additions and 115 deletions

View File

@ -45,9 +45,72 @@ layout(location = -2) in vec4 v1; // ERROR
layout(location = start + 2) in vec4 v2; // ERROR
layout(location = 4.7e10) in vec4 v20; // ERROR
struct S {
float f1;
layout(location = 3) float f2; // ERROR
};
layout(location = 1) in inblock { // ERROR
float f1;
layout(location = 3) float f2; // ERROR
};
layout(location = 1) uniform ublock { // ERROR
float f1;
layout(location = 3) float f2; // ERROR
} uinst;
#extension GL_ARB_enhanced_layouts : enable
layout(location = start) in vec4 v3;
layout(location = -2) in vec4 v4; // ERROR
layout(location = -start) in vec4 v5; // ERROR
layout(location = start*start - 2) in vec4 v6;
layout(location = start*start - 2 - 4) in vec4 v6;
struct S2 {
float f1;
layout(location = 3) float f2; // ERROR
};
layout(location = 28) in inblock2 {
bool b1;
float f1;
layout(location = 25) float f2;
vec4 f3;
layout(location = 21) S2 s2;
vec4 f4;
vec4 f5;
} ininst2;
layout(location = 13) uniform ublock2 { // ERROR
float f1;
layout(location = 3) float f2; // ERROR
} uinst2;
in inblock3 { // ERROR, mix of location internal with no location external
float f1;
layout(location = 40) float f2;
} in3;
in ublock4 {
layout(location = 50) float f1;
layout(location = 51) float f2;
} in4;
layout(location = 33) in struct SS {
vec3 a; // gets location 33
mat2 b; // gets locations 34 and 35
vec4 c[2]; // gets locations 36 and 37
layout (location = 38) vec2 A; // ERROR, can't use on struct member
} s;
layout(location = 44) in block {
vec4 d; // gets location 44
vec4 e; // gets location 45
layout(location = 47) vec4 f; // gets location 47
vec4 g; // gets location 48
layout (location = 41) vec4 h; // gets location 41
vec4 i; // gets location 42
vec4 j; // gets location 43
vec4 k; // ERROR, location 44 already used
};

22
Test/440.frag Normal file
View File

@ -0,0 +1,22 @@
#version 440
// Note 'location'-only tests for enhanced layouts are in 330.frag
// Generic 'component' tests are in 440.vert
// a consumes components 2 and 3 of location 4
layout(location = 4, component = 2) in vec2 a;
// b consumes component 1 of location 4
layout(location = 4, component = 1) in float b;
layout(location = 4, component = 2) in vec2 h; // ERROR, component overlap not okay for fragment in
layout(location = 3, component = 2) in vec3 c; // ERROR: c overflows components 2 and 3
// e consumes beginning (components 0, 1 and 2) of each of 6 slots
layout(location = 20, component = 0) in vec3 e[6];
// f consumes last component of the same 6 slots
layout(location = 20, component = 3) in float f[6];
layout(location = 30, component = 3) out int be;
layout(location = 30, component = 0) out vec3 bf; // ERROR, not the same basic type

64
Test/440.vert Normal file
View File

@ -0,0 +1,64 @@
#version 440
// Note 'location' tests for enhanced layouts are in 330.frag
layout(location = 2, component = 2) in vec2 a;
layout(location = 2, component = 1) in float b;
layout(location = 3, component = 2) in vec3 c; // ERROR: c overflows components 2 and 3
layout(location = 0, component = 3) in float d[4];
layout(location = 4, component = 0) in vec3 e[5];
layout(location = 4, component = 3) in float f[5];
layout(location = 9, component = 4) in float g[6]; // ERROR, component too big
layout(location = 4, component = 2) in vec2 h; // component overlap okay for vertex in
layout(location = 3, component = 2) out vec2 i;
layout(location = 3, component = 0) out vec2 j;
layout(location = 4, component = 2) out vec2 k;
layout(location = 4, component = 2) out vec2 m; // ERROR, component overlap
layout(location = 2, component = 2) out vec2 n;
layout(location = 2, component = 0) out vec3 p; // ERROR, component overlap
layout(location = 10, component = 3) out float q[6];
layout(location = 10, component = 0) out vec3 r[6];
layout(location = 15, component = 3) out float s; // ERROR, overlap
layout(location = 10, component = 1) out float t; // ERROR, overlap
layout(location = 20, component = 2) out float u;
layout(location = 20, component = 0) out float v;
layout(location = 20, component = 3) out float w;
layout(location = 20, component = 1) out vec2 x; // ERROR, overlap
layout(location = 30, component = 3) out vec2 y; // ERROR, goes to component 4
layout(location = 31, component = 1) out vec4 z; // ERROR, goes to component 4
layout(location = 32, component = 1) out mat4 ba; // ERROR
layout(location = 33, component = 1) out struct S {int a;} Ss; // ERROR
layout(location = 34, component = 1) out bn { int a;} bb; // ERROR
layout(component = 1) out float bc; // ERROR, no location
out blockname {
layout(location = 40, component = 2) out float u;
layout(location = 40, component = 0) out float v;
layout(location = 40, component = 3) out float w;
layout(location = 40, component = 1) out vec2 x; // ERROR, overlap
layout(location = 41, component = 3) out vec2 y; // ERROR, goes to component 4
layout(location = 42, component = 1) out vec4 z; // ERROR, goes to component 4
layout(location = 42, component = 1) out mat4 ba; // ERROR
layout(location = 43, component = 1) out S Ss; // ERROR
} bd;
layout(location = 1, component = 1) out; // ERROR, no global setting
layout(location = 50, component = 3) out int be;
layout(location = 50, component = 0) out vec3 bf;

View File

@ -9,6 +9,7 @@ ERROR: 0:44: 'stream' : can only be used on an output
ERROR: 0:45: 'stream' : can only be used on an output
ERROR: 0:46: 'stream' : can only be used on an output
ERROR: 0:47: 'stream' : can only be used on an output
ERROR: 0:47: 'stream' : can only be used on an output
ERROR: 0:60: 'stream' : member cannot contradict block
ERROR: 0:65: 'max_vertices' : can only apply to a standalone qualifier
ERROR: 0:70: 'points' : cannot change previously set output primitive
@ -29,7 +30,8 @@ ERROR: 0:86: 'triangles_adjacency' : cannot change previously set input primitiv
ERROR: 0:87: 'invocations' : not supported for this version or the enabled extensions
ERROR: 0:88: 'max_vertices' : too large, must be less than gl_MaxGeometryOutputVertices
ERROR: 0:91: 'stream' : member cannot contradict block
ERROR: 29 compilation errors. No code generated.
ERROR: 0:91: 'stream' : can only be used on an output
ERROR: 31 compilation errors. No code generated.
invocations = 4

View File

@ -221,8 +221,8 @@ ERROR: 0:40: 'vertices' : cannot change previously set layout value
ERROR: 0:44: '[' : array index out of range '4'
ERROR: 0:47: 'in' : type must be an array: ina
ERROR: 0:49: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:56: 'location' : repeated use of location 4
ERROR: 0:60: 'location' : repeated use of location 4
ERROR: 0:56: 'location' : overlapping use of location 4
ERROR: 0:60: 'location' : overlapping use of location 4
ERROR: 11 compilation errors. No code generated.
@ -381,8 +381,8 @@ ERROR: 0:73: 'in' : type must be an array: ina
ERROR: 0:75: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:78: 'in' : type must be an array: bla
ERROR: 0:86: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:96: 'location' : repeated use of location 24
ERROR: 0:99: 'location' : repeated use of location 24
ERROR: 0:96: 'location' : overlapping use of location 24
ERROR: 0:99: 'location' : overlapping use of location 24
ERROR: 29 compilation errors. No code generated.

View File

@ -1,7 +1,7 @@
300layout.frag
ERROR: 0:4: 'location qualifier on input' : not supported in this stage: fragment
ERROR: 0:18: 'location' : repeated use of location 41
ERROR: 0:19: 'location' : repeated use of location 40
ERROR: 0:18: 'location' : overlapping use of location 41
ERROR: 0:19: 'location' : overlapping use of location 40
ERROR: 3 compilation errors. No code generated.

View File

@ -2,9 +2,9 @@
ERROR: 0:7: 'vertex input arrays' : not supported with this profile: es
ERROR: 0:8: 'in' : cannot be a structure or array
ERROR: 0:8: 'vertex input arrays' : not supported with this profile: es
ERROR: 0:8: 'location' : repeated use of location 10
ERROR: 0:12: 'badm4' : cannot specify matrix layout on a variable declaration
ERROR: 0:12: 'badm4' : cannot specify packing on a variable declaration
ERROR: 0:8: 'location' : overlapping use of location 10
ERROR: 0:12: 'layout' : cannot specify matrix layout on a variable declaration
ERROR: 0:12: 'layout' : cannot specify packing on a variable declaration
ERROR: 0:19: 'badf' : member of uniform block cannot have an auxiliary or interpolation qualifier
ERROR: 0:20: 'badg' : member storage qualifier cannot contradict block storage qualifier
ERROR: 0:21: 'bad1' : member of block cannot have a packing layout qualifier
@ -15,8 +15,8 @@ ERROR: 0:38: 'output block' : not supported with this profile: es
ERROR: 0:42: 'location qualifier on output' : not supported in this stage: vertex
ERROR: 0:50: 'shared' : not supported with this profile: es
ERROR: 0:50: 'shared' : not supported in this stage: vertex
ERROR: 0:54: 'aoeuntaoeu' : layout qualifiers for matrix layout and packing only apply to uniform or buffer blocks
ERROR: 0:57: 'location' : repeated use of location 40
ERROR: 0:54: 'layout' : qualifiers for matrix layout and block packing only apply to uniform or buffer blocks
ERROR: 0:57: 'location' : overlapping use of location 40
ERROR: 18 compilation errors. No code generated.

View File

@ -10,9 +10,22 @@ ERROR: 0:44: 'layout-id value' : cannot be negative
ERROR: 0:45: 'non-literal layout-id value' : not supported for this version or the enabled extensions
ERROR: 0:46: 'layout-id value' : scalar integer expression required
ERROR: 0:46: 'location' : location is too large
ERROR: 0:51: 'layout-id value' : cannot be negative
ERROR: 0:52: 'layout-id value' : cannot be negative
ERROR: 12 compilation errors. No code generated.
ERROR: 0:50: 'f2' : cannot use layout qualifiers on structure members
ERROR: 0:55: 'location on block member' : not supported for this version or the enabled extensions
ERROR: 0:60: 'location on block member' : can only use in an in/out block
ERROR: 0:60: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
ERROR: 0:58: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
ERROR: 0:66: 'layout-id value' : cannot be negative
ERROR: 0:67: 'layout-id value' : cannot be negative
ERROR: 0:72: 'f2' : cannot use layout qualifiers on structure members
ERROR: 0:87: 'location on block member' : can only use in an in/out block
ERROR: 0:87: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
ERROR: 0:87: 'location' : overlapping use of location 3
ERROR: 0:85: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
ERROR: 0:90: 'location' : either the block needs a location, or all members need a location, or no members have a location
ERROR: 0:104: 'A' : cannot use layout qualifiers on structure members
ERROR: 0:115: 'location' : overlapping use of location 44
ERROR: 25 compilation errors. No code generated.
ERROR: node is still EOpNull!
@ -57,10 +70,18 @@ ERROR: node is still EOpNull!
0:? 'v1' (smooth in 4-component vector of float)
0:? 'v2' (layout(location=8 ) smooth in 4-component vector of float)
0:? 'v20' (smooth in 4-component vector of float)
0:? '__anon__1' (in block{layout(location=1 component=0 ) in float f1, layout(location=3 ) in float f2})
0:? 'uinst' (layout(location=1 column_major shared ) uniform block{layout(column_major shared ) uniform float f1, layout(location=3 column_major shared ) uniform float f2})
0:? 'v3' (layout(location=6 ) smooth in 4-component vector of float)
0:? 'v4' (smooth in 4-component vector of float)
0:? 'v5' (smooth in 4-component vector of float)
0:? 'v6' (layout(location=34 ) smooth in 4-component vector of float)
0:? 'v6' (layout(location=30 ) smooth in 4-component vector of float)
0:? 'ininst2' (in block{layout(location=28 component=0 ) in bool b1, layout(location=29 component=0 ) in float f1, layout(location=25 ) in float f2, layout(location=26 component=0 ) in 4-component vector of float f3, layout(location=21 ) in structure{float f1, float f2} s2, layout(location=23 component=0 ) in 4-component vector of float f4, layout(location=24 component=0 ) in 4-component vector of float f5})
0:? 'uinst2' (layout(location=13 column_major shared ) uniform block{layout(column_major shared ) uniform float f1, layout(location=3 column_major shared ) uniform float f2})
0:? 'in3' (in block{in float f1, layout(location=40 ) in float f2})
0:? 'in4' (in block{layout(location=50 ) in float f1, layout(location=51 ) in float f2})
0:? 's' (layout(location=33 ) smooth in structure{3-component vector of float a, 2X2 matrix of float b, 2-element array of 4-component vector of float c, 2-component vector of float A})
0:? '__anon__2' (in block{layout(location=44 component=0 ) in 4-component vector of float d, layout(location=45 component=0 ) in 4-component vector of float e, layout(location=47 ) in 4-component vector of float f, layout(location=48 component=0 ) in 4-component vector of float g, layout(location=41 ) in 4-component vector of float h, layout(location=42 component=0 ) in 4-component vector of float i, layout(location=43 component=0 ) in 4-component vector of float j, layout(location=44 component=0 ) in 4-component vector of float k})
Linked fragment stage:

View File

@ -8,7 +8,7 @@ ERROR: 0:25: 'length' : array must first be sized by a redeclaration or layout
ERROR: 0:36: 'length' : array must first be sized by a redeclaration or layout qualifier
ERROR: 0:40: 'triangles' : inconsistent input primitive for array size of colorBad
ERROR: 0:44: 'triangles' : inconsistent input primitive for array size of colorbad2
ERROR: 0:56: 'location' : repeated use of location 4
ERROR: 0:56: 'location' : overlapping use of location 4
ERROR: 0:58: 'patch' : not supported in this stage: geometry
ERROR: 0:59: 'patch' : not supported in this stage: geometry
ERROR: 0:61: 'in' : type must be an array: scalar

View File

@ -1,6 +1,6 @@
430.vert
Warning, version 430 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:3: 'v4' : location qualifiers only appy to uniform, buffer, in, or out storage qualifiers
ERROR: 0:3: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers
ERROR: 0:7: 'location qualifier on in/out block' : not supported for this version or the enabled extensions
ERROR: 0:8: 'location qualifier on in/out block' : not supported for this version or the enabled extensions
ERROR: 0:21: 'g' : cannot use storage or interpolation qualifiers on structure members
@ -11,7 +11,7 @@ ERROR: 0:25: 'm3' : cannot use layout qualifiers on structure members
ERROR: 0:28: '' : cannot use invariant qualifier on a function parameter
ERROR: 0:30: '' : cannot use layout qualifiers on a function parameter
ERROR: 0:31: '' : cannot use auxiliary or interpolation qualifiers on a function parameter
ERROR: 0:42: 'location' : repeated use of location 53
ERROR: 0:42: 'location' : overlapping use of location 53
ERROR: 0:47: 'gl_ClipDistance array size' : must be less than gl_MaxClipDistances (8)
ERROR: 13 compilation errors. No code generated.

View File

@ -0,0 +1,25 @@
440.frag
Warning, version 440 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:11: 'location' : overlapping use of location 4
ERROR: 0:13: 'component' : type overflows the available 4 components
ERROR: 0:22: 'location' : fragment outputs sharing the same location must be the same basic type 30
ERROR: 3 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:? Linker Objects
0:? 'a' (layout(location=4 component=2 ) smooth in 2-component vector of float)
0:? 'b' (layout(location=4 component=1 ) smooth in float)
0:? 'h' (layout(location=4 component=2 ) smooth in 2-component vector of float)
0:? 'c' (layout(location=3 component=2 ) smooth in 3-component vector of float)
0:? 'e' (layout(location=20 component=0 ) smooth in 6-element array of 3-component vector of float)
0:? 'f' (layout(location=20 component=3 ) smooth in 6-element array of float)
0:? 'be' (layout(location=30 component=3 ) out int)
0:? 'bf' (layout(location=30 component=0 ) out 3-component vector of float)
Linked fragment stage:
ERROR: Linking fragment stage: Missing entry point: Each stage requires one "void main()" entry point

View File

@ -0,0 +1,66 @@
440.vert
Warning, version 440 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:8: 'component' : type overflows the available 4 components
ERROR: 0:15: 'component' : component is too large
ERROR: 0:23: 'location' : overlapping use of location 4
ERROR: 0:26: 'location' : overlapping use of location 2
ERROR: 0:31: 'location' : overlapping use of location 15
ERROR: 0:32: 'location' : overlapping use of location 10
ERROR: 0:37: 'location' : overlapping use of location 20
ERROR: 0:39: 'component' : type overflows the available 4 components
ERROR: 0:40: 'component' : type overflows the available 4 components
ERROR: 0:42: 'component' : cannot apply to a matrix, structure, or block
ERROR: 0:43: 'component' : cannot apply to a matrix, structure, or block
ERROR: 0:44: 'component' : cannot apply to a matrix, structure, or block
ERROR: 0:46: 'component' : must specify 'location' to use 'component'
ERROR: 0:52: 'location' : overlapping use of location 40
ERROR: 0:54: 'component' : type overflows the available 4 components
ERROR: 0:55: 'component' : type overflows the available 4 components
ERROR: 0:57: 'component' : cannot apply to a matrix, structure, or block
ERROR: 0:58: 'component' : cannot apply to a matrix, structure, or block
ERROR: 0:61: 'location' : cannot declare a default, use a full declaration
ERROR: 19 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:? Linker Objects
0:? 'a' (layout(location=2 component=2 ) in 2-component vector of float)
0:? 'b' (layout(location=2 component=1 ) in float)
0:? 'c' (layout(location=3 component=2 ) in 3-component vector of float)
0:? 'd' (layout(location=0 component=3 ) in 4-element array of float)
0:? 'e' (layout(location=4 component=0 ) in 5-element array of 3-component vector of float)
0:? 'f' (layout(location=4 component=3 ) in 5-element array of float)
0:? 'g' (layout(location=9 ) in 6-element array of float)
0:? 'h' (layout(location=4 component=2 ) in 2-component vector of float)
0:? 'i' (layout(location=3 component=2 ) smooth out 2-component vector of float)
0:? 'j' (layout(location=3 component=0 ) smooth out 2-component vector of float)
0:? 'k' (layout(location=4 component=2 ) smooth out 2-component vector of float)
0:? 'm' (layout(location=4 component=2 ) smooth out 2-component vector of float)
0:? 'n' (layout(location=2 component=2 ) smooth out 2-component vector of float)
0:? 'p' (layout(location=2 component=0 ) smooth out 3-component vector of float)
0:? 'q' (layout(location=10 component=3 ) smooth out 6-element array of float)
0:? 'r' (layout(location=10 component=0 ) smooth out 6-element array of 3-component vector of float)
0:? 's' (layout(location=15 component=3 ) smooth out float)
0:? 't' (layout(location=10 component=1 ) smooth out float)
0:? 'u' (layout(location=20 component=2 ) smooth out float)
0:? 'v' (layout(location=20 component=0 ) smooth out float)
0:? 'w' (layout(location=20 component=3 ) smooth out float)
0:? 'x' (layout(location=20 component=1 ) smooth out 2-component vector of float)
0:? 'y' (layout(location=30 component=3 ) smooth out 2-component vector of float)
0:? 'z' (layout(location=31 component=1 ) smooth out 4-component vector of float)
0:? 'ba' (layout(location=32 component=1 ) smooth out 4X4 matrix of float)
0:? 'Ss' (layout(location=33 component=1 ) smooth out structure{int a})
0:? 'bb' (layout(location=34 component=1 ) out block{out int a})
0:? 'bc' (layout(location=63 component=1 ) smooth out float)
0:? 'bd' (out block{layout(location=40 component=2 ) out float u, layout(location=40 component=0 ) out float v, layout(location=40 component=3 ) out float w, layout(location=40 component=1 ) out 2-component vector of float x, layout(location=41 component=3 ) out 2-component vector of float y, layout(location=42 component=1 ) out 4-component vector of float z, layout(location=42 component=1 ) out 4X4 matrix of float ba, layout(location=43 component=1 ) out structure{int a} Ss})
0:? 'be' (layout(location=50 component=3 ) smooth out int)
0:? 'bf' (layout(location=50 component=0 ) smooth out 3-component vector of float)
0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int)
Linked vertex stage:
ERROR: Linking vertex stage: Missing entry point: Each stage requires one "void main()" entry point

View File

@ -16,7 +16,7 @@ ERROR: 0:99: 'local_size_y' : there is no such layout identifier for this stage
ERROR: 0:100: 'local_size_x' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:102: 'color' : redefinition
ERROR: 0:103: 'index' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:104: 'location' : repeated use of location 3
ERROR: 0:104: 'location' : overlapping use of location 3
ERROR: 0:106: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:112: 'depth_any' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:115: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)

View File

@ -1,7 +1,7 @@
specExamples.vert
Warning, version 430 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:23: 'transforms' : redeclaration of array with size
ERROR: 0:29: 's' : location qualifiers only appy to uniform, buffer, in, or out storage qualifiers
ERROR: 0:29: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers
ERROR: 0:31: 'triangles' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:31: 'invocations' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:33: 'lines' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
@ -17,15 +17,15 @@ ERROR: 0:47: 'stream' : there is no such layout identifier for this stage taking
ERROR: 0:50: 'stream' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:55: 'stream' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:80: 's17' : redefinition
ERROR: 0:85: 'offset' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:85: 'uniform buffer-member offset' : not supported for this version or the enabled extensions
ERROR: 0:85: 'binding' : requires block, or sampler/image, or atomic-counter type
ERROR: 0:87: 'binding' : requires block, or sampler/image, or atomic-counter type
ERROR: 0:89: 'offset' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:89: 'uniform buffer-member offset' : not supported for this version or the enabled extensions
WARNING: 0:89: 'layout' : useless application of layout qualifier
ERROR: 0:91: 'bar' : redefinition
ERROR: 0:92: 'offset' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:92: 'uniform buffer-member offset' : not supported for this version or the enabled extensions
ERROR: 0:92: 'bar' : redefinition
ERROR: 0:94: 'offset' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:94: 'uniform buffer-member offset' : not supported for this version or the enabled extensions
ERROR: 0:94: 'a2' : redefinition
ERROR: 0:95: 'binding' : requires block, or sampler/image, or atomic-counter type
ERROR: 0:96: 'binding' : requires block, or sampler/image, or atomic-counter type
@ -291,7 +291,7 @@ ERROR: node is still EOpNull!
0:? '__anon__3' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform 4X4 matrix of float M1, layout(column_major std140 ) uniform 4X4 matrix of float M2, layout(row_major std140 ) uniform 3X3 matrix of float N1})
0:? '__anon__4' (layout(column_major shared ) uniform block{layout(column_major shared ) uniform 4X4 matrix of float M13, layout(row_major shared ) uniform 4X4 matrix of float m14, layout(column_major shared ) uniform 3X3 matrix of float N12})
0:? 's17' (layout(binding=3 ) uniform sampler2D)
0:? 'a2' (layout(binding=2 ) uniform int)
0:? 'a2' (layout(binding=2 offset=4 ) uniform int)
0:? 'bar' (layout(binding=2 ) uniform int)
0:? 'b2' (layout(binding=2 ) uniform int)
0:? 'c2' (layout(binding=3 ) uniform int)

View File

@ -59,6 +59,8 @@ numeral.frag
410.geom
430.vert
430.comp
440.vert
440.frag
dce.frag
../../LunarGLASS/test/aggOps.frag
../../LunarGLASS/test/always-discard.frag

View File

@ -209,43 +209,39 @@ Shader Functionality to Implement/Finish
- Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arrays extension.
- Compute shaders are now supported, as per the GL_ARB_compute_shader extension.
- Added imageSize() built-ins to query the dimensions of an image.
- Define robust out-of-bounds access behavior when enabled, as per the GL_ARB_robust_buffer_access_behavior extension.
- All choice of depth or stencil texturing, for a packed depth-stencil texture, as per the
GL_ARB_stencil_texturing extension.
- Allow explicit locations/indexes to be assigned to uniform variables and subroutines, as per the
GL_ARB_explicit_uniform_location extension.
- Accept ES GLSL shader #version statements, which will request ES functionality for ES GLSL
+ Accept ES GLSL shader #version statements, which will request ES functionality for ES GLSL
versions 100 and 300, as per the GL_ARB_ES3_compatibility extension.
- Clarify and correct scoping rules to what would normally be expected and what was intended.
+ Clarify and correct scoping rules to what would normally be expected and what was intended.
(Function parameters and body nest inside global space. Loop variables and body nest inside
loop scope.)
- There are no digraphs (trigraphs were already disallowed).
- Remove the CPP difference that it is a compile-time error to use #if or #elif on expressions
+ There are no digraphs (trigraphs were already disallowed).
+ Remove the CPP difference that it is a compile-time error to use #if or #elif on expressions
containing undefined macro names. This reverts back to following expected CPP behavior.
- Set both gl_MaxFragmentImageUniformsand gl_MaxCombinedImageUniforms to 8.
+ Set both gl_MaxFragmentImageUniforms and gl_MaxCombinedImageUniforms to 8.
- Clarify textureSize() for cube map arrays.
- For layout qualifiers,
- make negative output locations a compile-time error, once integer expressions are allowed in layouts
+ make negative output locations a compile-time error, once integer expressions are allowed in layouts
- make indexes outside the range [0,1] a compile-time error.
- Add textureQueryLevels() built-ins to query the number of mipmap levels, as per the
GL_ARB_texture_query_levels extension.
+ Make gl_Layer and gl_ViewportIndex also be inputs to the fragment shader, as per the
GL_ARB_fragment_layer_viewport extension.
- Add more examples and rules to be more specific about the required behavior of the precise
qualifier.
- Clarify fragment output variables cannot be double precision.
- Allow the new shared keyword to be in layout-qualifier-id, allowing backward compatibility
+ Allow the new shared keyword to be in layout-qualifier-id, allowing backward compatibility
with the shared identifier that was previously used.
+ Added overlooked texture function float textureOffset (sampler2DArrayShadow sampler, vec4 P, vec2 offset [, float bias] ).
+ Add missing type in grammar, ATOMIC_UINT, and missing qualifiers COHERENT, VOLATILE, RESTRICT, READONLY, and WRITEONLY.
- do version checking for the above
+ Add missing initializer lists to grammar.
GLSL 4.4
- Incorporate the ARB_enhanced_layouts extension, which adds
- compile-time constant expressions for layout qualifier integers
+ compile-time constant expressions for layout qualifier integers
- new offset and align layout qualifiers for control over buffer block layouts
- add location layout qualifier for input and output blocks and block members
- new componentlayout qualifier for finer-grained layout control of input and output variables and blocks
+ add location layout qualifier for input and output blocks and block members
+ new component layout qualifier for finer-grained layout control of input and output variables and blocks
- new xfb_buffer, xfb_stride, and xfb_offsetlayout qualifiers to allow the shader to control
transform feedback buffering.
+ Bug 10530: To be consistent with ES, include sample types as valid in a precision statement.

View File

@ -353,29 +353,55 @@ public:
{
layoutMatrix = ElmNone;
layoutPacking = ElpNone;
layoutOffset = -1;
layoutAlign = -1;
layoutLocation = layoutLocationEnd;
layoutComponent = layoutComponentEnd;
layoutBinding = layoutBindingEnd;
layoutStream = layoutStreamEnd;
layoutXfbBuffer = layoutXfbBufferEnd;
layoutXfbStride = layoutXfbStrideEnd;
layoutXfbOffset = layoutXfbOffsetEnd;
}
bool hasLayout() const
{
return layoutMatrix != ElmNone ||
layoutPacking != ElpNone ||
return hasUniformLayout() ||
hasLocation() ||
hasBinding() ||
hasStream();
hasStream() ||
hasXfb();
}
TLayoutMatrix layoutMatrix : 3;
TLayoutPacking layoutPacking : 4;
int layoutOffset;
int layoutAlign;
unsigned int layoutLocation : 7;
static const unsigned int layoutLocationEnd = 0x3F;
unsigned int layoutComponent : 3;
static const unsigned int layoutComponentEnd = 4;
unsigned int layoutBinding : 8;
static const unsigned int layoutBindingEnd = 0xFF;
unsigned int layoutStream : 8;
static const unsigned int layoutStreamEnd = 0xFF;
unsigned int layoutXfbBuffer : 4;
static const unsigned int layoutXfbBufferEnd = 0xF;
unsigned int layoutXfbStride : 8;
static const unsigned int layoutXfbStrideEnd = 0xFF;
unsigned int layoutXfbOffset : 8;
static const unsigned int layoutXfbOffsetEnd = 0xFF;
bool hasUniformLayout() const
{
return layoutMatrix != ElmNone ||
layoutPacking != ElpNone ||
layoutOffset != -1 ||
layoutAlign != -1;
}
TLayoutMatrix layoutMatrix : 3;
TLayoutPacking layoutPacking : 4;
unsigned int layoutLocation : 7; // ins/outs should have small numbers, buffer offsets could be large
static const unsigned int layoutLocationEnd = 0x3F;
unsigned int layoutBinding : 8;
static const unsigned int layoutBindingEnd = 0xFF;
unsigned int layoutStream : 8;
static const unsigned int layoutStreamEnd = 0xFF;
bool hasLocation() const
{
return layoutLocation != layoutLocationEnd;
return layoutLocation != layoutLocationEnd ||
layoutComponent != layoutComponentEnd;
}
bool hasBinding() const
{
@ -385,6 +411,12 @@ public:
{
return layoutStream != layoutStreamEnd;
}
bool hasXfb() const
{
return layoutXfbBuffer != layoutXfbBufferEnd ||
layoutXfbStride != layoutXfbStrideEnd ||
layoutXfbOffset != layoutXfbOffsetEnd;
}
static const char* getLayoutPackingString(TLayoutPacking packing)
{
switch (packing) {
@ -824,8 +856,11 @@ public:
if (qualifier.hasLayout()) {
p += snprintf(p, end - p, "layout(");
if (qualifier.hasLocation())
if (qualifier.hasLocation()) {
p += snprintf(p, end - p, "location=%d ", qualifier.layoutLocation);
if (qualifier.layoutComponent != qualifier.layoutComponentEnd)
p += snprintf(p, end - p, "component=%d ", qualifier.layoutComponent);
}
if (qualifier.hasBinding())
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
if (qualifier.hasStream())
@ -834,6 +869,17 @@ public:
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
if (qualifier.layoutPacking != ElpNone)
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking));
if (qualifier.layoutOffset != -1)
p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
if (qualifier.layoutAlign != -1)
p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
if (qualifier.layoutXfbBuffer != qualifier.layoutXfbBufferEnd)
p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer);
if (qualifier.layoutXfbOffset != qualifier.layoutXfbOffsetEnd)
p += snprintf(p, end - p, "xfb_offset=%d ", qualifier.layoutXfbOffset);
if (qualifier.layoutXfbStride != qualifier.layoutXfbStrideEnd)
p += snprintf(p, end - p, "xfb_stride=%d ", qualifier.layoutXfbStride);
p += snprintf(p, end - p, ") ");
}

View File

@ -9,5 +9,5 @@
// source have to figure out how to create revision.h just to get a build
// going. However, if it is not updated, it can be a version behind.
#define GLSLANG_REVISION "24674"
#define GLSLANG_DATE "2014/01/07 10:44:41"
#define GLSLANG_REVISION "24675"
#define GLSLANG_DATE "2014/01/07 11:14:48"

View File

@ -101,6 +101,8 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
globalBufferDefaults.layoutMatrix = ElmColumnMajor;
globalBufferDefaults.layoutPacking = ElpShared;
// TODO: 4.4 enhanced layouts: defaults for xfb?
globalInputDefaults.clear();
globalOutputDefaults.clear();
@ -2429,7 +2431,7 @@ void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList
symbolTable.insert(*block);
// Check for general layout qualifier errors
layoutTypeCheck(loc, *block);
layoutObjectCheck(loc, *block);
// Tracking for implicit sizing of array
if (isIoResizeArray(block->getType())) {
@ -2829,7 +2831,20 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
}
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
if (id == "location") {
if (id == "offset") {
const char* feature = "uniform buffer-member offset";
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
publicType.qualifier.layoutOffset = value;
return;
} else if (id == "align") {
const char* feature = "uniform buffer-member align";
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
publicType.qualifier.layoutAlign = value;
return;
} else if (id == "location") {
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, "location");
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
@ -2837,8 +2852,7 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
else
publicType.qualifier.layoutLocation = value;
return;
}
if (id == "binding") {
} else if (id == "binding") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "binding");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, "binding");
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
@ -2846,7 +2860,37 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
else
publicType.qualifier.layoutBinding = value;
return;
} else if (id == "component") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, "component");
if ((unsigned)value >= TQualifier::layoutComponentEnd)
error(loc, "component is too large", id.c_str(), "");
else
publicType.qualifier.layoutComponent = value;
return;
} else if (id.compare(0, 4, "xfb_") == 0) {
const char* feature = "transform feedback qualifier";
requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature);
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
if (id == "xfb_buffer") {
if (value >= TQualifier::layoutXfbBufferEnd) // TODO: 4.4 enhanced layouts: also check against gl_MaxTransformFeedbackBuffers
error(loc, "buffer is too large", id.c_str(), "");
else
publicType.qualifier.layoutXfbBuffer = value;
} else if (id == "xfb_offset") {
if (value >= TQualifier::layoutXfbOffsetEnd) // TODO: 4.4 enhanced layouts: also check against gl_MaxTransformFeedbackInterleavedComponents
error(loc, "offset is too large", id.c_str(), "");
else
publicType.qualifier.layoutXfbOffset = value;
} else if (id == "xfb_stride") {
if (value >= TQualifier::layoutXfbStrideEnd) // TODO: 4.4 enhanced layouts: also check against gl_MaxTransformFeedbackInterleavedComponents
error(loc, "stride is too large", id.c_str(), "");
else
publicType.qualifier.layoutXfbStride = value;
}
}
switch (language) {
case EShLangVertex:
break;
@ -2900,51 +2944,122 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst,
if (src.layoutPacking != ElpNone)
dst.layoutPacking = src.layoutPacking;
if (! inheritOnly) {
if (src.hasLocation())
dst.layoutLocation = src.layoutLocation;
if (src.hasBinding())
dst.layoutBinding = src.layoutBinding;
}
if (src.hasStream())
dst.layoutStream = src.layoutStream;
if (src.layoutXfbBuffer != TQualifier::layoutXfbBufferEnd)
dst.layoutXfbBuffer = src.layoutXfbBuffer;
if (! inheritOnly) {
if (src.layoutLocation != TQualifier::layoutLocationEnd)
dst.layoutLocation = src.layoutLocation;
if (src.layoutComponent != TQualifier::layoutComponentEnd)
dst.layoutComponent = src.layoutComponent;
if (src.layoutOffset != -1)
dst.layoutOffset = src.layoutOffset;
if (src.layoutAlign != -1)
dst.layoutAlign = src.layoutAlign;
if (src.layoutBinding != TQualifier::layoutBindingEnd)
dst.layoutBinding = src.layoutBinding;
if (src.layoutXfbStride != TQualifier::layoutXfbStrideEnd)
dst.layoutXfbStride = src.layoutXfbStride;
if (src.layoutXfbOffset != TQualifier::layoutXfbOffsetEnd)
dst.layoutXfbOffset = src.layoutXfbOffset;
}
}
// Do error layout error checking given a full variable/block declaration.
void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol)
{
const TType& type = symbol.getType();
const TQualifier& qualifier = type.getQualifier();
// first, qualifier only error checking
// first, cross check WRT to just the type
layoutTypeCheck(loc, type);
// now, any remaining error checking based on the object itself
if (qualifier.hasLocation()) {
switch (qualifier.storage) {
case EvqUniform:
case EvqBuffer:
if (symbol.getAsVariable() == 0)
error(loc, "can only be used on variable declaration", "location", "");
break;
default:
break;
}
}
// Check packing and matrix
// TODO: 4.4 enhanced layouts: generalize to include offset/align
if (qualifier.layoutMatrix || qualifier.layoutPacking) {
switch (qualifier.storage) {
case EvqBuffer:
case EvqUniform:
if (type.getBasicType() != EbtBlock) {
if (qualifier.layoutMatrix != ElmNone)
error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
if (qualifier.layoutPacking != ElpNone)
error(loc, "cannot specify packing on a variable declaration", "layout", "");
}
break;
default:
if (type.getBasicType() != EbtBlock && symbol.getAsVariable()) {
if (qualifier.layoutMatrix != ElmNone ||
qualifier.layoutPacking != ElpNone)
error(loc, "qualifiers for matrix layout and block packing only apply to uniform or buffer blocks", "layout", "");
}
}
}
}
// Do error layout error checking with respect to a type.
void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
{
const TQualifier& qualifier = type.getQualifier();
// first, intra layout qualifier-only error checking
layoutQualifierCheck(loc, qualifier);
// now, error checking combining type and qualifier
if (qualifier.hasLocation()) {
if (qualifier.layoutComponent != TQualifier::layoutComponentEnd) {
// "It is a compile-time error if this sequence of components gets larger than 3."
if (qualifier.layoutComponent + type.getVectorSize() > 4)
error(loc, "type overflows the available 4 components", "component", "");
// "It is a compile-time error to apply the component qualifier to a matrix, a structure, a block, or an array containing any of these."
if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct)
error(loc, "cannot apply to a matrix, structure, or block", "component", "");
}
switch (qualifier.storage) {
case EvqVaryingIn:
case EvqVaryingOut:
if (type.getBasicType() == EbtBlock)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, 0 /* TODO ARB_enhanced_layouts*/, "location qualifier on in/out block");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, "location qualifier on in/out block");
break;
case EvqUniform:
case EvqBuffer:
{
const char* feature = "location qualifier on uniform or buffer";
if (symbol.getAsVariable() == 0)
error(loc, "can only be used on variable declaration", feature, "");
break;
}
default:
error(loc, "location qualifiers only appy to uniform, buffer, in, or out storage qualifiers", symbol.getName().c_str(), "");
error(loc, "can only appy to uniform, buffer, in, or out storage qualifiers", "location", "");
break;
}
int repeated = intermediate.addUsedLocation(qualifier, type);
if (repeated >= 0)
error(loc, "repeated use of location", "location", "%d", repeated);
bool typeCollision;
int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
if (repeated >= 0 && ! typeCollision)
error(loc, "overlapping use of location", "location", "%d", repeated);
// "fragment-shader outputs ... if two variables are placed within the same
// location, they must have the same underlying type (floating-point or integer)"
if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput())
error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated);
}
if (qualifier.hasBinding()) {
@ -2967,34 +3082,22 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
}
}
// Check packing and matrix
if (qualifier.layoutMatrix || qualifier.layoutPacking) {
switch (qualifier.storage) {
case EvqBuffer:
case EvqUniform:
if (symbol.getType().getBasicType() != EbtBlock) {
if (qualifier.layoutMatrix != ElmNone)
error(loc, "cannot specify matrix layout on a variable declaration", symbol.getName().c_str(), "");
if (qualifier.layoutPacking != ElpNone)
error(loc, "cannot specify packing on a variable declaration", symbol.getName().c_str(), "");
}
break;
default:
if (symbol.getType().getBasicType() != EbtBlock && symbol.getAsVariable()) {
if (qualifier.layoutMatrix != ElmNone ||
qualifier.layoutPacking != ElpNone)
error(loc, "layout qualifiers for matrix layout and packing only apply to uniform or buffer blocks", symbol.getName().c_str(), "");
}
}
}
}
// Do layout error checking that can be done within a qualifier proper, not needing to know
// if there are blocks, atomic counters, variables, etc.
void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier)
{
// "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
if (qualifier.layoutComponent != TQualifier::layoutComponentEnd && qualifier.layoutLocation == TQualifier::layoutLocationEnd)
error(loc, "must specify 'location' to use 'component'", "component", "");
if (qualifier.hasLocation()) {
// "As with input layout qualifiers, all shaders except compute shaders
// allow *location* layout qualifiers on output variable declarations,
// output block declarations, and output block member declarations."
switch (qualifier.storage) {
case EvqVaryingIn:
{
@ -3257,7 +3360,7 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
}
// look for errors/adjustments in layout qualifier use
layoutTypeCheck(loc, *symbol);
layoutObjectCheck(loc, *symbol);
// see if it's a linker-level object to track
if (newDeclaration && symbolTable.atGlobalLevel())
@ -3710,7 +3813,10 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
}
// fix and check for member layout qualifiers
// TODO: 4.4 enhanced layouts: generalize to include offset/align
mergeObjectLayoutQualifiers(loc, defaultQualification, currentBlockQualifier, true);
bool memberWithLocation = false;
bool memberWithoutLocation = false;
for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc;
@ -3720,10 +3826,28 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
}
if (memberQualifier.layoutPacking != ElpNone)
error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
if (memberQualifier.hasLocation()) {
const char* feature = "location on block member";
switch (currentBlockQualifier.storage) {
case EvqVaryingIn:
case EvqVaryingOut:
requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile, feature);
profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
memberWithLocation = true;
break;
default:
error(memberLoc, "can only use in an in/out block", feature, "");
break;
}
} else
memberWithoutLocation = true;
TQualifier newMemberQualification = defaultQualification;
mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
memberQualifier = newMemberQualification;
}
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
for (unsigned int member = 0; member < typeList.size(); ++member)
layoutTypeCheck(typeList[member].loc, *typeList[member].type);
// reverse merge, so that currentBlockQualifier now has all layout information
// (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
@ -3783,7 +3907,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
}
// Check for general layout qualifier errors
layoutTypeCheck(loc, variable);
layoutObjectCheck(loc, variable);
if (isIoResizeArray(blockType)) {
ioArraySymbolResizeList.push_back(&variable);
@ -3795,6 +3919,46 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
intermediate.addSymbolLinkageNode(linkage, variable);
}
//
// "For a block, this process applies to the entire block, or until the first member
// is reached that has a location layout qualifier. When a block member is declared with a location
// qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
// until the next member declared with a location qualifier. The values used for locations do not have to be
// declared in increasing order."
void TParseContext::fixBlockLocations(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
{
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members
// have a location layout qualifier, or a compile-time error results."
if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
else {
if (memberWithLocation) {
// remove any block-level location and make it per *every* member
int nextLocation; // by the rule above, initial value is not relevant
if (qualifier.hasLocation()) {
nextLocation = qualifier.layoutLocation;
qualifier.layoutLocation = TQualifier::layoutLocationEnd;
if (qualifier.layoutComponent != TQualifier::layoutComponentEnd) {
// "It is a compile-time error to apply the *component* qualifier to a ... block"
error(loc, "cannot apply to a block", "component", "");
}
}
for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc;
if (! memberQualifier.hasLocation()) {
if (nextLocation >= TQualifier::layoutLocationEnd)
error(memberLoc, "location is too large", "location", "");
memberQualifier.layoutLocation = nextLocation;
memberQualifier.layoutComponent = 0;
}
nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
}
}
}
}
// For an identifier that is already declared, add more qualification to it.
void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
{
@ -3941,6 +4105,7 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
layoutQualifierCheck(loc, qualifier);
// TODO: 4.4 enhanced layouts: generalize to include all new ones
switch (qualifier.storage) {
case EvqUniform:
if (qualifier.layoutMatrix != ElmNone)

View File

@ -150,7 +150,8 @@ public:
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, const TIntermTyped*);
void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src, bool inheritOnly);
void layoutTypeCheck(TSourceLoc, const TSymbol&);
void layoutObjectCheck(TSourceLoc, const TSymbol&);
void layoutTypeCheck(TSourceLoc, const TType&);
void layoutQualifierCheck(TSourceLoc, const TQualifier&);
void checkNoShaderLayouts(TSourceLoc, const TShaderQualifiers&);
@ -163,6 +164,7 @@ public:
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
void invariantCheck(TSourceLoc, const TType&, const TString& identifier);

View File

@ -252,7 +252,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
writeTypeComparison = true;
}
// Layouts...
// Layouts...
// TODO: 4.4 enhanced layouts: generalize to include offset/align
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
@ -481,8 +482,14 @@ bool TIntermediate::userOutputUsed() const
// as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type)
//
// typeCollision is set to true if there is no direct collision, but the types in the same location
// are different.
//
int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type, bool& typeCollision)
{
typeCollision = false;
int set;
if (qualifier.isPipeInput())
set = 0;
@ -510,20 +517,34 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
size = computeTypeLocationSize(type);
}
TRange range = { qualifier.layoutLocation, qualifier.layoutLocation + size - 1 };
TRange locationRange = { qualifier.layoutLocation, qualifier.layoutLocation + size - 1 };
TRange componentRange = { 0, 3 };
if (qualifier.layoutComponent != TQualifier::layoutComponentEnd) {
componentRange.start = qualifier.layoutComponent;
componentRange.last = componentRange.start + type.getVectorSize() - 1;
}
// check for collisions, except for vertex inputs on desktop
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) {
for (size_t r = 0; r < usedLocations[set].size(); ++r) {
if (range.last >= usedLocations[set][r].start &&
range.start <= usedLocations[set][r].last) {
for (size_t r = 0; r < usedIo[set].size(); ++r) {
if (locationRange.last >= usedIo[set][r].location.start &&
locationRange.start <= usedIo[set][r].location.last &&
componentRange.last >= usedIo[set][r].component.start &&
componentRange.start <= usedIo[set][r].component.last) {
// there is a collision; pick one
return std::max(range.start, usedLocations[set][r].start);
return std::max(locationRange.start, usedIo[set][r].location.start);
} else if (locationRange.last >= usedIo[set][r].location.start &&
locationRange.start <= usedIo[set][r].location.last &&
type.getBasicType() != usedIo[set][r].basicType) {
typeCollision = true;
return std::max(locationRange.start, usedIo[set][r].location.start);
}
}
}
usedLocations[set].push_back(range);
TIoRange range = { locationRange, componentRange, type.getBasicType() };
usedIo[set].push_back(range);
return -1;
}
@ -546,7 +567,6 @@ int TIntermediate::computeTypeLocationSize(const TType& type)
// "The locations consumed by block and structure members are determined by applying the rules above
// recursively..."
if (type.isStruct()) {
// TODO: 440 functionality: input/output block locations when members also have locations
int size = 0;
for (size_t member = 0; member < type.getStruct()->size(); ++member) {
TType memberType(type, member);

View File

@ -172,7 +172,8 @@ public:
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
int addUsedLocation(const TQualifier&, const TType&);
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
int computeTypeLocationSize(const TType&);
protected:
void error(TInfoSink& infoSink, const char*);
@ -183,7 +184,6 @@ protected:
void inOutLocationCheck(TInfoSink&);
TIntermSequence& findLinkerObjects() const;
bool userOutputUsed() const;
int computeTypeLocationSize(const TType&);
protected:
const EShLanguage language;
@ -217,11 +217,19 @@ protected:
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
// A location range is a 2-D rectangle; the set of (location, component) pairs all lying
// both within the location range and the component range.
// The following are entirely encapsulated by addUsedLocation().
struct TRange {
int start;
int last;
};
std::vector<TRange> usedLocations[3]; // sets of used locations, one for each of in, out, and uniform
struct TIoRange {
TRange location;
TRange component;
TBasicType basicType;
};
std::vector<TIoRange> usedIo[3]; // sets of used locations, one for each of in, out, and uniform
private:
void operator=(TIntermediate&); // prevent assignments