mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 19:40:06 +00:00
Add geometry-shader stream, invocations, max_vertices, lines, triangles, etc. layout qualifiers, and their default/inheritance behaviors, and some other misc. geometry shader features. (Geometry shaders are not yet done though.)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23679 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
284231c9c5
commit
94fdd1117b
@ -36,3 +36,57 @@ void main()
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
gl_Layer = 2;
|
||||
}
|
||||
|
||||
out vec4 ov0; // stream should be 0
|
||||
layout(stream = 4) out vec4 ov4;
|
||||
out vec4 o1v0; // stream should be 0
|
||||
|
||||
layout(stream = 3) uniform; // ERROR
|
||||
layout(stream = 3) in; // ERROR
|
||||
layout(stream = 3) uniform int ua; // ERROR
|
||||
layout(stream = 3) uniform ubb { int ua; } ibb; // ERROR
|
||||
|
||||
layout(line_strip, points, triangle_strip, stream = 3, points, triangle_strip) out; // just means "stream = 3, triangle_strip"
|
||||
layout(stream = 3, triangle_strip) out;
|
||||
out vec4 ov3; // stream should be 3
|
||||
|
||||
layout(stream = 6) out ooutb { vec4 a; } ouuaa6;
|
||||
|
||||
layout(stream = 6) out ooutb {
|
||||
layout(stream = 6) vec4 a;
|
||||
} ouua6;
|
||||
|
||||
layout(stream = 7) out ooutb {
|
||||
layout(stream = 6) vec4 a; // ERROR
|
||||
} ouua7;
|
||||
|
||||
out vec4 ov2s3; // stream should be 3
|
||||
|
||||
void foo(layout(max_vertices = 4) int a) // ERROR
|
||||
{
|
||||
ouuaa6.a = vec4(1.0);
|
||||
}
|
||||
|
||||
layout(line_strip, points, triangle_strip, stream = 3, points) out; // ERROR, changing output primitive
|
||||
layout(line_strip, points, stream = 3) out; // ERROR, changing output primitive
|
||||
layout(triangle_strip) in; // ERROR, not an input primitive
|
||||
layout(triangle_strip) uniform; // ERROR
|
||||
layout(triangle_strip) out vec4 badv4; // ERROR, not on a variable
|
||||
layout(triangle_strip) in vec4 bad2v4; // ERROR, not on a variable or input
|
||||
layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block
|
||||
out outbn {
|
||||
layout(invocations = 3) int a; // ERROR, not on a block member
|
||||
layout(max_vertices = 3) int b; // ERROR, not on a block member
|
||||
layout(triangle_strip) int c; // ERROR, not on a block member
|
||||
} outbi;
|
||||
|
||||
layout(lines) out; // ERROR, not on output
|
||||
layout(lines_adjancency) in;
|
||||
layout(triangles) in; // ERROR, can't change it
|
||||
layout(triangles_adjacency) in; // ERROR, can't change it
|
||||
|
||||
layout(invocations = 4, max_vertices = 127) out;
|
||||
|
||||
in inbn {
|
||||
layout(stream = 2) int a; // ERROR, stream on input
|
||||
} inbi;
|
||||
|
@ -9,3 +9,6 @@ void main()
|
||||
|
||||
int id = gl_InvocationID;
|
||||
}
|
||||
|
||||
layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block
|
||||
layout(max_vertices = 127, invocations = 4) out;
|
||||
|
@ -101,6 +101,6 @@ ERROR: node is still EOpNull!
|
||||
0:? 'uint' (mediump int)
|
||||
0:? 'v' (smooth in 3-element array of mediump 4-component vector of float)
|
||||
0:? 'f' (mediump float)
|
||||
0:? '__anon__0' (layout(shared ) uniform block)
|
||||
0:? '__anon__0' (layout(column_major shared ) uniform block)
|
||||
0:? 'fa' (unsized array of mediump float)
|
||||
|
||||
|
@ -4,8 +4,35 @@ ERROR: 0:19: 'fromVertex' : redefinition
|
||||
ERROR: 0:21: 'fooC' : block instance name redefinition
|
||||
ERROR: 0:29: 'EmitStreamVertex' : no matching overloaded function found
|
||||
ERROR: 0:30: 'EndStreamPrimitive' : no matching overloaded function found
|
||||
ERROR: 5 compilation errors. No code generated.
|
||||
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: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
|
||||
ERROR: 0:71: 'points' : cannot change previously set output primitive
|
||||
ERROR: 0:72: 'triangle_strip' : does not apply to input
|
||||
ERROR: 0:73: 'triangle_strip' : cannot be used here
|
||||
ERROR: 0:74: 'triangle_strip' : can only apply to a standalone qualifier
|
||||
ERROR: 0:75: 'triangle_strip' : can only apply to a standalone qualifier
|
||||
ERROR: 0:76: 'invocations' : not supported for this version or the enabled extensions
|
||||
ERROR: 0:76: 'invocations' : can only apply to a standalone qualifier
|
||||
ERROR: 0:78: 'invocations' : not supported for this version or the enabled extensions
|
||||
ERROR: 0:78: 'invocations' : can only apply to a standalone qualifier
|
||||
ERROR: 0:79: 'max_vertices' : can only apply to a standalone qualifier
|
||||
ERROR: 0:80: 'triangle_strip' : can only apply to a standalone qualifier
|
||||
ERROR: 0:83: 'lines' : does not only apply to output
|
||||
ERROR: 0:85: 'triangles' : cannot change previously set input primitive
|
||||
ERROR: 0:86: 'triangles_adjacency' : cannot change previously set input primitive
|
||||
ERROR: 0:88: 'invocations' : not supported for this version or the enabled extensions
|
||||
ERROR: 0:91: 'stream' : member cannot contradict block
|
||||
ERROR: 28 compilation errors. No code generated.
|
||||
|
||||
invocations = 4
|
||||
max_vertices = 127
|
||||
input primitive = lines_adjancency
|
||||
output primitive = triangle_strip
|
||||
ERROR: node is still EOpNull!
|
||||
0:25 Function Definition: main( (void)
|
||||
0:25 Function Parameters:
|
||||
@ -17,8 +44,8 @@ ERROR: node is still EOpNull!
|
||||
0:30 Constant:
|
||||
0:30 0.000000
|
||||
0:32 move second child to first child (3-component vector of float)
|
||||
0:32 color: direct index for structure (3-component vector of float)
|
||||
0:32 '__anon__0' (out block)
|
||||
0:32 color: direct index for structure (layout(stream=0 ) 3-component vector of float)
|
||||
0:32 '__anon__0' (layout(stream=0 ) out block)
|
||||
0:32 Constant:
|
||||
0:32 0 (const uint)
|
||||
0:32 color: direct index for structure (3-component vector of float)
|
||||
@ -26,9 +53,9 @@ ERROR: node is still EOpNull!
|
||||
0:32 Constant:
|
||||
0:32 0 (const int)
|
||||
0:33 move second child to first child (float)
|
||||
0:33 direct index (float)
|
||||
0:33 gl_ClipDistance: direct index for structure (unsized array of float)
|
||||
0:33 '__anon__1' (out block)
|
||||
0:33 direct index (layout(stream=0 ) float)
|
||||
0:33 gl_ClipDistance: direct index for structure (layout(stream=0 ) unsized array of float)
|
||||
0:33 '__anon__1' (layout(stream=0 ) out block)
|
||||
0:33 Constant:
|
||||
0:33 2 (const uint)
|
||||
0:33 Constant:
|
||||
@ -44,8 +71,8 @@ ERROR: node is still EOpNull!
|
||||
0:33 Constant:
|
||||
0:33 2 (const int)
|
||||
0:34 move second child to first child (4-component vector of float)
|
||||
0:34 gl_Position: direct index for structure (4-component vector of float)
|
||||
0:34 '__anon__1' (out block)
|
||||
0:34 gl_Position: direct index for structure (layout(stream=0 ) 4-component vector of float)
|
||||
0:34 '__anon__1' (layout(stream=0 ) out block)
|
||||
0:34 Constant:
|
||||
0:34 0 (const uint)
|
||||
0:34 gl_Position: direct index for structure (4-component vector of float)
|
||||
@ -56,8 +83,8 @@ ERROR: node is still EOpNull!
|
||||
0:34 Constant:
|
||||
0:34 0 (const int)
|
||||
0:35 move second child to first child (float)
|
||||
0:35 gl_PointSize: direct index for structure (float)
|
||||
0:35 '__anon__1' (out block)
|
||||
0:35 gl_PointSize: direct index for structure (layout(stream=0 ) float)
|
||||
0:35 '__anon__1' (layout(stream=0 ) out block)
|
||||
0:35 Constant:
|
||||
0:35 1 (const uint)
|
||||
0:35 gl_PointSize: direct index for structure (float)
|
||||
@ -68,14 +95,43 @@ ERROR: node is still EOpNull!
|
||||
0:35 Constant:
|
||||
0:35 1 (const int)
|
||||
0:36 move second child to first child (int)
|
||||
0:36 'gl_PrimitiveID' (out int)
|
||||
0:36 'gl_PrimitiveID' (layout(stream=0 ) out int)
|
||||
0:36 'gl_PrimitiveIDIn' (in int)
|
||||
0:37 move second child to first child (int)
|
||||
0:37 'gl_Layer' (out int)
|
||||
0:37 'gl_Layer' (layout(stream=0 ) out int)
|
||||
0:37 Constant:
|
||||
0:37 2 (const int)
|
||||
0:65 Function Definition: foo(i1; (void)
|
||||
0:65 Function Parameters:
|
||||
0:65 'a' (in int)
|
||||
0:67 Sequence
|
||||
0:67 move second child to first child (4-component vector of float)
|
||||
0:67 a: direct index for structure (layout(stream=6 ) 4-component vector of float)
|
||||
0:67 'ouuaa6' (layout(stream=6 ) out block)
|
||||
0:67 Constant:
|
||||
0:67 0 (const int)
|
||||
0:67 Constant:
|
||||
0:67 1.000000
|
||||
0:67 1.000000
|
||||
0:67 1.000000
|
||||
0:67 1.000000
|
||||
0:? Linker Objects
|
||||
0:? 'fromV' (in block)
|
||||
0:? 'toF' (out block)
|
||||
0:? '__anon__0' (out block)
|
||||
0:? 'toF' (layout(stream=0 ) out block)
|
||||
0:? '__anon__0' (layout(stream=0 ) out block)
|
||||
0:? 'ov0' (layout(stream=0 ) out 4-component vector of float)
|
||||
0:? 'ov4' (layout(stream=4 ) out 4-component vector of float)
|
||||
0:? 'o1v0' (layout(stream=0 ) out 4-component vector of float)
|
||||
0:? 'ua' (layout(stream=3 ) uniform int)
|
||||
0:? 'ibb' (layout(stream=3 column_major shared ) uniform block)
|
||||
0:? 'ov3' (layout(stream=3 ) out 4-component vector of float)
|
||||
0:? 'ouuaa6' (layout(stream=6 ) out block)
|
||||
0:? 'ouua6' (layout(stream=6 ) out block)
|
||||
0:? 'ouua7' (layout(stream=7 ) out block)
|
||||
0:? 'ov2s3' (layout(stream=3 ) out 4-component vector of float)
|
||||
0:? 'badv4' (layout(stream=3 ) out 4-component vector of float)
|
||||
0:? 'bad2v4' (in 4-component vector of float)
|
||||
0:? '__anon__1' (layout(stream=3 ) out block)
|
||||
0:? 'outbi' (layout(stream=3 ) out block)
|
||||
0:? 'inbi' (in block)
|
||||
|
||||
|
@ -33,7 +33,7 @@ ERROR: node is still EOpNull!
|
||||
0:? Linker Objects
|
||||
0:? 'iv4' (in 4-component vector of float)
|
||||
0:? 'ps' (uniform float)
|
||||
0:? '__anon__1' (layout(shared ) uniform block)
|
||||
0:? '__anon__1' (layout(column_major shared ) uniform block)
|
||||
0:? 'gl_VertexID' (gl_VertexId int)
|
||||
0:? 'gl_InstanceID' (gl_InstanceId int)
|
||||
|
||||
|
@ -239,5 +239,5 @@ ERROR: node is still EOpNull!
|
||||
0:? 'sc' (out lowp 3-component vector of float)
|
||||
0:? 'sf' (out lowp float)
|
||||
0:? 'arrayedSampler' (uniform 5-element array of lowp sampler2D)
|
||||
0:? 'multiInst' (layout(shared ) uniform 2-element array of block)
|
||||
0:? 'multiInst' (layout(column_major shared ) uniform 2-element array of block)
|
||||
|
||||
|
@ -153,7 +153,7 @@ ERROR: node is still EOpNull!
|
||||
0:? 's' (smooth out structure)
|
||||
0:? 'badsize' (unsized array of highp float)
|
||||
0:? 'badsize2' (unsized array of highp float)
|
||||
0:? 'ubInst' (layout(shared ) uniform unsized array of block)
|
||||
0:? 'ubInst' (layout(column_major shared ) uniform unsized array of block)
|
||||
0:? 'okayA' (2-element array of highp float)
|
||||
0:? 'gl_VertexID' (gl_VertexId highp int)
|
||||
0:? 'gl_InstanceID' (gl_InstanceId highp int)
|
||||
|
@ -16,13 +16,13 @@ ERROR: node is still EOpNull!
|
||||
0:44 Construct vec3 (3-component vector of float)
|
||||
0:44 Convert int to float (float)
|
||||
0:44 ni: direct index for structure (layout(column_major shared ) mediump int)
|
||||
0:44 'inst' (layout(shared ) uniform block)
|
||||
0:44 'inst' (layout(column_major shared ) uniform block)
|
||||
0:44 Constant:
|
||||
0:44 1 (const int)
|
||||
0:44 Convert uint to float (float)
|
||||
0:44 direct index (mediump uint)
|
||||
0:44 bv: direct index for structure (layout(column_major shared ) mediump 4-component vector of uint)
|
||||
0:44 '__anon__0' (layout(shared ) uniform block)
|
||||
0:44 '__anon__0' (layout(column_major shared ) uniform block)
|
||||
0:44 Constant:
|
||||
0:44 0 (const uint)
|
||||
0:44 Constant:
|
||||
@ -30,16 +30,16 @@ ERROR: node is still EOpNull!
|
||||
0:44 Convert uint to float (float)
|
||||
0:44 direct index (mediump uint)
|
||||
0:44 nbv: direct index for structure (layout(column_major shared ) mediump 4-component vector of uint)
|
||||
0:44 direct index (layout(shared ) uniform block)
|
||||
0:44 'insts' (layout(shared ) uniform 4-element array of block)
|
||||
0:44 direct index (layout(column_major shared ) uniform block)
|
||||
0:44 'insts' (layout(column_major shared ) uniform 4-element array of block)
|
||||
0:44 Constant:
|
||||
0:44 2 (const int)
|
||||
0:44 Constant:
|
||||
0:44 0 (const int)
|
||||
0:44 Constant:
|
||||
0:44 2 (const int)
|
||||
0:45 indirect index (layout(shared ) uniform block)
|
||||
0:45 'insts' (layout(shared ) uniform 4-element array of block)
|
||||
0:45 indirect index (layout(column_major shared ) uniform block)
|
||||
0:45 'insts' (layout(column_major shared ) uniform 4-element array of block)
|
||||
0:45 direct index (mediump uint)
|
||||
0:45 v: direct index for structure (mediump 4-component vector of uint)
|
||||
0:45 's' (uniform structure)
|
||||
@ -49,8 +49,8 @@ ERROR: node is still EOpNull!
|
||||
0:45 0 (const int)
|
||||
0:? Linker Objects
|
||||
0:? 's' (uniform structure)
|
||||
0:? '__anon__0' (layout(shared ) uniform block)
|
||||
0:? 'inst' (layout(shared ) uniform block)
|
||||
0:? 'insts' (layout(shared ) uniform 4-element array of block)
|
||||
0:? '__anon__1' (layout(shared ) uniform block)
|
||||
0:? '__anon__0' (layout(column_major shared ) uniform block)
|
||||
0:? 'inst' (layout(column_major shared ) uniform block)
|
||||
0:? 'insts' (layout(column_major shared ) uniform 4-element array of block)
|
||||
0:? '__anon__1' (layout(column_major shared ) uniform block)
|
||||
|
||||
|
@ -25,11 +25,11 @@ ERROR: node is still EOpNull!
|
||||
0:43 add (highp 4X4 matrix of float)
|
||||
0:43 add (highp 4X4 matrix of float)
|
||||
0:43 M1: direct index for structure (layout(row_major std140 ) highp 4X4 matrix of float)
|
||||
0:43 'tblock' (layout(std140 ) uniform block)
|
||||
0:43 'tblock' (layout(row_major std140 ) uniform block)
|
||||
0:43 Constant:
|
||||
0:43 0 (const int)
|
||||
0:43 M2: direct index for structure (layout(column_major std140 ) highp 4X4 matrix of float)
|
||||
0:43 'tblock' (layout(std140 ) uniform block)
|
||||
0:43 'tblock' (layout(row_major std140 ) uniform block)
|
||||
0:43 Constant:
|
||||
0:43 1 (const int)
|
||||
0:43 M4: direct index for structure (layout(row_major shared ) highp 4X4 matrix of float)
|
||||
@ -41,7 +41,7 @@ ERROR: node is still EOpNull!
|
||||
0:43 Constant:
|
||||
0:43 0 (const uint)
|
||||
0:43 t2m: direct index for structure (layout(row_major shared ) highp 4X4 matrix of float)
|
||||
0:43 '__anon__0' (layout(shared ) uniform block)
|
||||
0:43 '__anon__0' (layout(row_major shared ) uniform block)
|
||||
0:43 Constant:
|
||||
0:43 1 (const uint)
|
||||
0:44 move second child to first child (highp 3-component vector of float)
|
||||
@ -49,7 +49,7 @@ ERROR: node is still EOpNull!
|
||||
0:44 vector-times-matrix (highp 3-component vector of float)
|
||||
0:44 'c' (layout(location=7 ) in highp 3-component vector of float)
|
||||
0:44 N1: direct index for structure (layout(row_major std140 ) highp 3X3 matrix of float)
|
||||
0:44 'tblock' (layout(std140 ) uniform block)
|
||||
0:44 'tblock' (layout(row_major std140 ) uniform block)
|
||||
0:44 Constant:
|
||||
0:44 2 (const int)
|
||||
0:? Linker Objects
|
||||
@ -60,8 +60,8 @@ ERROR: node is still EOpNull!
|
||||
0:? 'pos' (smooth out highp 4-component vector of float)
|
||||
0:? 'color' (smooth out highp 3-component vector of float)
|
||||
0:? 'badm4' (layout(column_major shared ) uniform highp 4X4 matrix of float)
|
||||
0:? 'tblock' (layout(std140 ) uniform block)
|
||||
0:? '__anon__0' (layout(shared ) uniform block)
|
||||
0:? 'tblock' (layout(row_major std140 ) uniform block)
|
||||
0:? '__anon__0' (layout(row_major shared ) uniform block)
|
||||
0:? '__anon__2' (out block)
|
||||
0:? 'badoutA' (layout(location=10 ) smooth out highp 4-component vector of float)
|
||||
0:? 'compute_only' (shared highp 4-component vector of float)
|
||||
|
@ -1,5 +1,5 @@
|
||||
ERROR: 0:11: 'float' : type requires declaration of default precision qualifier
|
||||
ERROR: 0:30: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'layout(shared ) uniform block' and a right operand of type 'layout(shared ) uniform block' (or there is no acceptable conversion)
|
||||
ERROR: 0:30: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'layout(column_major shared ) uniform block' and a right operand of type 'layout(column_major shared ) uniform block' (or there is no acceptable conversion)
|
||||
ERROR: 0:31: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'structure' and a right operand of type 'structure' (or there is no acceptable conversion)
|
||||
ERROR: 0:32: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'mediump int' and a right operand of type 'mediump float' (or there is no acceptable conversion)
|
||||
ERROR: 0:33: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'mediump uint' and a right operand of type 'mediump float' (or there is no acceptable conversion)
|
||||
@ -14,7 +14,7 @@ ERROR: 0:42: '%' : wrong operand types: no operation '%' exists that takes a le
|
||||
ERROR: 0:43: '%' : wrong operand types: no operation '%' exists that takes a left-hand operand of type 'mediump int' and a right operand of type 'mediump float' (or there is no acceptable conversion)
|
||||
ERROR: 0:44: '%' : wrong operand types: no operation '%' exists that takes a left-hand operand of type 'mediump float' and a right operand of type 'mediump uint' (or there is no acceptable conversion)
|
||||
ERROR: 0:45: '++' : l-value required "instanceName" (can't modify a uniform)
|
||||
ERROR: 0:45: '++' : wrong operand type no operation '++' exists that takes an operand of type layout(shared ) uniform block (or there is no acceptable conversion)
|
||||
ERROR: 0:45: '++' : wrong operand type no operation '++' exists that takes an operand of type layout(column_major shared ) uniform block (or there is no acceptable conversion)
|
||||
ERROR: 0:46: '++' : wrong operand type no operation '++' exists that takes an operand of type structure (or there is no acceptable conversion)
|
||||
ERROR: 0:47: '--' : wrong operand type no operation '--' exists that takes an operand of type 5-element array of mediump float (or there is no acceptable conversion)
|
||||
ERROR: 0:48: '++' : wrong operand type no operation '++' exists that takes an operand of type 3-component vector of bool (or there is no acceptable conversion)
|
||||
@ -39,7 +39,7 @@ ERROR: 0:70: '~' : wrong operand type no operation '~' exists that takes an ope
|
||||
ERROR: 0:71: '~' : wrong operand type no operation '~' exists that takes an operand of type mediump 4X4 matrix of float (or there is no acceptable conversion)
|
||||
ERROR: 0:72: '~' : wrong operand type no operation '~' exists that takes an operand of type mediump 3-component vector of float (or there is no acceptable conversion)
|
||||
ERROR: 0:73: '~' : wrong operand type no operation '~' exists that takes an operand of type 5-element array of mediump float (or there is no acceptable conversion)
|
||||
ERROR: 0:74: '~' : wrong operand type no operation '~' exists that takes an operand of type layout(shared ) uniform block (or there is no acceptable conversion)
|
||||
ERROR: 0:74: '~' : wrong operand type no operation '~' exists that takes an operand of type layout(column_major shared ) uniform block (or there is no acceptable conversion)
|
||||
ERROR: 0:76: '<<' : wrong operand types: no operation '<<' exists that takes a left-hand operand of type 'mediump int' and a right operand of type 'mediump 3-component vector of int' (or there is no acceptable conversion)
|
||||
ERROR: 0:77: '<<' : wrong operand types: no operation '<<' exists that takes a left-hand operand of type 'mediump uint' and a right operand of type 'mediump 3-component vector of uint' (or there is no acceptable conversion)
|
||||
ERROR: 0:78: '>>' : wrong operand types: no operation '>>' exists that takes a left-hand operand of type 'mediump int' and a right operand of type 'mediump float' (or there is no acceptable conversion)
|
||||
@ -60,7 +60,7 @@ ERROR: node is still EOpNull!
|
||||
0:13 Function Definition: main( (void)
|
||||
0:13 Function Parameters:
|
||||
0:? Sequence
|
||||
0:30 'instanceName' (layout(shared ) uniform block)
|
||||
0:30 'instanceName' (layout(column_major shared ) uniform block)
|
||||
0:31 's' (structure)
|
||||
0:32 'i' (mediump int)
|
||||
0:33 'u' (mediump uint)
|
||||
@ -74,7 +74,7 @@ ERROR: node is still EOpNull!
|
||||
0:42 'f' (mediump float)
|
||||
0:43 'i' (mediump int)
|
||||
0:44 'f' (mediump float)
|
||||
0:45 'instanceName' (layout(shared ) uniform block)
|
||||
0:45 'instanceName' (layout(column_major shared ) uniform block)
|
||||
0:46 's' (structure)
|
||||
0:47 'a' (5-element array of mediump float)
|
||||
0:48 'b3' (3-component vector of bool)
|
||||
@ -111,7 +111,7 @@ ERROR: node is still EOpNull!
|
||||
0:71 'm4' (mediump 4X4 matrix of float)
|
||||
0:72 'v3' (mediump 3-component vector of float)
|
||||
0:73 'a' (5-element array of mediump float)
|
||||
0:74 'instanceName' (layout(shared ) uniform block)
|
||||
0:74 'instanceName' (layout(column_major shared ) uniform block)
|
||||
0:76 'i' (mediump int)
|
||||
0:77 'u' (mediump uint)
|
||||
0:78 'i' (mediump int)
|
||||
@ -212,7 +212,7 @@ ERROR: node is still EOpNull!
|
||||
0:127 'iv3' (mediump 3-component vector of int)
|
||||
0:127 'iv3' (mediump 3-component vector of int)
|
||||
0:? Linker Objects
|
||||
0:? 'instanceName' (layout(shared ) uniform block)
|
||||
0:? 'instanceName' (layout(column_major shared ) uniform block)
|
||||
0:? 's' (structure)
|
||||
0:? 'a' (5-element array of mediump float)
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
|
||||
0:? Sequence
|
||||
ERROR: 0:13: 'invocations' : can only apply to a standalone qualifier
|
||||
ERROR: 1 compilation errors. No code generated.
|
||||
|
||||
invocations = 4
|
||||
max_vertices = 127
|
||||
input primitive = none
|
||||
output primitive = none
|
||||
ERROR: node is still EOpNull!
|
||||
0:3 Function Definition: main( (void)
|
||||
0:3 Function Parameters:
|
||||
0:5 Sequence
|
||||
@ -16,4 +23,5 @@ Warning, version 400 is not yet complete; some version-specific features are pre
|
||||
0:10 'id' (int)
|
||||
0:10 'gl_InvocationID' (in int)
|
||||
0:? Linker Objects
|
||||
0:? '__anon__0' (layout(stream=0 ) out block)
|
||||
|
||||
|
@ -1,10 +1,14 @@
|
||||
Warning, version 410 is not yet complete; some version-specific features are present, but many are missing.
|
||||
invocations = 0
|
||||
max_vertices = 0
|
||||
input primitive = none
|
||||
output primitive = none
|
||||
0:? Sequence
|
||||
0:3 Function Definition: main( (void)
|
||||
0:3 Function Parameters:
|
||||
0:5 Sequence
|
||||
0:5 move second child to first child (int)
|
||||
0:5 'gl_ViewportIndex' (out int)
|
||||
0:5 'gl_ViewportIndex' (layout(stream=0 ) out int)
|
||||
0:5 Constant:
|
||||
0:5 7 (const int)
|
||||
0:? Linker Objects
|
||||
|
@ -116,10 +116,10 @@ ERROR: node is still EOpNull!
|
||||
0:? 4.200000
|
||||
0:? 'dx' (const float)
|
||||
0:? 4.200000
|
||||
0:? 'boundInst' (layout(binding=3 shared ) uniform block)
|
||||
0:? '__anon__0' (layout(binding=7 shared ) uniform block)
|
||||
0:? 'boundInst' (layout(binding=3 column_major shared ) uniform block)
|
||||
0:? '__anon__0' (layout(binding=7 column_major shared ) uniform block)
|
||||
0:? '__anon__1' (layout(binding=1 ) in block)
|
||||
0:? '__anon__2' (layout(shared ) uniform block)
|
||||
0:? '__anon__2' (layout(column_major shared ) uniform block)
|
||||
0:? 'sampb1' (layout(binding=4 ) uniform sampler2D)
|
||||
0:? 'sampb2' (layout(binding=5 ) uniform 10-element array of sampler2D)
|
||||
0:? 'gl_VertexID' (gl_VertexId int)
|
||||
|
@ -20,6 +20,10 @@ Warning, version 150 is not yet complete; some version-specific features are pre
|
||||
ERROR: 1 compilation errors. No code generated.
|
||||
|
||||
|
||||
invocations = 0
|
||||
max_vertices = 0
|
||||
input primitive = none
|
||||
output primitive = none
|
||||
ERROR: node is still EOpNull!
|
||||
0:3 Function Definition: foo( (void)
|
||||
0:3 Function Parameters:
|
||||
@ -28,6 +32,10 @@ ERROR: node is still EOpNull!
|
||||
noMain2.geom
|
||||
Warning, version 150 is not yet complete; some version-specific features are present, but many are missing.
|
||||
|
||||
invocations = 0
|
||||
max_vertices = 0
|
||||
input primitive = none
|
||||
output primitive = none
|
||||
0:? Sequence
|
||||
0:3 Function Definition: bar( (void)
|
||||
0:3 Function Parameters:
|
||||
@ -43,6 +51,10 @@ Linked fragment stage:
|
||||
ERROR: Linking fragment stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
|
||||
main(
|
||||
|
||||
invocations = 0
|
||||
max_vertices = 0
|
||||
input primitive = none
|
||||
output primitive = none
|
||||
ERROR: node is still EOpNull!
|
||||
0:3 Function Definition: foo( (void)
|
||||
0:3 Function Parameters:
|
||||
|
@ -6,21 +6,21 @@ ERROR: 0:37: 'view' : redefinition
|
||||
ERROR: 0:68: 'lightPosition' : redefinition
|
||||
ERROR: 0:75: 'Atten' : member storage qualifier cannot contradict block storage qualifier
|
||||
ERROR: 0:87: 'Color' : redefinition
|
||||
ERROR: 0:92: 'origin_upper_left' : unrecognized layout identifier
|
||||
ERROR: 0:93: 'pixel_center_integer' : unrecognized layout identifier
|
||||
ERROR: 0:94: 'origin_upper_left' : unrecognized layout identifier
|
||||
ERROR: 0:94: 'pixel_center_integer' : unrecognized layout identifier
|
||||
ERROR: 0:96: 'early_fragment_tests' : unrecognized layout identifier
|
||||
ERROR: 0:99: 'local_size_x' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:99: 'local_size_y' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:100: 'local_size_x' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:92: 'origin_upper_left' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:93: 'pixel_center_integer' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:94: 'origin_upper_left' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:94: 'pixel_center_integer' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:96: 'early_fragment_tests' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:99: 'local_size_x' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:99: 'local_size_y' : there is no such layout identifier for this stage taking an assigned value
|
||||
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 taking an assigned value
|
||||
ERROR: 0:106: 'depth_greater' : unrecognized layout identifier
|
||||
ERROR: 0:112: 'depth_any' : unrecognized layout identifier
|
||||
ERROR: 0:115: 'depth_greater' : unrecognized layout identifier
|
||||
ERROR: 0:118: 'depth_less' : unrecognized layout identifier
|
||||
ERROR: 0:121: 'depth_unchanged' : unrecognized layout identifier
|
||||
ERROR: 0:103: 'index' : there is no such layout identifier for this stage taking an assigned value
|
||||
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)
|
||||
ERROR: 0:118: 'depth_less' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:121: 'depth_unchanged' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array
|
||||
ERROR: 0:150: '=' : cannot convert from 'const float' to '3-element array of 4-component vector of float'
|
||||
ERROR: 0:152: 'constructor' : cannot convert parameter 1 from 'const 2-element array of 4-component vector of float' to '4-component vector of float'
|
||||
|
@ -1,30 +1,30 @@
|
||||
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:31: 'triangles' : unrecognized layout identifier
|
||||
ERROR: 0:31: 'invocations' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:33: 'lines' : unrecognized layout identifier
|
||||
ERROR: 0:35: 'triangle_strip' : unrecognized layout identifier
|
||||
ERROR: 0:35: 'max_vertices' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:36: 'max_vertices' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:37: 'triangle_strip' : unrecognized layout identifier
|
||||
ERROR: 0:41: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:43: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:45: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:46: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:47: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:50: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:55: 'stream' : there is no such layout identifier taking an assigned value
|
||||
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)
|
||||
ERROR: 0:35: 'triangle_strip' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:35: 'max_vertices' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:36: 'max_vertices' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:37: 'triangle_strip' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:41: 'stream' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:43: 'stream' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:45: 'stream' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:46: 'stream' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:47: 'stream' : there is no such layout identifier for this stage taking an assigned value
|
||||
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 taking an assigned value
|
||||
ERROR: 0:85: 'offset' : there is no such layout identifier for this stage taking an assigned value
|
||||
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 taking an assigned value
|
||||
ERROR: 0:89: 'offset' : there is no such layout identifier for this stage taking an assigned value
|
||||
WARNING: 0:89: '' : cannot set qualifier defaults when using a type and no identifier
|
||||
ERROR: 0:91: 'bar' : redefinition
|
||||
ERROR: 0:92: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:92: 'offset' : there is no such layout identifier for this stage taking an assigned value
|
||||
ERROR: 0:92: 'bar' : redefinition
|
||||
ERROR: 0:94: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:94: 'offset' : there is no such layout identifier for this stage taking an assigned value
|
||||
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
|
||||
@ -34,8 +34,8 @@ ERROR: 0:112: 'ColorIvn' : identifier not previously declared
|
||||
ERROR: 0:132: 'shared' : not supported in this stage: vertex
|
||||
ERROR: 0:134: '' : function does not return a value: funcA
|
||||
ERROR: 0:136: '' : function does not return a value: funcB
|
||||
ERROR: 0:137: 'rgba32f' : unrecognized layout identifier
|
||||
ERROR: 0:138: 'rgba32f' : unrecognized layout identifier
|
||||
ERROR: 0:137: 'rgba32f' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:138: 'rgba32f' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
|
||||
ERROR: 0:153: '' : function does not return a value: func3
|
||||
ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array
|
||||
ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array
|
||||
@ -276,7 +276,7 @@ ERROR: node is still EOpNull!
|
||||
0:? Linker Objects
|
||||
0:? 'Coords' (out block)
|
||||
0:? '__anon__0' (out block)
|
||||
0:? 'transforms' (layout(shared ) uniform 4-element array of block)
|
||||
0:? 'transforms' (layout(column_major shared ) uniform 4-element array of block)
|
||||
0:? 'normal' (layout(location=3 ) in 4-component vector of float)
|
||||
0:? 'colors' (layout(location=6 ) in 3-element array of 4-component vector of float)
|
||||
0:? 's' (layout(location=3 ) structure)
|
||||
@ -285,7 +285,7 @@ ERROR: node is still EOpNull!
|
||||
0:? 'var5' (smooth out 4-component vector of float)
|
||||
0:? '__anon__2' (out block)
|
||||
0:? 'var7' (smooth out 4-component vector of float)
|
||||
0:? '__anon__3' (layout(std140 ) uniform block)
|
||||
0:? '__anon__3' (layout(row_major std140 ) uniform block)
|
||||
0:? '__anon__4' (layout(column_major shared ) uniform block)
|
||||
0:? 's17' (layout(binding=3 ) uniform sampler2D)
|
||||
0:? 'a2' (layout(binding=2 ) uniform int)
|
||||
@ -303,8 +303,8 @@ ERROR: node is still EOpNull!
|
||||
0:? 'c' (in 4-component vector of float)
|
||||
0:? 'd' (in 4-component vector of float)
|
||||
0:? 'v' (smooth out 4-component vector of float)
|
||||
0:? '__anon__6' (layout(shared ) coherent uniform block)
|
||||
0:? '__anon__7' (layout(shared ) uniform block)
|
||||
0:? '__anon__6' (layout(row_major shared ) coherent uniform block)
|
||||
0:? '__anon__7' (layout(row_major shared ) uniform block)
|
||||
0:? 'shv' (shared 4-component vector of float)
|
||||
0:? 'img1' (uniform image2D)
|
||||
0:? 'img2' (coherent uniform image2D)
|
||||
|
18
Todo.txt
18
Todo.txt
@ -37,6 +37,9 @@ Link Validation
|
||||
- Non ES: matching redeclarations of interface blocks
|
||||
- Non ES: read or write to both gl_ClipVertex and gl_ClipDistance
|
||||
- Non ES: write to only one of gl_FragColor, gl_FragData, or user-declared
|
||||
- 1.50: at least one geometry shader says input primitive and at least one says output primitive...
|
||||
- 1.50: at least one geometry shader says max_vertices...
|
||||
- 1.50: match between all explicit input array sizes and input primitive
|
||||
- 4.3: Be clear that early_fragment_tests is only needed in one fragment-stage compilation unit.
|
||||
- 4.3: Be clear that implicit array sizing is only within a stage, not cross stage.
|
||||
- 4.4: overlapping transform/feedback offsets, offset/stride overflow checks, and stride matching
|
||||
@ -50,11 +53,12 @@ Shader Functionality to Implement/Finish
|
||||
+ implement non-inductive array accesses limitation detection
|
||||
ESSL 3.0
|
||||
- "const" compile-time constant propagation in the front-end has to be complete, for all built-in functions
|
||||
- add limitation around #define GL_FRAGMENT_PRECISION_HIGH 1 ?
|
||||
GLSL 1.2
|
||||
+ Handle multiple compilation units per stage
|
||||
+ Allow initializers on uniform declarations
|
||||
- signature matching takes type conversions into account, ambiguity is an error
|
||||
- all constructors to contain non-dereferenced arrays?
|
||||
- allow constructors to contain non-dereferenced arrays?
|
||||
GLSL 1.3
|
||||
. flat is for both user and predeclared built-in in/out variables
|
||||
GLSL 1.3 (Non-ES)
|
||||
@ -77,7 +81,7 @@ Shader Functionality to Implement/Finish
|
||||
+ ftransform(). Use invariant outputs instead.
|
||||
GLSL 1.5 (Non-ES)
|
||||
- Deprecated gl_MaxVaryingComponents
|
||||
- Add new minimum maximums for gl_MaxVertexOutputComponents, gl_MaxGeometryInputComponents, gl_MaxGeometryOutputComponents, and gl_MaxFragmentInputComponents,
|
||||
+ Add new minimum maximums for gl_MaxVertexOutputComponents, gl_MaxGeometryInputComponents, gl_MaxGeometryOutputComponents, and gl_MaxFragmentInputComponents,
|
||||
rather than relying on gl_MaxVaryingComponents. Also, corrected gl_MaxVaryingComponents to be 60 instead of 64.
|
||||
+ Added gl_PrimitiveID as an input to fragment shaders.
|
||||
- Added gl_FragCoord qualifiers origin_upper_left, and pixel_center_integer to modify the values returned by gl_FragCoord (and have no affect on any other aspect of the pipeline or language).
|
||||
@ -85,10 +89,10 @@ Shader Functionality to Implement/Finish
|
||||
- Added support for multi-sample textures through sampler2DMS and sampler2DMSArray support in texelFetch() and textureSize().
|
||||
+ Broadened interface blocks from just uniforms to in and out interfaces as well.
|
||||
+ Broaden array usage to include vertex shader inputs (vertex in).
|
||||
- Added geometry shaders. This includes targeting layers in FBO rendering.
|
||||
- geometry shader layouts: they must be declared, telling the system the primitive input and output types and maximum number of vertices.
|
||||
- Added geometry shader constants.
|
||||
- Broaden structure usage to include geometry inputs and geometry outputs.
|
||||
+ Added geometry shaders. This includes targeting layers in FBO rendering.
|
||||
+ geometry shader layouts: they must be declared, telling the system the primitive input and output types and maximum number of vertices.
|
||||
+ Added geometry shader constants.
|
||||
+ Broaden structure usage to include geometry inputs and geometry outputs.
|
||||
GLSL 4.0
|
||||
- tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization.
|
||||
- Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine.
|
||||
@ -203,7 +207,7 @@ Shader Functionality to Implement/Finish
|
||||
- Set both gl_MaxFragmentImageUniformsand gl_MaxCombinedImageUniforms to 8.
|
||||
- Clarify textureSize() for cube map arrays.
|
||||
- For layout qualifiers,
|
||||
- make negative output locations a compile-time error, and
|
||||
- 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.
|
||||
|
@ -176,14 +176,8 @@ protected:
|
||||
};
|
||||
|
||||
//
|
||||
// TPublicType (coming up after some dependent declarations)
|
||||
// is a workaround for a problem with the yacc stack, It can't have
|
||||
// types that it thinks have non-trivial constructors. It should
|
||||
// just be used while recognizing the grammar, not anything else. Pointers
|
||||
// could be used, but also trying to avoid lots of memory management overhead.
|
||||
//
|
||||
// Not as bad as it looks, there is no actual assumption that the fields
|
||||
// match up or are named the same or anything like that.
|
||||
// Following are a series of helper enums for managing layouts and qualifiers,
|
||||
// used for TPublicType, TType, others.
|
||||
//
|
||||
|
||||
enum TLayoutPacking {
|
||||
@ -191,14 +185,32 @@ enum TLayoutPacking {
|
||||
ElpShared, // default, but different than saying nothing
|
||||
ElpStd140,
|
||||
ElpStd430,
|
||||
ElpPacked // see bitfield width below
|
||||
ElpPacked
|
||||
// If expanding, see bitfield width below
|
||||
};
|
||||
|
||||
enum TLayoutMatrix {
|
||||
ElmNone,
|
||||
ElmRowMajor,
|
||||
ElmColumnMajor // default, but different than saying nothing
|
||||
}; // see bitfield width below
|
||||
// If expanding, see bitfield width below
|
||||
};
|
||||
|
||||
// Union of geometry shader and tessellation shader geometry types.
|
||||
// They don't go into TType, but rather have current state per shader or
|
||||
// active parser type (TPublicType).
|
||||
enum TLayoutGeometry {
|
||||
ElgNone,
|
||||
ElgPoints,
|
||||
ElgLines,
|
||||
ElgLinesAdjacency,
|
||||
ElgLineStrip,
|
||||
ElgTriangles,
|
||||
ElgTrianglesAdjacency,
|
||||
ElgTriangleStrip,
|
||||
ElgQuads,
|
||||
ElgIsolines,
|
||||
};
|
||||
|
||||
class TQualifier {
|
||||
public:
|
||||
@ -298,13 +310,15 @@ public:
|
||||
layoutPacking = ElpNone;
|
||||
layoutSlotLocation = layoutLocationEnd;
|
||||
layoutBinding = layoutBindingEnd;
|
||||
layoutStream = layoutStreamEnd;
|
||||
}
|
||||
bool hasLayout() const
|
||||
{
|
||||
return layoutMatrix != ElmNone ||
|
||||
layoutPacking != ElpNone ||
|
||||
hasLocation() ||
|
||||
hasBinding();
|
||||
hasBinding() ||
|
||||
hasStream();
|
||||
}
|
||||
TLayoutMatrix layoutMatrix : 3;
|
||||
TLayoutPacking layoutPacking : 4;
|
||||
@ -312,6 +326,8 @@ public:
|
||||
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 layoutSlotLocation != layoutLocationEnd;
|
||||
@ -320,6 +336,10 @@ public:
|
||||
{
|
||||
return layoutBinding != layoutBindingEnd;
|
||||
}
|
||||
bool hasStream() const
|
||||
{
|
||||
return layoutStream != layoutStreamEnd;
|
||||
}
|
||||
static const char* getLayoutPackingString(TLayoutPacking packing)
|
||||
{
|
||||
switch (packing) {
|
||||
@ -338,13 +358,50 @@ public:
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
static const char* getGeometryString(TLayoutGeometry geometry)
|
||||
{
|
||||
switch (geometry) {
|
||||
case ElgPoints: return "points";
|
||||
case ElgLines: return "lines";
|
||||
case ElgLinesAdjacency: return "lines_adjancency";
|
||||
case ElgLineStrip: return "line_strip";
|
||||
case ElgTriangles: return "triangles";
|
||||
case ElgTrianglesAdjacency: return "triangles_adjacency";
|
||||
case ElgTriangleStrip: return "triangle_strip";
|
||||
case ElgQuads: return "quads";
|
||||
case ElgIsolines: return "isolines";
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
static int mapGeometryToSize(TLayoutGeometry geometry)
|
||||
{
|
||||
switch (geometry) {
|
||||
case ElgPoints: return 1;
|
||||
case ElgLines: return 2;
|
||||
case ElgLinesAdjacency: return 4;
|
||||
case ElgTriangles: return 3;
|
||||
case ElgTrianglesAdjacency: return 6;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// TPublicType is just temporarily used while parsing and not quite the same
|
||||
// information kept per node in TType. Due to the bison stack, it can't have
|
||||
// types that it thinks have non-trivial constructors. It should
|
||||
// just be used while recognizing the grammar, not anything else.
|
||||
// Once enough is known about the situation, the proper information
|
||||
// moved into a TType, or the parse context, etc.
|
||||
//
|
||||
class TPublicType {
|
||||
public:
|
||||
TBasicType basicType;
|
||||
TSampler sampler;
|
||||
TQualifier qualifier;
|
||||
TLayoutGeometry geometry; // don't keep this in the qualifier; it's more a per shader than per type
|
||||
int invocations; // 0 means no declaration
|
||||
int maxVertices;
|
||||
int vectorSize : 4;
|
||||
int matrixCols : 4;
|
||||
int matrixRows : 4;
|
||||
@ -375,6 +432,9 @@ public:
|
||||
initType(loc);
|
||||
sampler.clear();
|
||||
initQualifiers(global);
|
||||
geometry = ElgNone;
|
||||
invocations = 0; // 0 means no declaration
|
||||
maxVertices = 0;
|
||||
}
|
||||
|
||||
void setVector(int s)
|
||||
@ -641,6 +701,8 @@ public:
|
||||
p += snprintf(p, end - p, "location=%d ", qualifier.layoutSlotLocation);
|
||||
if (qualifier.hasBinding())
|
||||
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
|
||||
if (qualifier.hasStream())
|
||||
p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream);
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
|
@ -77,19 +77,17 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
|
||||
defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
|
||||
|
||||
switch (language) {
|
||||
case EShLangVertex:
|
||||
defaultPrecision[EbtInt] = EpqHigh;
|
||||
defaultPrecision[EbtUint] = EpqHigh;
|
||||
defaultPrecision[EbtFloat] = EpqHigh;
|
||||
defaultPrecision[EbtSampler] = EpqLow;
|
||||
break;
|
||||
case EShLangFragment:
|
||||
defaultPrecision[EbtInt] = EpqMedium;
|
||||
defaultPrecision[EbtUint] = EpqMedium;
|
||||
defaultPrecision[EbtSampler] = EpqLow;
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixError, "unexpected es-profile stage");
|
||||
defaultPrecision[EbtInt] = EpqHigh;
|
||||
defaultPrecision[EbtUint] = EpqHigh;
|
||||
defaultPrecision[EbtFloat] = EpqHigh;
|
||||
defaultPrecision[EbtSampler] = EpqLow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +102,8 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
|
||||
globalInputDefaults.clear();
|
||||
|
||||
globalOutputDefaults.clear();
|
||||
if (language == EShLangGeometry)
|
||||
globalOutputDefaults.layoutStream = 0;
|
||||
}
|
||||
|
||||
//
|
||||
@ -1587,7 +1587,7 @@ void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQual
|
||||
dst.precision = src.precision;
|
||||
|
||||
// Layout qualifiers
|
||||
mergeLayoutQualifiers(loc, dst, src);
|
||||
mergeObjectLayoutQualifiers(loc, dst, src);
|
||||
|
||||
// individual qualifiers
|
||||
bool repeated = false;
|
||||
@ -2109,26 +2109,68 @@ void TParseContext::finalize()
|
||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
|
||||
{
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor))
|
||||
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
|
||||
publicType.qualifier.layoutMatrix = ElmColumnMajor;
|
||||
else if (id == TQualifier::getLayoutMatrixString(ElmRowMajor))
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
|
||||
publicType.qualifier.layoutMatrix = ElmRowMajor;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpPacked))
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutPackingString(ElpPacked)) {
|
||||
publicType.qualifier.layoutPacking = ElpPacked;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpShared))
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutPackingString(ElpShared)) {
|
||||
publicType.qualifier.layoutPacking = ElpShared;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd140))
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutPackingString(ElpStd140)) {
|
||||
publicType.qualifier.layoutPacking = ElpStd140;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "std430");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "std430");
|
||||
publicType.qualifier.layoutPacking = ElpStd430;
|
||||
} else if (id == "location")
|
||||
error(loc, "requires an integer assignment (e.g., location = 4)", "location", "");
|
||||
else if (id == "binding") {
|
||||
error(loc, "requires an integer assignment (e.g., binding = 4)", "binding", "");
|
||||
} else
|
||||
error(loc, "unrecognized layout identifier", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry || language == EShLangTessEvaluation) {
|
||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||
publicType.geometry = ElgTriangles;
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry) {
|
||||
if (id == TQualifier::getGeometryString(ElgPoints)) {
|
||||
publicType.geometry = ElgPoints;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLineStrip)) {
|
||||
publicType.geometry = ElgLineStrip;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLines)) {
|
||||
publicType.geometry = ElgLines;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
|
||||
publicType.geometry = ElgLinesAdjacency;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
|
||||
publicType.geometry = ElgTrianglesAdjacency;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
|
||||
publicType.geometry = ElgTriangleStrip;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// TODO: tessellation evaluation
|
||||
}
|
||||
}
|
||||
error(loc, "unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)", id.c_str(), "");
|
||||
}
|
||||
|
||||
// Put the id's layout qualifier value into the public type. This is before we know any
|
||||
@ -2143,22 +2185,54 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
||||
error(loc, "location is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutSlotLocation = value;
|
||||
} else if (id == "binding") {
|
||||
return;
|
||||
}
|
||||
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)
|
||||
error(loc, "binding is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutBinding = value;
|
||||
} else
|
||||
error(loc, "there is no such layout identifier taking an assigned value", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry) {
|
||||
if (id == "invocations") {
|
||||
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations");
|
||||
publicType.invocations = value;
|
||||
return;
|
||||
}
|
||||
if (id == "max_vertices") {
|
||||
publicType.maxVertices = value;
|
||||
return;
|
||||
}
|
||||
if (id == "stream") {
|
||||
publicType.qualifier.layoutStream = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
|
||||
|
||||
// TODO: semantics: error check: make sure locations are non-overlapping across the whole stage
|
||||
// TODO: semantics: error check: output arrays can only be indexed with a constant (es 300)
|
||||
}
|
||||
|
||||
//
|
||||
// Merge characteristics of the 'src' qualifier into the 'dst', at the TPublicType level,
|
||||
// which means for layout-qualifier information not kept per qualifier.
|
||||
//
|
||||
void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TPublicType& dst, const TPublicType& src)
|
||||
{
|
||||
if (src.geometry != ElgNone)
|
||||
dst.geometry = src.geometry;
|
||||
if (src.invocations != 0)
|
||||
dst.invocations = src.invocations;
|
||||
if (src.maxVertices != 0)
|
||||
dst.maxVertices = src.maxVertices;
|
||||
}
|
||||
|
||||
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone
|
||||
void TParseContext::mergeLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src)
|
||||
void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src)
|
||||
{
|
||||
if (src.layoutMatrix != ElmNone)
|
||||
dst.layoutMatrix = src.layoutMatrix;
|
||||
@ -2171,40 +2245,31 @@ void TParseContext::mergeLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const
|
||||
|
||||
if (src.hasBinding())
|
||||
dst.layoutBinding = src.layoutBinding;
|
||||
|
||||
if (src.hasStream())
|
||||
dst.layoutStream = src.layoutStream;
|
||||
}
|
||||
|
||||
// Do error layout error checking given a full variable/block declaration.
|
||||
void TParseContext::layoutCheck(TSourceLoc loc, const TSymbol& symbol)
|
||||
void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
|
||||
{
|
||||
const TType& type = symbol.getType();
|
||||
const TQualifier& qualifier = type.getQualifier();
|
||||
|
||||
// first, qualifier only error checking
|
||||
layoutQualifierCheck(loc, qualifier);
|
||||
|
||||
// now, error checking combining type and qualifier
|
||||
if (qualifier.hasLocation()) {
|
||||
switch (qualifier.storage) {
|
||||
case EvqVaryingIn:
|
||||
{
|
||||
const char* feature = "location qualifier on input";
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangVertex, feature);
|
||||
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
|
||||
if (language == EShLangVertex)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
|
||||
else
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
|
||||
if (type.getBasicType() == EbtBlock)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, 0 /* TODO ARB_enhanced_layouts*/, "location qualifier on input block");
|
||||
break;
|
||||
}
|
||||
case EvqVaryingOut:
|
||||
{
|
||||
const char* feature = "location qualifier on output";
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangFragment, feature);
|
||||
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
|
||||
if (language == EShLangFragment)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
|
||||
else
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
|
||||
if (type.getBasicType() == EbtBlock)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, 0 /* TODO ARB_enhanced_layouts*/, "location qualifier on output block");
|
||||
break;
|
||||
@ -2213,8 +2278,6 @@ void TParseContext::layoutCheck(TSourceLoc loc, const TSymbol& symbol)
|
||||
case EvqBuffer:
|
||||
{
|
||||
const char* feature = "location qualifier on uniform or buffer";
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature);
|
||||
if (symbol.getAsVariable() == 0)
|
||||
error(loc, "can only be used on variable declaration", feature, "");
|
||||
break;
|
||||
@ -2235,19 +2298,78 @@ void TParseContext::layoutCheck(TSourceLoc loc, const TSymbol& symbol)
|
||||
//
|
||||
// TODO: binding error checking against limits, arrays
|
||||
//
|
||||
if (qualifier.storage != EvqUniform && qualifier.storage != EvqBuffer)
|
||||
error(loc, "requires uniform or buffer storage qualifier", "binding", "");
|
||||
if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock)
|
||||
error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
|
||||
// TODO: atomic counter functionality: include in test above
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Non-Errors.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
if (qualifier.hasLocation()) {
|
||||
switch (qualifier.storage) {
|
||||
case EvqVaryingIn:
|
||||
{
|
||||
const char* feature = "location qualifier on input";
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangVertex, feature);
|
||||
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
|
||||
if (language == EShLangVertex)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
|
||||
else
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
|
||||
break;
|
||||
}
|
||||
case EvqVaryingOut:
|
||||
{
|
||||
const char* feature = "location qualifier on output";
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangFragment, feature);
|
||||
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
|
||||
if (language == EShLangFragment)
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
|
||||
else
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
|
||||
break;
|
||||
}
|
||||
case EvqUniform:
|
||||
case EvqBuffer:
|
||||
{
|
||||
const char* feature = "location qualifier on uniform or buffer";
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (qualifier.hasBinding()) {
|
||||
if (qualifier.storage != EvqUniform && qualifier.storage != EvqBuffer)
|
||||
error(loc, "requires uniform or buffer storage qualifier", "binding", "");
|
||||
}
|
||||
|
||||
if (qualifier.hasStream()) {
|
||||
if (qualifier.storage != EvqVaryingOut)
|
||||
error(loc, "can only be used on an output", "stream", "");
|
||||
}
|
||||
}
|
||||
|
||||
// For places that can't have shader-level layout qualifiers
|
||||
void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TPublicType& publicType)
|
||||
{
|
||||
const char* message = "can only apply to a standalone qualifier";
|
||||
|
||||
if (publicType.geometry != ElgNone)
|
||||
error(loc, message, TQualifier::getGeometryString(publicType.geometry), "");
|
||||
if (publicType.invocations > 0)
|
||||
error(loc, message, "invocations", "");
|
||||
if (publicType.maxVertices > 0)
|
||||
error(loc, message, "max_vertices", "");
|
||||
}
|
||||
|
||||
//
|
||||
// Look up a function name in the symbol table, and make sure it is a function.
|
||||
@ -2292,6 +2414,13 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
||||
if (! initializer)
|
||||
nonInitConstCheck(loc, identifier, type);
|
||||
|
||||
// Pick up defaults
|
||||
if (! type.getQualifier().hasStream() && language == EShLangGeometry && type.getQualifier().storage == EvqVaryingOut)
|
||||
type.getQualifier().layoutStream = globalOutputDefaults.layoutStream;
|
||||
|
||||
if (publicType.geometry != ElgNone)
|
||||
error(loc, "geometry primitive qualifier cannot be applied to a variable declaration", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
|
||||
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
||||
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||
TSymbol* symbol = redeclareBuiltin(loc, identifier, newDeclaration);
|
||||
@ -2331,9 +2460,9 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
||||
initNode = executeInitializer(loc, identifier, initializer, variable);
|
||||
}
|
||||
|
||||
// look for errors in layout qualifier use
|
||||
// look for errors/adjustments in layout qualifier use
|
||||
if (symbol)
|
||||
layoutCheck(loc, *symbol);
|
||||
layoutTypeCheck(loc, *symbol);
|
||||
|
||||
// see if it's a linker-level object to track
|
||||
if (symbol && newDeclaration && symbolTable.atGlobalLevel())
|
||||
@ -2732,7 +2861,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
if (profile == EEsProfile && arraySizes)
|
||||
arraySizeRequiredCheck(loc, arraySizes->getSize());
|
||||
|
||||
switch (currentBlockDefaults.storage) {
|
||||
switch (currentBlockQualifier.storage) {
|
||||
case EvqBuffer:
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "buffer block");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "buffer block");
|
||||
@ -2754,14 +2883,14 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
|
||||
arrayDimCheck(loc, arraySizes, 0);
|
||||
|
||||
// fix and check for member qualifiers and types that don't belong within a block
|
||||
// fix and check for member storage qualifiers and types that don't belong within a block
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||
TSourceLoc memberLoc = typeList[member].loc;
|
||||
pipeInOutFix(memberLoc, memberQualifier);
|
||||
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockDefaults.storage)
|
||||
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
|
||||
error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), "");
|
||||
if ((currentBlockDefaults.storage == EvqUniform && memberQualifier.isInterpolation()) || memberQualifier.isAuxiliary())
|
||||
if ((currentBlockQualifier.storage == EvqUniform && memberQualifier.isInterpolation()) || memberQualifier.isAuxiliary())
|
||||
error(memberLoc, "member of uniform block cannot have an auxiliary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), "");
|
||||
|
||||
TBasicType basicType = typeList[member].type->getBasicType();
|
||||
@ -2772,7 +2901,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
// Make default block qualification, and adjust the member qualifications
|
||||
|
||||
TQualifier defaultQualification;
|
||||
switch (currentBlockDefaults.storage) {
|
||||
switch (currentBlockQualifier.storage) {
|
||||
case EvqBuffer: defaultQualification = globalBufferDefaults; break;
|
||||
case EvqUniform: defaultQualification = globalUniformDefaults; break;
|
||||
case EvqVaryingIn: defaultQualification = globalInputDefaults; break;
|
||||
@ -2780,19 +2909,31 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
default: defaultQualification.clear(); break;
|
||||
}
|
||||
|
||||
mergeLayoutQualifiers(loc, defaultQualification, currentBlockDefaults);
|
||||
// fix and check for member layout qualifiers
|
||||
mergeObjectLayoutQualifiers(loc, defaultQualification, currentBlockQualifier);
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||
TQualifier memberQualification = defaultQualification;
|
||||
mergeQualifiers(loc, memberQualification, typeList[member].type->getQualifier(), false);
|
||||
typeList[member].type->getQualifier() = memberQualification;
|
||||
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||
TSourceLoc memberLoc = typeList[member].loc;
|
||||
if (memberQualifier.hasStream()) {
|
||||
if (defaultQualification.layoutStream != memberQualifier.layoutStream)
|
||||
error(memberLoc, "member cannot contradict block", "stream", "");
|
||||
}
|
||||
TQualifier newMemberQualification = defaultQualification;
|
||||
mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
|
||||
memberQualifier = newMemberQualification;
|
||||
}
|
||||
|
||||
//
|
||||
// Build and add the interface block as a new type named blockName
|
||||
//
|
||||
|
||||
TType blockType(&typeList, *blockName, currentBlockDefaults);
|
||||
// reverse merge, so that currentBlockQualifier now has all layout information
|
||||
// (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
|
||||
mergeObjectLayoutQualifiers(loc, currentBlockQualifier, defaultQualification);
|
||||
|
||||
TType blockType(&typeList, *blockName, currentBlockQualifier);
|
||||
if (arraySizes)
|
||||
blockType.setArraySizes(arraySizes);
|
||||
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
|
||||
|
||||
//
|
||||
// Don't make a user-defined type out of block name; that will cause an error
|
||||
@ -2834,7 +2975,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
}
|
||||
|
||||
// Check for general layout qualifier errors
|
||||
layoutCheck(loc, variable);
|
||||
layoutTypeCheck(loc, variable);
|
||||
|
||||
// Save it in the AST for linker use.
|
||||
intermediate.addSymbolLinkageNode(linkage, variable);
|
||||
@ -2879,55 +3020,76 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
||||
}
|
||||
|
||||
//
|
||||
// Update qualifier defaults for all forms of declarations, which
|
||||
// must error check for their form before calling here.
|
||||
// Updating default qualifier for the case of a declaration with just a qualifier,
|
||||
// no type, block, or identifier.
|
||||
//
|
||||
void TParseContext::updateQualifierDefaults(TQualifier qualifier)
|
||||
void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
|
||||
{
|
||||
switch (qualifier.storage) {
|
||||
case EvqBuffer:
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
|
||||
break;
|
||||
case EvqUniform:
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
if (qualifier.hasLocation())
|
||||
globalInputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
|
||||
break;
|
||||
case EvqVaryingOut:
|
||||
if (qualifier.hasLocation())
|
||||
globalOutputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
|
||||
break;
|
||||
default:
|
||||
// error handling should be done by callers of this function
|
||||
break;
|
||||
if (publicType.maxVertices) {
|
||||
if (! intermediate.setMaxVertices(publicType.maxVertices))
|
||||
error(loc, "cannot change previously set layout value", "max_vertices", "");
|
||||
}
|
||||
if (publicType.invocations) {
|
||||
if (! intermediate.setInvocations(publicType.invocations))
|
||||
error(loc, "cannot change previously set layout value", "invocations", "");
|
||||
}
|
||||
if (publicType.geometry != ElgNone) {
|
||||
if (publicType.qualifier.storage == EvqVaryingIn) {
|
||||
switch (publicType.geometry) {
|
||||
case ElgPoints:
|
||||
case ElgLines:
|
||||
case ElgLinesAdjacency:
|
||||
case ElgTriangles:
|
||||
case ElgTrianglesAdjacency:
|
||||
if (! intermediate.setInputPrimitive(publicType.geometry))
|
||||
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
break;
|
||||
default:
|
||||
error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
}
|
||||
} else if (publicType.qualifier.storage == EvqVaryingOut) {
|
||||
switch (publicType.geometry) {
|
||||
case ElgPoints:
|
||||
case ElgLineStrip:
|
||||
case ElgTriangleStrip:
|
||||
if (! intermediate.setOutputPrimitive(publicType.geometry))
|
||||
error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
break;
|
||||
default:
|
||||
error(loc, "does not only apply to output", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
}
|
||||
} else
|
||||
error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update defaults for qualifiers. This is called directly for the case
|
||||
// of a declaration with just a qualifier.
|
||||
//
|
||||
void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier)
|
||||
{
|
||||
const TQualifier& qualifier = publicType.qualifier;
|
||||
|
||||
if (qualifier.isAuxiliary() ||
|
||||
qualifier.isMemory() ||
|
||||
qualifier.isInterpolation() ||
|
||||
qualifier.precision != EpqNone)
|
||||
error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "", "");
|
||||
|
||||
layoutQualifierCheck(loc, qualifier);
|
||||
|
||||
switch (qualifier.storage) {
|
||||
case EvqUniform:
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
|
||||
break;
|
||||
case EvqBuffer:
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
break;
|
||||
case EvqVaryingOut:
|
||||
if (qualifier.hasStream())
|
||||
globalOutputDefaults.layoutStream = qualifier.layoutStream;
|
||||
break;
|
||||
default:
|
||||
error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
|
||||
@ -2938,18 +3100,14 @@ void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier
|
||||
error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
|
||||
if (qualifier.hasLocation())
|
||||
error(loc, "cannot declare a default, use a full declaration", "location", "");
|
||||
|
||||
updateQualifierDefaults(qualifier);
|
||||
}
|
||||
|
||||
//
|
||||
// Update defaults for qualifiers when declared with a type, and optionally an identifier.
|
||||
// (But, not the case of just a qualifier; only when a type is present.)
|
||||
// (But, not the case of just a qualifier.)
|
||||
//
|
||||
void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, const TString* id)
|
||||
void TParseContext::updateTypedDefaults(TSourceLoc loc, const TQualifier& qualifier, const TString* id)
|
||||
{
|
||||
bool cantHaveId = false;
|
||||
|
||||
if (! id) {
|
||||
if (qualifier.hasLayout())
|
||||
warn(loc, "cannot set qualifier defaults when using a type and no identifier", "", "");
|
||||
@ -2966,8 +3124,12 @@ void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, co
|
||||
error(loc, "cannot specify packing on a variable declaration", id->c_str(), "");
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
if (qualifier.hasLocation())
|
||||
globalInputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
|
||||
break;
|
||||
case EvqVaryingOut:
|
||||
if (qualifier.hasLocation())
|
||||
globalOutputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
|
||||
break;
|
||||
default:
|
||||
if (qualifier.layoutMatrix != ElmNone ||
|
||||
@ -2976,11 +3138,6 @@ void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, co
|
||||
else if (qualifier.hasLocation())
|
||||
error(loc, "location qualifiers only appy to uniform, buffer, in, or out storage qualifiers", id->c_str(), "");
|
||||
}
|
||||
|
||||
if (cantHaveId)
|
||||
error(loc, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), "");
|
||||
|
||||
updateQualifierDefaults(qualifier);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -126,8 +126,11 @@ public:
|
||||
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
|
||||
void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
|
||||
void layoutCheck(TSourceLoc, const TSymbol&);
|
||||
void mergeShaderLayoutQualifiers(TSourceLoc, TPublicType& dst, const TPublicType& src);
|
||||
void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
|
||||
void layoutTypeCheck(TSourceLoc, const TSymbol&);
|
||||
void layoutQualifierCheck(TSourceLoc, const TQualifier&);
|
||||
void checkNoShaderLayouts(TSourceLoc, const TPublicType&);
|
||||
|
||||
const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0);
|
||||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
@ -137,9 +140,8 @@ public:
|
||||
void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
|
||||
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
|
||||
void updateQualifierDefaults(TQualifier);
|
||||
void updateQualifierDefaults(TSourceLoc, TQualifier);
|
||||
void updateTypedDefaults(TSourceLoc, TQualifier, const TString* id);
|
||||
void updateStandaloneQualifierDefaults(TSourceLoc, const TPublicType&);
|
||||
void updateTypedDefaults(TSourceLoc, const TQualifier&, const TString* id);
|
||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||
TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
|
||||
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
|
||||
@ -202,7 +204,7 @@ public:
|
||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||
bool functionReturnsValue; // true if a non-void function has a return
|
||||
const TString* blockName;
|
||||
TQualifier currentBlockDefaults;
|
||||
TQualifier currentBlockQualifier;
|
||||
TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST
|
||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||
TSourceLoc currentLoc;
|
||||
@ -214,7 +216,7 @@ protected:
|
||||
TPpContext* ppContext;
|
||||
int numErrors; // number of compile-time errors encountered
|
||||
bool parsingBuiltins; // true if parsing built-in symbols/functions
|
||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what it's current behavior is set to
|
||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
||||
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
|
||||
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
||||
bool afterEOF;
|
||||
|
@ -159,7 +159,8 @@ const char* TParseContext::getPreamble()
|
||||
return
|
||||
"#define GL_ES 1\n";
|
||||
} else {
|
||||
return
|
||||
return
|
||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||
"#define GL_ARB_texture_rectangle 1\n"
|
||||
"#define GL_ARB_shading_language_420pack 1\n"
|
||||
"#define GL_ARB_texture_gather 1\n"
|
||||
|
@ -774,16 +774,18 @@ declaration
|
||||
}
|
||||
| type_qualifier SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.updateQualifierDefaults($1.loc, $1.qualifier);
|
||||
parseContext.updateStandaloneQualifierDefaults($1.loc, $1);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER identifier_list SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
$3->push_back($2.string);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);
|
||||
$$ = 0;
|
||||
@ -795,7 +797,8 @@ block_structure
|
||||
--parseContext.structNestingLevel;
|
||||
parseContext.blockName = $2.string;
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.currentBlockDefaults = $1.qualifier;
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.currentBlockQualifier = $1.qualifier;
|
||||
$$.loc = $1.loc;
|
||||
$$.typeList = $5;
|
||||
}
|
||||
@ -915,7 +918,8 @@ parameter_declaration
|
||||
$$ = $2;
|
||||
if ($1.qualifier.precision != EpqNone)
|
||||
$$.param.type->getQualifier().precision = $1.qualifier.precision;
|
||||
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
|
||||
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
|
||||
}
|
||||
@ -932,7 +936,8 @@ parameter_declaration
|
||||
$$ = $2;
|
||||
if ($1.qualifier.precision != EpqNone)
|
||||
$$.param.type->getQualifier().precision = $1.qualifier.precision;
|
||||
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
|
||||
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
|
||||
}
|
||||
@ -1033,6 +1038,7 @@ fully_specified_type
|
||||
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier))
|
||||
$2.arraySizes = 0;
|
||||
|
||||
parseContext.checkNoShaderLayouts($2.loc, $1);
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
parseContext.precisionQualifierCheck($2.loc, $2);
|
||||
|
||||
@ -1089,7 +1095,8 @@ layout_qualifier_id_list
|
||||
}
|
||||
| layout_qualifier_id_list COMMA layout_qualifier_id {
|
||||
$$ = $1;
|
||||
parseContext.mergeLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);
|
||||
parseContext.mergeShaderLayoutQualifiers($2.loc, $$, $3);
|
||||
parseContext.mergeObjectLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);
|
||||
}
|
||||
|
||||
layout_qualifier_id
|
||||
@ -1127,6 +1134,7 @@ type_qualifier
|
||||
if ($$.basicType == EbtVoid)
|
||||
$$.basicType = $2.basicType;
|
||||
|
||||
parseContext.mergeShaderLayoutQualifiers($$.loc, $$, $2);
|
||||
parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false);
|
||||
}
|
||||
;
|
||||
@ -2043,6 +2051,7 @@ struct_declaration
|
||||
|
||||
$$ = $3;
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
parseContext.precisionQualifierCheck($2.loc, $2);
|
||||
|
@ -579,6 +579,13 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it
|
||||
//
|
||||
void TIntermediate::outputTree(TInfoSink& infoSink)
|
||||
{
|
||||
if (language == EShLangGeometry) {
|
||||
infoSink.debug << "invocations = " << invocations << "\n";
|
||||
infoSink.debug << "max_vertices = " << maxVertices << "\n";
|
||||
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
|
||||
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
||||
}
|
||||
|
||||
if (treeRoot == 0)
|
||||
return;
|
||||
|
||||
|
@ -56,7 +56,8 @@ class TSymbol;
|
||||
//
|
||||
class TIntermediate {
|
||||
public:
|
||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0) { }
|
||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0),
|
||||
invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone) { }
|
||||
|
||||
void setVersion(int v) { version = v; }
|
||||
int getVersion() const { return version; }
|
||||
@ -99,6 +100,36 @@ public:
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
||||
|
||||
bool setInvocations(int i)
|
||||
{
|
||||
if (invocations > 0)
|
||||
return false;
|
||||
invocations = i;
|
||||
return true;
|
||||
}
|
||||
bool setMaxVertices(int m)
|
||||
{
|
||||
if (maxVertices > 0)
|
||||
return maxVertices == m;
|
||||
maxVertices = m;
|
||||
return true;
|
||||
}
|
||||
bool setInputPrimitive(TLayoutGeometry p)
|
||||
{
|
||||
if (inputPrimitive != ElgNone)
|
||||
return inputPrimitive == p;
|
||||
inputPrimitive = p;
|
||||
return true;
|
||||
}
|
||||
TLayoutGeometry getInputPrimitive() { return inputPrimitive; }
|
||||
bool setOutputPrimitive(TLayoutGeometry p)
|
||||
{
|
||||
if (outputPrimitive != ElgNone)
|
||||
return outputPrimitive == p;
|
||||
outputPrimitive = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||
void merge(TInfoSink&, TIntermediate&);
|
||||
void errorCheck(TInfoSink&);
|
||||
@ -122,6 +153,10 @@ protected:
|
||||
int version;
|
||||
int numMains;
|
||||
int numErrors;
|
||||
int invocations;
|
||||
int maxVertices;
|
||||
TLayoutGeometry inputPrimitive;
|
||||
TLayoutGeometry outputPrimitive;
|
||||
|
||||
// for detecting recursion: pair is <caller, callee>
|
||||
struct TCall {
|
||||
|
Loading…
Reference in New Issue
Block a user