mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 20:10:06 +00:00
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:
parent
b76d6d6496
commit
68546c6ca4
@ -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
22
Test/440.frag
Normal 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
64
Test/440.vert
Normal 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;
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
25
Test/baseResults/440.frag.out
Normal file
25
Test/baseResults/440.frag.out
Normal 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
|
||||
|
||||
|
66
Test/baseResults/440.vert.out
Normal file
66
Test/baseResults/440.vert.out
Normal 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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
24
Todo.txt
24
Todo.txt
@ -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.
|
||||
|
@ -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, ") ");
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user