diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 8d3f5cac8e58d25be8affde27f14a7c94c68fd4c..b16f139a9d01db5b290cfc81bb2648ed274f0d8d 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -155,6 +155,7 @@ const char* DefaultConfig = "MaxFragmentInputComponents 128\n" "MaxImageUnits 8\n" "MaxCombinedImageUnitsAndFragmentOutputs 8\n" + "MaxCombinedShaderOutputResources 8\n" "MaxImageSamples 0\n" "MaxVertexImageUniforms 0\n" "MaxTessControlImageUniforms 0\n" @@ -316,6 +317,8 @@ void ProcessConfigFile() Resources.maxImageUnits = value; else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0) Resources.maxCombinedImageUnitsAndFragmentOutputs = value; + else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0) + Resources.maxCombinedShaderOutputResources = value; else if (strcmp(token, "MaxImageSamples") == 0) Resources.maxImageSamples = value; else if (strcmp(token, "MaxVertexImageUniforms") == 0) diff --git a/Test/130.frag b/Test/130.frag index a5903928042dfd632221e70ed98b548893e68c4d..3e394110b5516f4ac1a29095dfabff25bf242bb8 100644 --- a/Test/130.frag +++ b/Test/130.frag @@ -148,4 +148,22 @@ in float gl_FogFragCoord; #extension GL_ARB_separate_shader_objects : enable in float gl_FogFragCoord; -in int gl_FogFragCoord; +in int gl_FogFragCoord; // ERROR + +layout(early_fragment_tests) in; // ERROR +layout(r32i) uniform iimage2D iimg2Dbad; // ERROR + +#extension GL_ARB_shader_image_load_store : enable + +layout(early_fragment_tests) in; + +layout(r32i) uniform iimage2D iimg2D; + +void qux2() +{ + int i; + imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i); + ivec4 pos = imageLoad(iimg2D, ivec2(i,i)); +} + +layout(early_fragment_tests) out; // ERROR diff --git a/Test/150.geom b/Test/150.geom index 2edf95076c74ce6c7a53ffdda966815d07377cc1..8f13a60c25d06ee9f6f9b21c4c263387f30eeb38 100644 --- a/Test/150.geom +++ b/Test/150.geom @@ -83,7 +83,7 @@ out outbn2 { } outbi; layout(lines) out; // ERROR, not on output -layout(lines_adjancency) in; +layout(lines_adjacency) in; layout(triangles) in; // ERROR, can't change it layout(triangles_adjacency) in; // ERROR, can't change it layout(invocations = 4) in; // ERROR, not until 4.0 diff --git a/Test/420.vert b/Test/420.vert index de3534f2dbad7a1be82cdcc46e676af9be498a73..93a9874fa2d48f3b0859b6a5f8df7e56174e9072 100644 --- a/Test/420.vert +++ b/Test/420.vert @@ -99,3 +99,46 @@ void bar23444() const int comma0 = (2, 3); // ERROR int comma1[(2, 3)]; // ERROR + +layout(r32i) uniform iimage2D iimg2D; +layout(rgba32i) uniform iimage2D iimg2Drgba; +layout(rgba32f) uniform image2D img2Drgba; +layout(r32ui) uniform uimage2D uimg2D; +uniform image2DMS img2DMS; // ERROR image variables not declared writeonly must have format layout qualifier +uniform writeonly image2DMS img2DMSWO; +void qux() +{ + int i = aoeu; + imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i); + imageAtomicAdd(uimg2D, ivec2(i,i), uint(i)); + imageAtomicMin(iimg2Drgba, ivec2(i,i), i); // ERROR iimg2Drgba does not have r32i layout + imageAtomicMax(img2Drgba, ivec2(i,i), i); // ERROR img2Drgba is not integer image + ivec4 pos = imageLoad(iimg2D, ivec2(i,i)); + vec4 col = imageLoad(img2DMS, ivec2(i,i), i); + imageStore(img2DMSWO, ivec2(i,i), i, vec4(0)); + imageLoad(img2DMSWO, ivec2(i,i), i); // ERROR, drops writeonly +} + +volatile float vol; // ERROR, not an image +readonly int vol2; // ERROR, not an image + +void passr(coherent readonly iimage2D image) +{ +} + +layout(r32i) coherent readonly uniform iimage2D qualim1; +layout(r32i) coherent restrict readonly uniform iimage2D qualim2; + +void passrc() +{ + passr(qualim1); + passr(qualim2); // ERROR, drops restrict + passr(iimg2D); +} + +layout(rg8i) uniform uimage2D i1bad; // ERROR, type mismatch +layout(rgba32i) uniform image2D i2bad; // ERROR, type mismatch +layout(rgba32f) uniform uimage2D i3bad; // ERROR, type mismatch +layout(r8_snorm) uniform iimage2D i4bad; // ERROR, type mismatch +layout(rgba32ui) uniform iimage2D i5bad; // ERROR, type mismatch +layout(r8ui) uniform iimage2D i6bad; // ERROR, type mismatch diff --git a/Test/baseResults/130.frag.out b/Test/baseResults/130.frag.out index 6b1dca516f21b3da48e54375a2d1c32efe7dc13a..b2d2ed24b0086255eaf126a8460e388c0404cda4 100644 --- a/Test/baseResults/130.frag.out +++ b/Test/baseResults/130.frag.out @@ -25,16 +25,22 @@ ERROR: 0:143: 'length' : method does not accept any arguments ERROR: 0:146: 'gl_FogFragCoord' : identifiers starting with "gl_" are reserved ERROR: 0:151: 'int' : must be qualified as flat in ERROR: 0:151: 'redeclaration' : cannot change the type of gl_FogFragCoord -ERROR: 24 compilation errors. No code generated. +ERROR: 0:153: 'early_fragment_tests' : not supported for this version or the enabled extensions +ERROR: 0:154: 'image load store' : not supported for this version or the enabled extensions +ERROR: 0:154: 'iimage2D' : Reserved word. +ERROR: 0:169: 'early_fragment_tests' : can only apply to 'in' +ERROR: 28 compilation errors. No code generated. Shader version: 130 Requested GL_ARB_gpu_shader5 Requested GL_ARB_separate_shader_objects +Requested GL_ARB_shader_image_load_store Requested GL_ARB_shading_language_420pack Requested GL_ARB_texture_cube_map_array Requested GL_ARB_texture_gather Requested GL_ARB_texture_rectangle +using early_fragment_tests ERROR: node is still EOpNull! 0:16 Function Definition: main( (void) 0:16 Function Parameters: @@ -348,6 +354,24 @@ ERROR: node is still EOpNull! 0:141 0.000000 0:143 Constant: 0:143 1 (const int) +0:162 Function Definition: qux2( (void) +0:162 Function Parameters: +0:? Sequence +0:165 Function Call: imageAtomicCompSwap(iI21;vi2;i1;i1; (int) +0:165 'iimg2D' (layout(r32i ) uniform iimage2D) +0:165 Construct ivec2 (2-component vector of int) +0:165 'i' (int) +0:165 'i' (int) +0:165 'i' (int) +0:165 'i' (int) +0:166 Sequence +0:166 move second child to first child (4-component vector of int) +0:166 'pos' (4-component vector of int) +0:166 Function Call: imageLoad(iI21;vi2; (4-component vector of int) +0:166 'iimg2D' (layout(r32i ) uniform iimage2D) +0:166 Construct ivec2 (2-component vector of int) +0:166 'i' (int) +0:166 'i' (int) 0:? Linker Objects 0:? 'a' (3-component vector of float) 0:? 'b' (float) @@ -377,6 +401,8 @@ ERROR: node is still EOpNull! 0:? 'instanceName' (layout(binding=0 column_major shared ) uniform block{layout(column_major shared ) uniform int a}) 0:? 'bounds' (layout(binding=0 ) uniform sampler2D) 0:? 'gl_FogFragCoord' (smooth in float) +0:? 'iimg2Dbad' (layout(r32i ) uniform iimage2D) +0:? 'iimg2D' (layout(r32i ) uniform iimage2D) Linked fragment stage: @@ -385,10 +411,12 @@ Linked fragment stage: Shader version: 130 Requested GL_ARB_gpu_shader5 Requested GL_ARB_separate_shader_objects +Requested GL_ARB_shader_image_load_store Requested GL_ARB_shading_language_420pack Requested GL_ARB_texture_cube_map_array Requested GL_ARB_texture_gather Requested GL_ARB_texture_rectangle +using early_fragment_tests ERROR: node is still EOpNull! 0:16 Function Definition: main( (void) 0:16 Function Parameters: @@ -702,6 +730,24 @@ ERROR: node is still EOpNull! 0:141 0.000000 0:143 Constant: 0:143 1 (const int) +0:162 Function Definition: qux2( (void) +0:162 Function Parameters: +0:? Sequence +0:165 Function Call: imageAtomicCompSwap(iI21;vi2;i1;i1; (int) +0:165 'iimg2D' (layout(r32i ) uniform iimage2D) +0:165 Construct ivec2 (2-component vector of int) +0:165 'i' (int) +0:165 'i' (int) +0:165 'i' (int) +0:165 'i' (int) +0:166 Sequence +0:166 move second child to first child (4-component vector of int) +0:166 'pos' (4-component vector of int) +0:166 Function Call: imageLoad(iI21;vi2; (4-component vector of int) +0:166 'iimg2D' (layout(r32i ) uniform iimage2D) +0:166 Construct ivec2 (2-component vector of int) +0:166 'i' (int) +0:166 'i' (int) 0:? Linker Objects 0:? 'a' (3-component vector of float) 0:? 'b' (float) @@ -731,4 +777,6 @@ ERROR: node is still EOpNull! 0:? 'instanceName' (layout(binding=0 column_major shared ) uniform block{layout(column_major shared ) uniform int a}) 0:? 'bounds' (layout(binding=0 ) uniform sampler2D) 0:? 'gl_FogFragCoord' (smooth in float) +0:? 'iimg2Dbad' (layout(r32i ) uniform iimage2D) +0:? 'iimg2D' (layout(r32i ) uniform iimage2D) diff --git a/Test/baseResults/150.geom.out b/Test/baseResults/150.geom.out index 1b0961f318e153e615a721c570df9161f53ceb81..8d0445700f586f0dc340d5865d271a68a9a536d8 100644 --- a/Test/baseResults/150.geom.out +++ b/Test/baseResults/150.geom.out @@ -37,7 +37,7 @@ ERROR: 32 compilation errors. No code generated. Shader version: 150 invocations = 4 max_vertices = 200 -input primitive = lines_adjancency +input primitive = lines_adjacency output primitive = triangle_strip ERROR: node is still EOpNull! 0:25 Function Definition: main( (void) @@ -156,7 +156,7 @@ Linked geometry stage: Shader version: 150 invocations = 4 max_vertices = 200 -input primitive = lines_adjancency +input primitive = lines_adjacency output primitive = triangle_strip ERROR: node is still EOpNull! 0:25 Function Definition: main( (void) diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out index f60022395f900c7a4fe9f4472842ab0629bc7a17..5db3e497cb41e8d3b949ae20618ee2b7c808a03b 100644 --- a/Test/baseResults/150.tesc.out +++ b/Test/baseResults/150.tesc.out @@ -215,9 +215,9 @@ ERROR: node is still EOpNull! 400.tesc Warning, version 400 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) -ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) -ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) +ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader ERROR: 0:39: 'vertices' : can only apply to 'out' ERROR: 0:40: 'vertices' : cannot change previously set layout value diff --git a/Test/baseResults/300layout.vert.out b/Test/baseResults/300layout.vert.out index 52de07b8e40d6a188544acab2f98621bd825f6d3..f954252354293b2de28be684b272580218300244 100644 --- a/Test/baseResults/300layout.vert.out +++ b/Test/baseResults/300layout.vert.out @@ -15,9 +15,10 @@ 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:50: '' : memory qualifiers can only be used on image types ERROR: 0:54: 'layout' : cannot specify packing on a variable declaration ERROR: 0:57: 'location' : overlapping use of location 40 -ERROR: 18 compilation errors. No code generated. +ERROR: 19 compilation errors. No code generated. Shader version: 300 diff --git a/Test/baseResults/400.tesc.out b/Test/baseResults/400.tesc.out index 8dab6f6c6b036a5ad10378e9209ffd6ab9465981..79baf2e8e444a3db8e018eacfdceb1cdaa8dcaf6 100644 --- a/Test/baseResults/400.tesc.out +++ b/Test/baseResults/400.tesc.out @@ -1,8 +1,8 @@ 400.tesc Warning, version 400 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) -ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) -ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) +ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader ERROR: 0:39: 'vertices' : can only apply to 'out' ERROR: 0:40: 'vertices' : cannot change previously set layout value diff --git a/Test/baseResults/420.vert.out b/Test/baseResults/420.vert.out index 0041a242bd0b6437317629c6bef8da43836b8e0f..94f849b8b9c13591693e909787135000e717992d 100644 --- a/Test/baseResults/420.vert.out +++ b/Test/baseResults/420.vert.out @@ -34,7 +34,20 @@ ERROR: 0:86: 'patch' : not supported in this stage: vertex ERROR: 0:100: '=' : global const initializers must be constant 'const int' ERROR: 0:101: '' : constant expression required ERROR: 0:101: '' : array size must be a constant integer expression -ERROR: 33 compilation errors. No code generated. +ERROR: 0:107: '' : image variables not declared 'writeonly' must have a format layout qualifier +ERROR: 0:114: 'imageAtomicMin' : only supported on image with format r32i or r32ui +ERROR: 0:115: 'imageAtomicMax' : no matching overloaded function found +ERROR: 0:119: 'writeonly' : argument cannot drop memory qualifier when passed to formal parameter +ERROR: 0:122: '' : memory qualifiers can only be used on image types +ERROR: 0:123: '' : memory qualifiers can only be used on image types +ERROR: 0:135: 'restrict' : argument cannot drop memory qualifier when passed to formal parameter +ERROR: 0:139: 'rg8i' : does not apply to unsigned integer images +ERROR: 0:140: 'rgba32i' : does not apply to floating point images +ERROR: 0:141: 'rgba32f' : does not apply to unsigned integer images +ERROR: 0:142: 'r8_snorm' : does not apply to signed integer images +ERROR: 0:143: 'rgba32ui' : does not apply to signed integer images +ERROR: 0:144: 'r8ui' : does not apply to signed integer images +ERROR: 46 compilation errors. No code generated. Shader version: 420 @@ -73,7 +86,7 @@ ERROR: node is still EOpNull! 0:42 No loop body 0:50 Function Definition: bar(vf4; (void) 0:50 Function Parameters: -0:50 'v' (in 4-component vector of float) +0:50 'v' (volatile in 4-component vector of float) 0:? Sequence 0:53 's' (int) 0:54 's' (int) @@ -146,6 +159,84 @@ ERROR: node is still EOpNull! 0:97 'a' (int) 0:97 Constant: 0:97 -1 (const int) +0:109 Function Definition: qux( (void) +0:109 Function Parameters: +0:111 Sequence +0:111 Sequence +0:111 move second child to first child (int) +0:111 'i' (int) +0:111 aoeu: direct index for structure (layout(column_major shared ) uniform int) +0:111 'anon@0' (layout(binding=7 column_major shared ) uniform block{layout(column_major shared ) uniform int aoeu}) +0:111 Constant: +0:111 0 (const uint) +0:112 Function Call: imageAtomicCompSwap(iI21;vi2;i1;i1; (int) +0:112 'iimg2D' (layout(r32i ) uniform iimage2D) +0:112 Construct ivec2 (2-component vector of int) +0:112 'i' (int) +0:112 'i' (int) +0:112 'i' (int) +0:112 'i' (int) +0:113 Function Call: imageAtomicAdd(uI21;vi2;u1; (uint) +0:113 'uimg2D' (layout(r32ui ) uniform uimage2D) +0:113 Construct ivec2 (2-component vector of int) +0:113 'i' (int) +0:113 'i' (int) +0:113 Convert int to uint (uint) +0:113 'i' (int) +0:114 Function Call: imageAtomicMin(iI21;vi2;i1; (int) +0:114 'iimg2Drgba' (layout(rgba32i ) uniform iimage2D) +0:114 Construct ivec2 (2-component vector of int) +0:114 'i' (int) +0:114 'i' (int) +0:114 'i' (int) +0:115 Constant: +0:115 0.000000 +0:116 Sequence +0:116 move second child to first child (4-component vector of int) +0:116 'pos' (4-component vector of int) +0:116 Function Call: imageLoad(iI21;vi2; (4-component vector of int) +0:116 'iimg2D' (layout(r32i ) uniform iimage2D) +0:116 Construct ivec2 (2-component vector of int) +0:116 'i' (int) +0:116 'i' (int) +0:117 Sequence +0:117 move second child to first child (4-component vector of float) +0:117 'col' (4-component vector of float) +0:117 Function Call: imageLoad(I21;vi2;i1; (4-component vector of float) +0:117 'img2DMS' (uniform image2DMS) +0:117 Construct ivec2 (2-component vector of int) +0:117 'i' (int) +0:117 'i' (int) +0:117 'i' (int) +0:118 Function Call: imageStore(I21;vi2;i1;vf4; (void) +0:118 'img2DMSWO' (writeonly uniform image2DMS) +0:118 Construct ivec2 (2-component vector of int) +0:118 'i' (int) +0:118 'i' (int) +0:118 'i' (int) +0:118 Constant: +0:118 0.000000 +0:118 0.000000 +0:118 0.000000 +0:118 0.000000 +0:119 Function Call: imageLoad(I21;vi2;i1; (4-component vector of float) +0:119 'img2DMSWO' (writeonly uniform image2DMS) +0:119 Construct ivec2 (2-component vector of int) +0:119 'i' (int) +0:119 'i' (int) +0:119 'i' (int) +0:125 Function Definition: passr(iI21; (void) +0:125 Function Parameters: +0:125 'image' (coherent readonly in iimage2D) +0:132 Function Definition: passrc( (void) +0:132 Function Parameters: +0:134 Sequence +0:134 Function Call: passr(iI21; (void) +0:134 'qualim1' (layout(r32i ) coherent readonly uniform iimage2D) +0:135 Function Call: passr(iI21; (void) +0:135 'qualim2' (layout(r32i ) coherent restrict readonly uniform iimage2D) +0:136 Function Call: passr(iI21; (void) +0:136 'iimg2D' (layout(r32i ) uniform iimage2D) 0:? Linker Objects 0:? 'v2' (smooth out 2-component vector of float) 0:? 'bad' (in 10-element array of 4-component vector of float) @@ -180,6 +271,22 @@ ERROR: node is still EOpNull! 0:? 'patchOut' (smooth patch out 4-component vector of float) 0:? 'comma0' (int) 0:? 'comma1' (1-element array of int) +0:? 'iimg2D' (layout(r32i ) uniform iimage2D) +0:? 'iimg2Drgba' (layout(rgba32i ) uniform iimage2D) +0:? 'img2Drgba' (layout(rgba32f ) uniform image2D) +0:? 'uimg2D' (layout(r32ui ) uniform uimage2D) +0:? 'img2DMS' (uniform image2DMS) +0:? 'img2DMSWO' (writeonly uniform image2DMS) +0:? 'vol' (volatile float) +0:? 'vol2' (readonly int) +0:? 'qualim1' (layout(r32i ) coherent readonly uniform iimage2D) +0:? 'qualim2' (layout(r32i ) coherent restrict readonly uniform iimage2D) +0:? 'i1bad' (layout(rg8i ) uniform uimage2D) +0:? 'i2bad' (layout(rgba32i ) uniform image2D) +0:? 'i3bad' (layout(rgba32f ) uniform uimage2D) +0:? 'i4bad' (layout(r8_snorm ) uniform iimage2D) +0:? 'i5bad' (layout(rgba32ui ) uniform iimage2D) +0:? 'i6bad' (layout(r8ui ) uniform iimage2D) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) @@ -223,7 +330,7 @@ ERROR: node is still EOpNull! 0:42 No loop body 0:50 Function Definition: bar(vf4; (void) 0:50 Function Parameters: -0:50 'v' (in 4-component vector of float) +0:50 'v' (volatile in 4-component vector of float) 0:? Sequence 0:53 's' (int) 0:54 's' (int) @@ -296,6 +403,84 @@ ERROR: node is still EOpNull! 0:97 'a' (int) 0:97 Constant: 0:97 -1 (const int) +0:109 Function Definition: qux( (void) +0:109 Function Parameters: +0:111 Sequence +0:111 Sequence +0:111 move second child to first child (int) +0:111 'i' (int) +0:111 aoeu: direct index for structure (layout(column_major shared ) uniform int) +0:111 'anon@0' (layout(binding=7 column_major shared ) uniform block{layout(column_major shared ) uniform int aoeu}) +0:111 Constant: +0:111 0 (const uint) +0:112 Function Call: imageAtomicCompSwap(iI21;vi2;i1;i1; (int) +0:112 'iimg2D' (layout(r32i ) uniform iimage2D) +0:112 Construct ivec2 (2-component vector of int) +0:112 'i' (int) +0:112 'i' (int) +0:112 'i' (int) +0:112 'i' (int) +0:113 Function Call: imageAtomicAdd(uI21;vi2;u1; (uint) +0:113 'uimg2D' (layout(r32ui ) uniform uimage2D) +0:113 Construct ivec2 (2-component vector of int) +0:113 'i' (int) +0:113 'i' (int) +0:113 Convert int to uint (uint) +0:113 'i' (int) +0:114 Function Call: imageAtomicMin(iI21;vi2;i1; (int) +0:114 'iimg2Drgba' (layout(rgba32i ) uniform iimage2D) +0:114 Construct ivec2 (2-component vector of int) +0:114 'i' (int) +0:114 'i' (int) +0:114 'i' (int) +0:115 Constant: +0:115 0.000000 +0:116 Sequence +0:116 move second child to first child (4-component vector of int) +0:116 'pos' (4-component vector of int) +0:116 Function Call: imageLoad(iI21;vi2; (4-component vector of int) +0:116 'iimg2D' (layout(r32i ) uniform iimage2D) +0:116 Construct ivec2 (2-component vector of int) +0:116 'i' (int) +0:116 'i' (int) +0:117 Sequence +0:117 move second child to first child (4-component vector of float) +0:117 'col' (4-component vector of float) +0:117 Function Call: imageLoad(I21;vi2;i1; (4-component vector of float) +0:117 'img2DMS' (uniform image2DMS) +0:117 Construct ivec2 (2-component vector of int) +0:117 'i' (int) +0:117 'i' (int) +0:117 'i' (int) +0:118 Function Call: imageStore(I21;vi2;i1;vf4; (void) +0:118 'img2DMSWO' (writeonly uniform image2DMS) +0:118 Construct ivec2 (2-component vector of int) +0:118 'i' (int) +0:118 'i' (int) +0:118 'i' (int) +0:118 Constant: +0:118 0.000000 +0:118 0.000000 +0:118 0.000000 +0:118 0.000000 +0:119 Function Call: imageLoad(I21;vi2;i1; (4-component vector of float) +0:119 'img2DMSWO' (writeonly uniform image2DMS) +0:119 Construct ivec2 (2-component vector of int) +0:119 'i' (int) +0:119 'i' (int) +0:119 'i' (int) +0:125 Function Definition: passr(iI21; (void) +0:125 Function Parameters: +0:125 'image' (coherent readonly in iimage2D) +0:132 Function Definition: passrc( (void) +0:132 Function Parameters: +0:134 Sequence +0:134 Function Call: passr(iI21; (void) +0:134 'qualim1' (layout(r32i ) coherent readonly uniform iimage2D) +0:135 Function Call: passr(iI21; (void) +0:135 'qualim2' (layout(r32i ) coherent restrict readonly uniform iimage2D) +0:136 Function Call: passr(iI21; (void) +0:136 'iimg2D' (layout(r32i ) uniform iimage2D) 0:? Linker Objects 0:? 'v2' (smooth out 2-component vector of float) 0:? 'bad' (in 10-element array of 4-component vector of float) @@ -330,6 +515,22 @@ ERROR: node is still EOpNull! 0:? 'patchOut' (smooth patch out 4-component vector of float) 0:? 'comma0' (int) 0:? 'comma1' (1-element array of int) +0:? 'iimg2D' (layout(r32i ) uniform iimage2D) +0:? 'iimg2Drgba' (layout(rgba32i ) uniform iimage2D) +0:? 'img2Drgba' (layout(rgba32f ) uniform image2D) +0:? 'uimg2D' (layout(r32ui ) uniform uimage2D) +0:? 'img2DMS' (uniform image2DMS) +0:? 'img2DMSWO' (writeonly uniform image2DMS) +0:? 'vol' (volatile float) +0:? 'vol2' (readonly int) +0:? 'qualim1' (layout(r32i ) coherent readonly uniform iimage2D) +0:? 'qualim2' (layout(r32i ) coherent restrict readonly uniform iimage2D) +0:? 'i1bad' (layout(rg8i ) uniform uimage2D) +0:? 'i2bad' (layout(rgba32i ) uniform image2D) +0:? 'i3bad' (layout(rgba32f ) uniform uimage2D) +0:? 'i4bad' (layout(r8_snorm ) uniform iimage2D) +0:? 'i5bad' (layout(rgba32ui ) uniform iimage2D) +0:? 'i6bad' (layout(r8ui ) uniform iimage2D) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) diff --git a/Test/baseResults/430.vert.out b/Test/baseResults/430.vert.out index 2706e88342720b5436dea7b62aef9dd11cfb0211..641bab20f649f2c969deee8b694267333e5fcd48 100644 --- a/Test/baseResults/430.vert.out +++ b/Test/baseResults/430.vert.out @@ -67,7 +67,7 @@ ERROR: node is still EOpNull! 0:31 Function Definition: foo3(vf4;vf3;vf2;vf3; (void) 0:31 Function Parameters: 0:31 'v4' (in 4-component vector of float) -0:31 'v3' (in 3-component vector of float) +0:31 'v3' (volatile in 3-component vector of float) 0:31 'v2' (in 2-component vector of float) 0:31 'cv3' (in 3-component vector of float) 0:? Linker Objects @@ -139,7 +139,7 @@ ERROR: node is still EOpNull! 0:31 Function Definition: foo3(vf4;vf3;vf2;vf3; (void) 0:31 Function Parameters: 0:31 'v4' (in 4-component vector of float) -0:31 'v3' (in 3-component vector of float) +0:31 'v3' (volatile in 3-component vector of float) 0:31 'v2' (in 2-component vector of float) 0:31 'cv3' (in 3-component vector of float) 0:? Linker Objects diff --git a/Test/baseResults/specExamples.frag.out b/Test/baseResults/specExamples.frag.out index 3d1ef00786bbc31e84e2038d87b1c8e471ad5393..d4438e8b38716597639de0850fd4aa7a5de2a332 100644 --- a/Test/baseResults/specExamples.frag.out +++ b/Test/baseResults/specExamples.frag.out @@ -10,18 +10,17 @@ ERROR: 0:75: 'Atten' : member storage qualifier cannot contradict block storage ERROR: 0:87: 'Color' : redefinition ERROR: 0:92: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord ERROR: 0:93: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord -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 for this stage taking an assigned value 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) -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:106: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:112: 'depth_any' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:115: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:118: 'depth_less' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:121: 'depth_unchanged' : unrecognized layout identifier, or qualifier requires assignment (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' @@ -46,13 +45,14 @@ ERROR: 0:226: 'in' : not allowed in nested scope ERROR: 0:227: 'in' : not allowed in nested scope ERROR: 0:228: 'in' : not allowed in nested scope ERROR: 0:232: 'out' : not allowed in nested scope -ERROR: 46 compilation errors. No code generated. +ERROR: 45 compilation errors. No code generated. Shader version: 430 Requested GL_3DL_array_objects gl_FragCoord pixel center is integer gl_FragCoord origin is upper left +using early_fragment_tests ERROR: node is still EOpNull! 0:5 Sequence 0:5 move second child to first child (int) @@ -305,6 +305,7 @@ Shader version: 430 Requested GL_3DL_array_objects gl_FragCoord pixel center is integer gl_FragCoord origin is upper left +using early_fragment_tests ERROR: node is still EOpNull! 0:5 Sequence 0:5 move second child to first child (int) diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out index 95c412602fa304dd624fbec9221fc11b1e3ebff7..3b20d8fb984fbe5ed6cbebca1b571124eae89d75 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -2,13 +2,13 @@ specExamples.vert Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. ERROR: 0:23: 'transforms' : redeclaration of array with size 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: 'triangles' : unrecognized layout identifier, or qualifier requires assignment (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:33: 'lines' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) +ERROR: 0:35: 'triangle_strip' : unrecognized layout identifier, or qualifier requires assignment (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:37: 'triangle_strip' : unrecognized layout identifier, or qualifier requires assignment (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 @@ -35,16 +35,20 @@ ERROR: 0:106: '' : vertex input cannot be further qualified ERROR: 0:106: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_FrontColor ERROR: 0:112: 'ColorIvn' : identifier not previously declared WARNING: 0:118: '' : unknown requalification +ERROR: 0:123: '' : memory qualifiers can only be used on image types +ERROR: 0:122: '' : memory qualifiers can only be used on image types +ERROR: 0:128: '' : memory qualifiers can only be used on image types +ERROR: 0:129: '' : memory qualifiers can only be used on image types ERROR: 0:132: 'shared' : not supported in this stage: vertex +ERROR: 0:132: '' : memory qualifiers can only be used on image types 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, 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:170: 'coherent' : argument cannot drop memory qualifier when passed to formal parameter ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array -ERROR: 42 compilation errors. No code generated. +ERROR: 46 compilation errors. No code generated. Shader version: 430 @@ -52,7 +56,7 @@ Requested GL_3DL_array_objects ERROR: node is still EOpNull! 0:134 Function Definition: funcA(I21; (4-component vector of float) 0:134 Function Parameters: -0:134 'a' (in image2D) +0:134 'a' (restrict in image2D) 0:136 Function Definition: funcB(I21; (4-component vector of float) 0:136 Function Parameters: 0:136 'a' (in image2D) @@ -225,9 +229,9 @@ ERROR: node is still EOpNull! 0:167 Constant: 0:167 0 (const int) 0:169 Function Call: funcA(I21; (4-component vector of float) -0:169 'img1' (uniform image2D) +0:169 'img1' (layout(rgba32f ) uniform image2D) 0:170 Function Call: funcB(I21; (4-component vector of float) -0:170 'img2' (coherent uniform image2D) +0:170 'img2' (layout(rgba32f ) coherent uniform image2D) 0:? Sequence 0:178 Sequence 0:178 move second child to first child (structure{float intensity, 3-component vector of float position}) @@ -314,8 +318,8 @@ ERROR: node is still EOpNull! 0:? 'anon@6' (layout(row_major shared ) coherent uniform block{layout(row_major shared ) readonly uniform 4-component vector of float member1, layout(row_major shared ) uniform 4-component vector of float member2}) 0:? 'anon@7' (layout(row_major shared ) uniform block{layout(row_major shared ) coherent readonly uniform 4-component vector of float member1A, layout(row_major shared ) coherent uniform 4-component vector of float member2A}) 0:? 'shv' (shared 4-component vector of float) -0:? 'img1' (uniform image2D) -0:? 'img2' (coherent uniform image2D) +0:? 'img1' (layout(rgba32f ) uniform image2D) +0:? 'img2' (layout(rgba32f ) coherent uniform image2D) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) @@ -328,7 +332,7 @@ Requested GL_3DL_array_objects ERROR: node is still EOpNull! 0:134 Function Definition: funcA(I21; (4-component vector of float) 0:134 Function Parameters: -0:134 'a' (in image2D) +0:134 'a' (restrict in image2D) 0:136 Function Definition: funcB(I21; (4-component vector of float) 0:136 Function Parameters: 0:136 'a' (in image2D) @@ -501,9 +505,9 @@ ERROR: node is still EOpNull! 0:167 Constant: 0:167 0 (const int) 0:169 Function Call: funcA(I21; (4-component vector of float) -0:169 'img1' (uniform image2D) +0:169 'img1' (layout(rgba32f ) uniform image2D) 0:170 Function Call: funcB(I21; (4-component vector of float) -0:170 'img2' (coherent uniform image2D) +0:170 'img2' (layout(rgba32f ) coherent uniform image2D) 0:? Sequence 0:178 Sequence 0:178 move second child to first child (structure{float intensity, 3-component vector of float position}) @@ -590,8 +594,8 @@ ERROR: node is still EOpNull! 0:? 'anon@6' (layout(row_major shared ) coherent uniform block{layout(row_major shared ) readonly uniform 4-component vector of float member1, layout(row_major shared ) uniform 4-component vector of float member2}) 0:? 'anon@7' (layout(row_major shared ) uniform block{layout(row_major shared ) coherent readonly uniform 4-component vector of float member1A, layout(row_major shared ) coherent uniform 4-component vector of float member2A}) 0:? 'shv' (shared 4-component vector of float) -0:? 'img1' (uniform image2D) -0:? 'img2' (coherent uniform image2D) +0:? 'img1' (layout(rgba32f ) uniform image2D) +0:? 'img2' (layout(rgba32f ) coherent uniform image2D) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) diff --git a/Test/baseResults/test.conf b/Test/baseResults/test.conf index 8fc933656813616d71950b9c437eac5aa1f010fc..bcdeed02c29c66375c159dfa7f678bc8737e157f 100644 --- a/Test/baseResults/test.conf +++ b/Test/baseResults/test.conf @@ -36,6 +36,7 @@ MaxGeometryOutputComponents 128 MaxFragmentInputComponents 128 MaxImageUnits 8 MaxCombinedImageUnitsAndFragmentOutputs 8 +MaxCombinedShaderOutputResources 8 MaxImageSamples 0 MaxVertexImageUniforms 0 MaxTessControlImageUniforms 0 diff --git a/Test/reflection.vert b/Test/reflection.vert index c08ea26ab620557f610a3f1c29325830b3cc359c..101f5ffc532fb25b651e90f5dd1a5f0d52c1f17f 100644 --- a/Test/reflection.vert +++ b/Test/reflection.vert @@ -72,7 +72,7 @@ uniform float uf2; uniform float ufDead3; uniform float ufDead4; -uniform uimage2D image_ui2D; +uniform writeonly uimage2D image_ui2D; uniform sampler2D sampler_2D; uniform sampler2DMSArray sampler_2DMSArray; @@ -111,7 +111,7 @@ void liveFunction2() float f = uf1; } -void liveFunction1(uimage2D p_ui2D, sampler2D p_2D, sampler2DMSArray p_2DMSArray) +void liveFunction1(writeonly uimage2D p_ui2D, sampler2D p_2D, sampler2DMSArray p_2DMSArray) { liveFunction2(); diff --git a/Todo.txt b/Todo.txt index afd370a6fe75dd4e512da6eb8694c80c4e90315c..c4e1a701b53979e7b5fe445b55a1cb9ea66baa0d 100644 --- a/Todo.txt +++ b/Todo.txt @@ -168,11 +168,12 @@ Shader Functionality to Implement/Finish + ES convergence + Clarify that .xyzwxy.xy is illegal, as it temporarily makes a “vec6”. + Clarify that return statements only accept values (no return of a void function). - - Add image types (GL_ARB_shader_image_load_store) + + Add image types (GL_ARB_shader_image_load_store) + 33 new types, all with “image” in their name, correspond to the non-shadow texture types - + addition of memory qualifiers: coherent,volatile, restrict, readonly, and writeonly - - can read/write/modify images from a shader, through new built-in functions - - qualifiers can act independently on the opaque shader variable and the backing image, so extra qualifiers can be used to separately qualify these + + addition of memory qualifiers: coherent, volatile, restrict, readonly, and writeonly + + can read/write/modify images from a shader, through new built-in functions + + qualifiers can act independently on the opaque shader variable and the backing image, so extra qualifiers can be used to separately qualify these + + early_fragment_tests + Variables declared in if and else statements are scoped only to the end of those statements, especially for non-compound statements Note, this is not backward compatible, it may depend on #version. + Allow implicit conversions of return values to the declared type of the function. diff --git a/glslang/Include/ResourceLimits.h b/glslang/Include/ResourceLimits.h index 03a39fd1d061d9fcdd00499467488e1ed3892aa9..bdf879c5ed7c734c2fec5890a94bbf6748d8c78c 100644 --- a/glslang/Include/ResourceLimits.h +++ b/glslang/Include/ResourceLimits.h @@ -88,6 +88,7 @@ struct TBuiltInResource { int maxFragmentInputComponents; int maxImageUnits; int maxCombinedImageUnitsAndFragmentOutputs; + int maxCombinedShaderOutputResources; int maxImageSamples; int maxVertexImageUniforms; int maxTessControlImageUniforms; diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 9ab22ebbac25d94db4b41a21e627201f1b629e19..ef1dcd9e6ca08f6384aa39cdd54a79969069571a 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -241,6 +241,61 @@ enum TVertexOrder { EvoCcw }; +// Note: order matters, as type of format is done by comparison. +enum TLayoutFormat { + ElfNone, + + // Float image + ElfRgba32f, + ElfRgba16f, + ElfRg32f, + ElfRg16f, + ElfR11fG11fB10f, + ElfR32f, + ElfR16f, + ElfRgba16, + ElfRgb10A2, + ElfRgba8, + ElfRg16, + ElfRg8, + ElfR16, + ElfR8, + ElfRgba16Snorm, + ElfRgba8Snorm, + ElfRg16Snorm, + ElfRg8Snorm, + ElfR16Snorm, + ElfR8Snorm, + + ElfFloatGuard, // to help with comparisons + + // Int image + ElfRgba32i, + ElfRgba16i, + ElfRgba8i, + ElfRg32i, + ElfRg16i, + ElfRg8i, + ElfR32i, + ElfR16i, + ElfR8i, + + ElfIntGuard, // to help with comparisons + + // Uint image + ElfRgba32ui, + ElfRgba16ui, + ElfRgba8ui, + ElfRg32ui, + ElfRg16ui, + ElfRg8ui, + ElfR32ui, + ElfR16ui, + ElfR8ui, + + ElfCount +}; + class TQualifier { public: void clear() @@ -416,6 +471,8 @@ public: layoutXfbBuffer = layoutXfbBufferEnd; layoutXfbStride = layoutXfbStrideEnd; layoutXfbOffset = layoutXfbOffsetEnd; + + layoutFormat = ElfNone; } bool hasLayout() const { @@ -423,7 +480,8 @@ public: hasLocation() || hasBinding() || hasStream() || - hasXfb(); + hasXfb() || + hasFormat(); } TLayoutMatrix layoutMatrix : 3; TLayoutPacking layoutPacking : 4; @@ -451,6 +509,8 @@ public: unsigned int layoutXfbOffset : 10; static const unsigned int layoutXfbOffsetEnd = 0x3FF; + TLayoutFormat layoutFormat : 8; + bool hasUniformLayout() const { return hasMatrix() || @@ -491,6 +551,10 @@ public: { return layoutStream != layoutStreamEnd; } + bool hasFormat() const + { + return layoutFormat != ElfNone; + } bool hasXfb() const { return hasXfbBuffer() || @@ -527,12 +591,58 @@ public: default: return "none"; } } + static const char* getLayoutFormatString(TLayoutFormat f) + { + switch (f) { + case ElfRgba32f: return "rgba32f"; + case ElfRgba16f: return "rgba16f"; + case ElfRg32f: return "rg32f"; + case ElfRg16f: return "rg16f"; + case ElfR11fG11fB10f: return "r11f_g11f_b10f"; + case ElfR32f: return "r32f"; + case ElfR16f: return "r16f"; + case ElfRgba16: return "rgba16"; + case ElfRgb10A2: return "rgb10_a2"; + case ElfRgba8: return "rgba8"; + case ElfRg16: return "rg16"; + case ElfRg8: return "rg8"; + case ElfR16: return "r16"; + case ElfR8: return "r8"; + case ElfRgba16Snorm: return "rgba16_snorm"; + case ElfRgba8Snorm: return "rgba8_snorm"; + case ElfRg16Snorm: return "rg16_snorm"; + case ElfRg8Snorm: return "rg8_snorm"; + case ElfR16Snorm: return "r16_snorm"; + case ElfR8Snorm: return "r8_snorm"; + + case ElfRgba32i: return "rgba32i"; + case ElfRgba16i: return "rgba16i"; + case ElfRgba8i: return "rgba8i"; + case ElfRg32i: return "rg32i"; + case ElfRg16i: return "rg16i"; + case ElfRg8i: return "rg8i"; + case ElfR32i: return "r32i"; + case ElfR16i: return "r16i"; + case ElfR8i: return "r8i"; + + case ElfRgba32ui: return "rgba32ui"; + case ElfRgba16ui: return "rgba16ui"; + case ElfRgba8ui: return "rgba8ui"; + case ElfRg32ui: return "rg32ui"; + case ElfRg16ui: return "rg16ui"; + case ElfRg8ui: return "rg8ui"; + case ElfR32ui: return "r32ui"; + case ElfR16ui: return "r16ui"; + case ElfR8ui: return "r8ui"; + 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 ElgLinesAdjacency: return "lines_adjacency"; case ElgLineStrip: return "line_strip"; case ElgTriangles: return "triangles"; case ElgTrianglesAdjacency: return "triangles_adjacency"; @@ -583,6 +693,7 @@ struct TShaderQualifiers { TVertexSpacing spacing; TVertexOrder order; bool pointMode; + bool earlyFragmentTests; // fragment input void init() { @@ -594,6 +705,7 @@ struct TShaderQualifiers { spacing = EvsNone; order = EvoNone; pointMode = false; + earlyFragmentTests = false; } // Merge in characteristics from the 'src' qualifier. They can override when @@ -616,6 +728,8 @@ struct TShaderQualifiers { order = src.order; if (src.pointMode) pointMode = true; + if (src.earlyFragmentTests) + earlyFragmentTests = true; } }; @@ -1023,6 +1137,9 @@ public: if (qualifier.hasAlign()) p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign); + if (qualifier.hasFormat()) + p += snprintf(p, end - p, "%s ", TQualifier::getLayoutFormatString(qualifier.layoutFormat)); + if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer); if (qualifier.hasXfbOffset()) diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 9fa6e4c4e14b9adbc194038b4a392b83e5db118b..4ea7c965b0853306e90a015b8c624dff2ddbb740 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -845,7 +845,7 @@ void TBuiltIns::initialize(int version, EProfile profile) "void barrier();" ); - if (version >= 420) + if (version >= 130) commonBuiltins.append( "void memoryBarrier();" ); @@ -1467,9 +1467,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile) // enumerate all the types for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler - if (image > 0 && version < 420) - continue; - for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not for (int ms = 0; ms <=1; ++ms) { @@ -1523,8 +1520,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile) addImageFunctions(sampler, typeName, version, profile); else { addSamplingFunctions(sampler, typeName, version, profile); - if (version >= 130) - addGatherFunctions(sampler, typeName, version, profile); + addGatherFunctions(sampler, typeName, version, profile); } } } @@ -1577,7 +1573,63 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi // void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile) { - // TODO: 4.2 Functionality: imaging functions + int dims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + TString imageParams = typeName; + if (dims == 1) + imageParams.append(", int"); + else { + imageParams.append(", ivec"); + imageParams.append(postfixes[dims]); + } + if (sampler.ms) + imageParams.append(", int"); + + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4 imageLoad(readonly "); + commonBuiltins.append(imageParams); + commonBuiltins.append(");\n"); + + commonBuiltins.append("void imageStore(writeonly "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4);\n"); + + if (sampler.type == EbtInt || sampler.type == EbtUint) { + const char* dataType = sampler.type == EbtInt ? "int" : "uint"; + + const int numBuiltins = 7; + + static const char* atomicFunc[numBuiltins] = { + " imageAtomicAdd(", + " imageAtomicMin(", + " imageAtomicMax(", + " imageAtomicAnd(", + " imageAtomicOr(", + " imageAtomicXor(", + " imageAtomicExchange(" + }; + + for (size_t i = 0; i < numBuiltins; ++i) { + commonBuiltins.append(dataType); + commonBuiltins.append(atomicFunc[i]); + if (version >= 450) + commonBuiltins.append("coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(");\n"); + } + + commonBuiltins.append(dataType); + commonBuiltins.append(" imageAtomicCompSwap("); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(");\n"); + } } // @@ -2111,17 +2163,27 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf } // images - if (version >= 420) { - //snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.); - //snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.); + if (version >= 130) { + snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.maxCombinedImageUnitsAndFragmentOutputs); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.maxImageSamples); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms); + s.append(builtInConstant); } // compute @@ -2264,6 +2326,11 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb symbolTable.setFunctionExtensions("textureCubeGradEXT", 1, &GL_EXT_shader_texture_lod); } + // GL_ARB_shader_image_load_store + if (version < 420) + symbolTable.setFunctionExtensions("memoryBarrier", 1, &GL_ARB_shader_image_load_store); + // All the image access functions are protected by checks on the type of the first argument. + symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &GL_EXT_frag_depth); break; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index e950eff851fdec8da6b6f722c73cb545cb8ba42b..61874029465876da06a24f67c68b8a4e38766abc 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -967,18 +967,32 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); if (arguments) { - // Make sure storage qualifications work for these arguments. + // Make sure qualifications work for these arguments. TIntermAggregate* aggregate = arguments->getAsAggregate(); for (int i = 0; i < fnCandidate->getParamCount(); ++i) { - TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage; - if (qual == EvqOut || qual == EvqInOut) { - // At this early point there is a slight ambiguity between whether an aggregate 'arguments' - // is the single argument itself or its children are the arguments. Only one argument - // means take 'arguments' itself as the one argument. - TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments); + // At this early point there is a slight ambiguity between whether an aggregate 'arguments' + // is the single argument itself or its children are the arguments. Only one argument + // means take 'arguments' itself as the one argument. + TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments); + TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier(); + if (formalQualifier.storage == EvqOut || formalQualifier.storage == EvqInOut) { if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped())) error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); } + TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); + if (argQualifier.isMemory()) { + const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; + if (argQualifier.volatil && ! formalQualifier.volatil) + error(arguments->getLoc(), message, "volatile", ""); + if (argQualifier.coherent && ! formalQualifier.coherent) + error(arguments->getLoc(), message, "coherent", ""); + if (argQualifier.restrict && ! formalQualifier.restrict) + error(arguments->getLoc(), message, "restrict", ""); + if (argQualifier.readonly && ! formalQualifier.readonly) + error(arguments->getLoc(), message, "readonly", ""); + if (argQualifier.writeonly && ! formalQualifier.writeonly) + error(arguments->getLoc(), message, "writeonly", ""); + } } // Convert 'in' arguments @@ -1273,6 +1287,14 @@ void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandida } } } + if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) { + const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType(); + if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { + if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); + } else + error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); + } } // @@ -2651,6 +2673,13 @@ void TParseContext::paramCheckFix(TSourceLoc loc, const TStorageQualifier& quali void TParseContext::paramCheckFix(TSourceLoc loc, const TQualifier& qualifier, TType& type) { + if (qualifier.isMemory()) { + type.getQualifier().volatil = qualifier.volatil; + type.getQualifier().coherent = qualifier.coherent; + type.getQualifier().readonly = qualifier.readonly; + type.getQualifier().writeonly = qualifier.writeonly; + type.getQualifier().restrict = qualifier.restrict; + } if (qualifier.isAuxiliary() || qualifier.isInterpolation()) error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", ""); @@ -2898,6 +2927,14 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, publicType.qualifier.layoutPacking = ElpStd430; return; } + for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) { + if (id == TQualifier::getLayoutFormatString(format)) { + requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load store"); + profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "image load store"); + publicType.qualifier.layoutFormat = format; + return; + } + } if (language == EShLangGeometry || language == EShLangTessEvaluation) { if (id == TQualifier::getGeometryString(ElgTriangles)) { publicType.shaderQualifiers.geometry = ElgTriangles; @@ -2987,8 +3024,14 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, publicType.shaderQualifiers.pixelCenterInteger = true; return; } + if (id == "early_fragment_tests") { + requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "early_fragment_tests"); + profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "early_fragment_tests"); + publicType.shaderQualifiers.earlyFragmentTests = true; + return; + } } - error(loc, "unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)", id.c_str(), ""); + error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); } // Put the id's layout qualifier value into the public type. This is before we know any @@ -3169,6 +3212,9 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, if (src.hasStream()) dst.layoutStream = src.layoutStream; + if (src.hasFormat()) + dst.layoutFormat = src.layoutFormat; + if (src.hasXfbBuffer()) dst.layoutXfbBuffer = src.layoutXfbBuffer; @@ -3332,6 +3378,23 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) if (type.getBasicType() == EbtBlock) error(loc, "only applies to block members, not blocks", "offset", ""); } + + // Image format + if (qualifier.hasFormat()) { + if (type.getBasicType() != EbtSampler || ! type.getSampler().image) + error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + else { + if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard) + error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard)) + error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard) + error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + } + } else if (type.getBasicType() == EbtSampler && type.getSampler().image && !qualifier.writeonly) + error(loc, "image variables not declared 'writeonly' must have a format layout qualifier", "", ""); + if (qualifier.isMemory() && (type.getBasicType() != EbtSampler || ! type.getSampler().image)) + error(loc, "memory qualifiers can only be used on image types", "", ""); } // Do layout error checking that can be done within a qualifier proper, not needing to know @@ -4498,6 +4561,12 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub else error(loc, "can only apply to 'in'", "point_mode", ""); } + if (publicType.shaderQualifiers.earlyFragmentTests) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setEarlyFragmentTests(); + else + error(loc, "can only apply to 'in'", "early_fragment_tests", ""); + } const TQualifier& qualifier = publicType.qualifier; diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index d10369c4e7315edf99f206965ec02061603249bd..a7a72e278210148f3e3d3929550824a21ec34017 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -672,15 +672,17 @@ int TScanContext::tokenizeIdentifier() return identifierOrType(); return keyword; + case ATOMIC_UINT: + return es30ReservedFromGLSL(420); + case COHERENT: case RESTRICT: case READONLY: case WRITEONLY: - case ATOMIC_UINT: - return es30ReservedFromGLSL(420); + return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420); case VOLATILE: - if (parseContext.profile == EEsProfile || parseContext.version < 420) + if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store)))) reservedWord(); return keyword; @@ -766,7 +768,7 @@ int TScanContext::tokenizeIdentifier() case IMAGECUBEARRAY: case IIMAGECUBEARRAY: - case UIMAGECUBEARRAY: + case UIMAGECUBEARRAY: case IMAGE2DMS: case IIMAGE2DMS: case UIMAGE2DMS: @@ -993,6 +995,9 @@ int TScanContext::identifierOrReserved(bool reserved) // but then got reserved by ES 3.0. int TScanContext::es30ReservedFromGLSL(int version) { + if (parseContext.symbolTable.atBuiltInLevel()) + return keyword; + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || (parseContext.profile != EEsProfile && parseContext.version < version)) { if (parseContext.forwardCompatible) @@ -1067,7 +1072,7 @@ int TScanContext::firstGenerationImage() { afterType = true; - if (parseContext.profile != EEsProfile && parseContext.version >= 420) + if (parseContext.symbolTable.atBuiltInLevel() || (parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store)))) return keyword; if ((parseContext.profile == EEsProfile && parseContext.version >= 300) || @@ -1087,7 +1092,7 @@ int TScanContext::secondGenerationImage() { afterType = true; - if (parseContext.profile != EEsProfile && parseContext.version >= 420) + if (parseContext.symbolTable.atBuiltInLevel() || parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store))) return keyword; if (parseContext.forwardCompatible) diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index eee23f12ee942172f6d72ef988790d51b666b502..feb233a68c3c6fe508f58d8240e5d8bcaf3068f7 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -166,6 +166,7 @@ void TParseContext::initializeExtensionBehavior() extensionBehavior[GL_ARB_texture_cube_map_array] = EBhDisable; extensionBehavior[GL_ARB_shader_texture_lod] = EBhDisable; extensionBehavior[GL_ARB_explicit_attrib_location] = EBhDisablePartial; // "index" for fragment outputs is missing + extensionBehavior[GL_ARB_shader_image_load_store] = EBhDisable; } // Get code that is not part of a shared symbol table, is specific to this shader, @@ -203,7 +204,8 @@ const char* TParseContext::getPreamble() "#define GL_ARB_enhanced_layouts 1\n" "#define GL_ARB_texture_cube_map_array 1\n" "#define GL_ARB_shader_texture_lod 1\n" - "#define GL_ARB_explicit_attrib_location 1\n"; + "#define GL_ARB_explicit_attrib_location 1\n" + "#define GL_ARB_shader_image_load_store 1\n"; } } diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index fce980ab3e0a4b9ae4905fea898a39b931cd8be1..0f51ddcded8f2a01fdc0a0bd9295f421479d8a85 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -90,6 +90,7 @@ const char* const GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; const char* const GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array"; const char* const GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; const char* const GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; +const char* const GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; } // end namespace glslang diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index cad4acd27a8afd221d482d8f6bc4878a23e77d09..8cc62f7a2adbd000472ee5c3dad8e197eeb22090 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -611,6 +611,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) infoSink.debug << "gl_FragCoord pixel center is integer\n"; if (originUpperLeft) infoSink.debug << "gl_FragCoord origin is upper left\n"; + if (earlyFragmentTests) + infoSink.debug << "using early_fragment_tests\n"; break; case EShLangCompute: diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 6625a34ef944b3607bed79b7b245868ba92ba176..b53bc31b47dc7f5266cb0e05ae65fdeaf6a5d43d 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -80,6 +80,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) error(infoSink, "gl_FragCoord redeclarations must match across shaders\n"); + if (! earlyFragmentTests) + earlyFragmentTests = unit.earlyFragmentTests; + if (inputPrimitive == ElgNone) inputPrimitive = unit.inputPrimitive; else if (inputPrimitive != unit.inputPrimitive) diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 1e7e5d6c631165b3f3df0b65bdc657fec79b05b2..00d7ba222ec0c45bd01386c00afedfea38c436de 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -112,7 +112,7 @@ public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0), recursive(false), invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), - vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), xfbMode(false) + vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), xfbMode(false) { xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); } @@ -235,6 +235,8 @@ public: bool getOriginUpperLeft() const { return originUpperLeft; } void setPixelCenterInteger() { pixelCenterInteger = true; } bool getPixelCenterInteger() const { return pixelCenterInteger; } + void setEarlyFragmentTests() { earlyFragmentTests = true; } + bool getEarlyFragmentTests() const { return earlyFragmentTests; } void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void merge(TInfoSink&, TIntermediate&); @@ -287,6 +289,7 @@ protected: TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; bool pointMode; + bool earlyFragmentTests; bool xfbMode; typedef std::list<TCall> TGraph;