diff --git a/StandAlone.vcproj b/StandAlone.vcproj deleted file mode 100644 index 411a83c8..00000000 --- a/StandAlone.vcproj +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/StandAlone.vcxproj b/StandAlone.vcxproj new file mode 100644 index 00000000..36eec5e6 --- /dev/null +++ b/StandAlone.vcxproj @@ -0,0 +1,151 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + StandAlone + {660D0A05-69A9-4F09-9664-02FBEB08FAE2} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + StandAlone\UserM_Debug\ + StandAlone\UserM_Debug\ + true + UserM_Release\ + UserM_Release\ + false + + + + Disabled + glslang;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;GENERIC_COMPILER;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + + + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + FastCall + + + /MACHINE:I386 %(AdditionalOptions) + odbc32.lib;odbccp32.lib;psapi.lib;UserM_Debug\generic\glslang.lib;%(AdditionalDependencies) + true + %(IgnoreSpecificDefaultLibraries) + true + UserM_Debug/StandAlone.pdb + Console + + + UserM_Debug/StandAlone.tlb + + + move exe + xcopy /y StandAlone\UserM_Debug\StandAlone.exe Test + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + + + + + MaxSpeed + OnlyExplicitInline + true + glslang;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;GENERIC_COMPILER;%(PreprocessorDefinitions) + true + Default + MultiThreaded + true + true + + + + + UserM_Release/ + UserM_Release/ + UserM_Release/Standalone + Level3 + true + ProgramDatabase + FastCall + + + /MACHINE:I386 %(AdditionalOptions) + odbc32.lib;odbccp32.lib;psapi.lib;Standalone\glslang.lib;%(AdditionalDependencies) + UserM_Release/StandAlone.exe + true + %(IgnoreSpecificDefaultLibraries) + true + UserM_Release/StandAlone.pdb + Console + true + true + + + UserM_Release/StandAlone.tlb + + + move exe + xcopy /y StandAlone\UserM_Release\StandAlone.exe StandAlone + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + + + + {3b146cc5-b2b8-4573-9d46-6139e2edfea3} + false + + + + + + \ No newline at end of file diff --git a/StandAlone.vcxproj.filters b/StandAlone.vcxproj.filters new file mode 100644 index 00000000..0685ca2f --- /dev/null +++ b/StandAlone.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {fcd4a310-b19f-40bd-9324-e7d4e7d4dad1} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + + + Source Files + + + \ No newline at end of file diff --git a/Test/run.bat b/Test/run.bat new file mode 100644 index 00000000..2e4d5c17 --- /dev/null +++ b/Test/run.bat @@ -0,0 +1,5 @@ +.\StandAlone.exe -i sample.vert > sample.vert.newout +diff sample.vert.out sample.vert.newout + +.\StandAlone.exe -i sample.frag > sample.frag.newout +diff sample.frag.out sample.frag.newout diff --git a/Test/runlist.bat b/Test/runlist.bat new file mode 100644 index 00000000..8d68a473 --- /dev/null +++ b/Test/runlist.bat @@ -0,0 +1 @@ +for /F "tokens=*" %%f in (testlist) do .\StandAlone.exe -i %%f diff --git a/StandAlone/sample.frag b/Test/sample.frag similarity index 95% rename from StandAlone/sample.frag rename to Test/sample.frag index 0d11cb2e..af3a6265 100644 --- a/StandAlone/sample.frag +++ b/Test/sample.frag @@ -36,5 +36,5 @@ varying vec3 color; void main() { - gl_FragColor = vec4(color, 1.0); + gl_FragColor = vec4(color, 1.0f); } diff --git a/StandAlone/sample.frag.out b/Test/sample.frag.out similarity index 85% rename from StandAlone/sample.frag.out rename to Test/sample.frag.out index 5af223e4..ebc450ca 100644 --- a/StandAlone/sample.frag.out +++ b/Test/sample.frag.out @@ -6,7 +6,7 @@ 0:39 move second child to first child (4-component vector of float) 0:39 'gl_FragColor' (FragColor 4-component vector of float) 0:39 Construct vec4 (4-component vector of float) -0:39 'color' (varying 3-component vector of float) +0:39 'color' (varying in 3-component vector of float) 0:39 1.000000 (const float) #### END COMPILER 0 INFO LOG #### diff --git a/StandAlone/sample.vert b/Test/sample.vert similarity index 100% rename from StandAlone/sample.vert rename to Test/sample.vert diff --git a/StandAlone/sample.vert.out b/Test/sample.vert.out similarity index 90% rename from StandAlone/sample.vert.out rename to Test/sample.vert.out index 2d50a828..ebb700d2 100644 --- a/StandAlone/sample.vert.out +++ b/Test/sample.vert.out @@ -4,7 +4,7 @@ 0:37 Function Parameters: 0:39 Sequence 0:39 move second child to first child (3-component vector of float) -0:39 'color' (varying 3-component vector of float) +0:39 'color' (varying out 3-component vector of float) 0:39 1.000000 (const float) 0:39 1.000000 (const float) 0:39 1.000000 (const float) diff --git a/Test/specExamples.frag b/Test/specExamples.frag new file mode 100644 index 00000000..3da05f43 --- /dev/null +++ b/Test/specExamples.frag @@ -0,0 +1,237 @@ +#version 430 + +#extension GL_3DL_array_objects : enable + +int a = 0xffffffff; // 32 bits, a gets the value -1 +//int b = 0xffffffffU; // ERROR: can't convert uint to int +uint c = 0xffffffff; // 32 bits, c gets the value 0xFFFFFFFF +//uint d = 0xffffffffU; // 32 bits, d gets the value 0xFFFFFFFF +int e = -1; // the literal is “1”, then negation is performed, + // and the resulting non-literal 32-bit signed + // bit pattern of 0xFFFFFFFF is assigned, giving e + // the value of -1. +//uint f = -1u; // the literal is “1u”, then negation is performed, + // and the resulting non-literal 32-bit unsigned + // bit pattern of 0xFFFFFFFF is assigned, giving f + // the value of 0xFFFFFFFF. +int g = 3000000000; // a signed decimal literal taking 32 bits, + // setting the sign bit, g gets -1294967296 +int h = 0xA0000000; // okay, 32-bit signed hexadecimal +//int i = 5000000000; // ERROR: needs more than 32 bits +//int j = 0xFFFFFFFFF; // ERROR: needs more that 32 bits +int k = 0x80000000; // k gets -2147483648 == 0x80000000 +int l = 2147483648; // l gets -2147483648 (the literal set the sign bit) + +float fa, fb = 1.5; // single-precision floating-point +//double fc, fd = 2.0LF; // double-precision floating-point + +vec2 texcoord1, texcoord2; +vec3 position; +vec4 myRGBA; +ivec2 textureLookup; +bvec3 less; + +mat2 mat2D; +mat3 optMatrix; +mat4 view, projection; +mat4x4 view; // an alternate way of declaring a mat4 +mat3x2 m; // a matrix with 3 columns and 2 rows +dmat4 highPrecisionMVP; +dmat2x4 dm; + +struct light { + float intensity; + vec3 position; +} lightVar; + +struct S { float f; }; + +struct T { + //S; // Error: anonymous structures disallowed + //struct { ... }; // Error: embedded structures disallowed + S s; // Okay: nested structures with name are allowed +}; + +float frequencies[3]; +uniform vec4 lightPosition[4]; +light lights[]; +const int numLights = 2; +light lights[numLights]; + +in vec3 normal; +centroid in vec2 TexCoord; +invariant centroid in vec4 Color; +noperspective in float temperature; +flat in vec3 myColor; +noperspective centroid in vec2 myTexCoord; + +uniform vec4 lightPosition; +uniform vec3 color = vec3(0.7, 0.7, 0.2); // value assigned at link time + +in Material { + smooth in vec4 Color1; // legal, input inside in block + smooth vec4 Color2; // legal, 'in' inherited from 'in Material' + vec2 TexCoord; // legal, TexCoord is an input + uniform float Atten; // illegal, mismatched storage qualifier + +}; + +in Light { + vec4 LightPos; + vec3 LightColor; +}; +in ColoredTexture { + vec4 Color; + vec2 TexCoord; +} Material; // instance name +vec3 Color; // different Color than Material.Color + +in vec4 gl_FragCoord; // redeclaration that changes nothing is allowed + +// All the following are allowed redeclaration that change behavior +layout(origin_upper_left) in vec4 gl_FragCoord; +layout(pixel_center_integer) in vec4 gl_FragCoord; +layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; + +layout(early_fragment_tests) in; + +// compute shader: +layout (local_size_x = 32, local_size_y = 32) in; +layout (local_size_x = 8) in; + +layout(location = 3) out vec4 color; +layout(location = 3, index = 1) out vec4 factor; +layout(location = 2) out vec4 colors[3]; + +layout (depth_greater) out float gl_FragDepth; + +// redeclaration that changes nothing is allowed +out float gl_FragDepth; + +// assume it may be modified in any way +layout (depth_any) out float gl_FragDepth; + +// assume it may be modified such that its value will only increase +layout (depth_greater) out float gl_FragDepth; + +// assume it may be modified such that its value will only decrease +layout (depth_less) out float gl_FragDepth; + +// assume it will not be modified +layout (depth_unchanged) out float gl_FragDepth; + +in vec4 gl_Color; // predeclared by the fragment language +flat in vec4 gl_Color; // redeclared by user to be flat + + +float[5] foo(float[5]) +{ + return float[5](3.4, 4.2, 5.0, 5.2, 1.1); +} + +precision highp float; +precision highp int; +precision mediump int; +precision highp float; + +void main() +{ + { + float a[5] = float[5](3.4, 4.2, 5.0, 5.2, 1.1); + } + { + float a[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1); // same thing + } + { + vec4 a[3][2]; // size-3 array of size-2 array of vec4 + vec4[2] a1[3]; // size-3 array of size-2 array of vec4 + vec4[3][2] a2; // size-3 array of size-2 array of vec4 + vec4 b[2] = vec4[2](vec4(0.0), vec4(0.1)); + vec4[3][2] a3 = vec4[3][2](b, b, b); // constructor + void foo(vec4[3][2]); // prototype with unnamed parameter + vec4 a4[3][2] = {vec4[2](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0)) }; + } + { + float a[5]; + { + float b[] = a; // b is explicitly size 5 + } + { + float b[5] = a; // means the same thing + } + { + float b[] = float[](1,2,3,4,5); // also explicitly sizes to 5 + } + a.length(); // returns 5 + } + { + vec4 a[3][2]; + a.length(); // this is 3 + a[x].length(); // this is 2 + } + // for an array b containing a member array a: + b[++x].a.length(); // b is never dereferenced, but “++x” is evaluated + + // for an array s of a shader storage object containing a member array a: + s[x].a.length(); // s is dereferenced; x needs to be a valid index + // + //All of the following declarations result in a compile-time error. + //float a[2] = { 3.4, 4.2, 5.0 }; // illegal + //vec2 b = { 1.0, 2.0, 3.0 }; // illegal + //mat3x3 c = { vec3(0.0), vec3(1.0), vec3(2.0), vec3(3.0) }; // illegal + //mat2x2 d = { 1.0, 0.0, 0.0, 1.0 }; // illegal, can't flatten nesting + //struct { + // float a; + // int b; + //} e = { 1.2, 2, 3 }; // illegal + + struct { + float a; + int b; + } e = { 1.2, 2 }; // legal, all types match + + struct { + float a; + int b; + } e = { 1, 3 }; // legal, first initializer is converted + + //All of the following declarations result in a compile-time error. + //int a = true; // illegal + //vec4 b[2] = { vec4(0.0), 1.0 }; // illegal + //mat4x2 c = { vec3(0.0), vec3(1.0) }; // illegal + + //struct S1 { + // vec4 a; + // vec4 b; + //}; + + //struct { + // float s; + // float t; + //} d[] = { S1(vec4(0.0), vec4(1.1)) }; // illegal + + { + float a[] = float[](3.4, 4.2, 5.0, 5.2, 1.1); + float b[] = { 3.4, 4.2, 5.0, 5.2, 1.1 }; + float c[] = a; // c is explicitly size 5 + float d[5] = b; // means the same thing + } + { + const vec3 zAxis = vec3 (0.0, 0.0, 1.0); + const float ceiling = a + b; // a and b not necessarily constants + } + { + in vec4 position; + in vec3 normal; + in vec2 texCoord[4]; + } + { + lowp float color; + out mediump vec2 P; + lowp ivec2 foo(lowp mat3); + highp mat4 m; + } + +} diff --git a/Test/specExamples.vert b/Test/specExamples.vert new file mode 100644 index 00000000..55559307 --- /dev/null +++ b/Test/specExamples.vert @@ -0,0 +1,196 @@ +#version 110 + +#extension GL_3DL_array_objects : enable + +out Vertex { + vec4 Position; // API transform/feedback will use “Vertex.Position” + vec2 Texture; +} Coords; // shader will use “Coords.Position” + +out Vertex2 { + vec4 Color; // API will use “Color” +}; + +uniform Transform { // API uses “Transform[2]” to refer to instance 2 + mat4 ModelViewMatrix; + mat4 ModelViewProjectionMatrix; + vec4 a[]; // array will get implicitly sized + float Deformation; +} transforms[4]; + +layout(location = 3) in vec4 normal; +layout(location = 6) in vec4 colors[3]; +layout(location = 9) in mat4 transforms[2]; + +layout(location = 3) struct S { + vec3 a; + mat2 b; + vec4 c[2]; +} s; + +layout(triangles, invocations = 6) in; + +layout(lines) in; // legal for Color2, input size is 2, matching Color2 + +layout(triangle_strip, max_vertices = 60) out; // order does not matter +layout(max_vertices = 60) out; // redeclaration okay +layout(triangle_strip) out; // redeclaration okay +//layout(points) out; // error, contradicts triangle_strip +//layout(max_vertices = 30) out; // error, contradicts 60 + +layout(stream = 1) out; + +layout(stream=1) out; // default is now stream 1 +out vec4 var1; // var1 gets default stream (1) +layout(stream=2) out Block1 { // "Block1" belongs to stream 2 + layout(stream=2) vec4 var2; // redundant block member stream decl + layout(stream=3) vec2 var3; // ILLEGAL (must match block stream) + vec3 var4; // belongs to stream 2 +}; +layout(stream=0) out; // default is now stream 0 +out vec4 var5; // var5 gets default stream (0) +out Block2 { // "Block2" gets default stream (0) + vec4 var6; +}; +layout(stream=3) out vec4 var7; // var7 belongs to stream 3 + +layout(shared, column_major) uniform; +layout(shared, column_major) buffer; + +layout(row_major, column_major) + +layout(shared, row_major) uniform; // default is now shared and row_major + +layout(std140) uniform Transform { // layout of this block is std140 + mat4 M1; // row_major + layout(column_major) mat4 M2; // column major + mat3 N1; // row_major +}; + +layout(column_major) uniform T3 { // shared and column_major + mat4 M3; // column_major + layout(row_major) mat4 m4; // row major + mat3 N2; // column_major +}; + +// in one compilation unit... +layout(binding=3) uniform sampler2D s; // s bound to unit 3 + +// in another compilation unit... +uniform sampler2D s; // okay, s still bound at 3 + +// in another compilation unit... +//layout(binding=4) uniform sampler2D s; // ERROR: contradictory bindings + +layout (binding = 2, offset = 4) uniform atomic_uint a; + +layout (binding = 2) uniform atomic_uint bar; + +layout (binding = 2, offset = 4) uniform atomic_uint; + +layout (binding = 2) uniform atomic_uint bar; // offset is 4 +layout (offset = 8) uniform atomic_uint bar; // error, no default binding + +layout (binding=3, offset=4) uniform atomic_uint a2; // offset = 4 +layout (binding=2) uniform atomic_uint b2; // offset = 0 +layout (binding=3) uniform atomic_uint c2; // offset = 8 +layout (binding=2) uniform atomic_uint d2; // offset = 4 + +//layout (offset=4) // error, must include binding +layout (binding=1, offset=0) a; // okay +layout (binding=2, offset=0) b; // okay +//layout (binding=1, offset=0) c; // error, offsets must not be shared +// // between a and c +//layout (binding=1, offset=2) d; // error, overlaps offset 0 of a + +flat in vec4 gl_FrontColor; // input to geometry shader, no “gl_in[]” +flat out vec4 gl_FrontColor; // output from geometry shader + +invariant gl_Position; // make existing gl_Position be invariant + +out vec3 Color; +invariant Color; // make existing Color be invariant + +invariant centroid out vec3 Color4; +precise out vec4 position; + +out vec3 Color5; +precise Color5; // make existing Color be precise +in vec4 a, b, c, d; +precise out vec4 v; + +coherent buffer Block { + readonly vec4 member1; + vec4 member2; +}; + +buffer Block { + coherent readonly vec4 member1; + coherent vec4 member2; +}; + +shared vec4 shv; + +vec4 funcA(restrict image2D a) { } + +vec4 funcB(image2D a) { } +layout(rgba32f) uniform image2D img1; +layout(rgba32f) coherent uniform image2D img2; + +float func(float e, float f, float g, float h) +{ + return (e*f) + (g*h); // no constraint on order or + // operator consistency +} + +float func2(float e, float f, float g, float h) +{ + precise float result = (e*f) + (g*h); // ensures same precision for + // the two multiplies + return result; +} + +float func3(float i, float j, precise out float k) +{ + k = i * i + j; // precise, due to declaration +} + +void main() +{ + vec3 r = vec3(a * b); // precise, used to compute v.xyz + vec3 s = vec3(c * d); // precise, used to compute v.xyz + v.xyz = r + s; // precise + v.w = (a.w * b.w) + (c.w * d.w); // precise + v.x = func(a.x, b.x, c.x, d.x); // values computed in func() + // are NOT precise + v.x = func2(a.x, b.x, c.x, d.x); // precise! + func3(a.x * b.x, c.x * d.x, v.x); // precise! + + funcA(img1); // OK, adding "restrict" is allowed + funcB(img2); // illegal, stripping "coherent" is not + + { + struct light { + float intensity; + vec3 position; + }; + + light lightVar = light(3.0, vec3(1.0, 2.0, 3.0)); + } + { + const float c[3] = float[3](5.0, 7.2, 1.1); + const float d[3] = float[](5.0, 7.2, 1.1); + + float g; + float a[5] = float[5](g, 1, g, 2.3, g); + float b[3]; + + b = float[3](g, g + 1.0, g + 2.0); + } + { + vec4 b[2] = { vec4(1.0), vec4(1.0) }; + vec4[3][2](b, b, b); // constructor + vec4[][2](b, b, b); // constructor, valid, size deduced + vec4[3][](b, b, b); // compile-time error, invalid type constructed + } +} diff --git a/Test/versionsClean.frag b/Test/versionsClean.frag new file mode 100644 index 00000000..187ffb6c --- /dev/null +++ b/Test/versionsClean.frag @@ -0,0 +1,45 @@ +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of LunarG Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +#version 300 es + +in vec3 color; +out vec4 foo; + +uniform sampler2DRect bar; + +void main() +{ + foo = vec4(color, 142.0f); + discard; +} diff --git a/Test/versionsClean.vert b/Test/versionsClean.vert new file mode 100644 index 00000000..7c197857 --- /dev/null +++ b/Test/versionsClean.vert @@ -0,0 +1,43 @@ +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of LunarG Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +#version 420 compatibility + +attribute vec3 color; + +uniform sampler2DRect foo; + +void main() +{ + gl_Position = vec4(color, 142.0f); +} diff --git a/Test/versionsErrors.frag b/Test/versionsErrors.frag new file mode 100644 index 00000000..021c7356 --- /dev/null +++ b/Test/versionsErrors.frag @@ -0,0 +1,46 @@ +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of LunarG Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +#version 110 es + +#extension GL_ARB_texture_rectangle : disable + +attribute vec3 color; + +uniform sampler2DRect foo; + +void main() +{ + gl_FragColor = vec4(color, 142.0f); + discard; +} diff --git a/Test/versionsErrors.vert b/Test/versionsErrors.vert new file mode 100644 index 00000000..8736f2e7 --- /dev/null +++ b/Test/versionsErrors.vert @@ -0,0 +1,46 @@ +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of LunarG Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +#version 420 core + +#extension GL_ARB_texture_rectangle : enable + +attribute vec3 color; + +uniform sampler2DRect foo; + +void main() +{ + gl_Position = vec4(color, 142.0f); + discard; +} diff --git a/Todo.txt b/Todo.txt new file mode 100644 index 00000000..8d003d69 --- /dev/null +++ b/Todo.txt @@ -0,0 +1,16 @@ +Minor "to do" items are identified in the source code with "TODO..." comments. + +Major items to do: + +* Use the new versioning infrastructure to identify all errors specific to + - profile + - extension + - version + - stage + +* Add semantics for all new grammar (1.2 through 4.3) + +* Replace the preprocessor with a better one. + +* Verify/fix thread safety of the parse context. + diff --git a/glslang.vcproj b/glslang.vcproj deleted file mode 100644 index a1fdc9a6..00000000 --- a/glslang.vcproj +++ /dev/null @@ -1,436 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/glslang.vcxproj b/glslang.vcxproj new file mode 100644 index 00000000..555ddf1e --- /dev/null +++ b/glslang.vcxproj @@ -0,0 +1,250 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + glslang + {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3} + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + glslang\UserM_Debug\ + glslang\UserM_Debug\ + false + UserM_Release\ + UserM_Release\ + false + + + + Disabled + glslang;glslang\MachineIndependent;glslang\OSDependent\Windows;OGLCompilersDLL;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;_USRDLL;TEST_EXPORTS;GENERIC_COMPILER;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + + + $(IntDir) + $(IntDir) + $(IntDir) + + + Level3 + true + ProgramDatabase + FastCall + Default + + + /MACHINE:I386 %(AdditionalOptions) + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + false + libcmtd.lib;libcd.lib;libcmt.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + UserM_Debug/glslang.pdb + Console + UserM_Debug/generic/glslang.lib + $(IntDir)$(TargetName)$(TargetExt) + + + UserM_Debug/generic/glslang.tlb + + + copy dll + del Test\$(TargetName)$(TargetExt) +xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + + + MaxSpeed + OnlyExplicitInline + true + glslang;glslang\MachineIndependent;glslang\OSDependent\Windows;OGLCompilersDLL;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;_USRDLL;TEST_EXPORTS;GENERIC_COMPILER;%(PreprocessorDefinitions) + true + false + Default + MultiThreadedDLL + true + true + + + UserM_Release/ + UserM_Release/ + UserM_Release/glslang + + + Level3 + true + ProgramDatabase + FastCall + Default + + + /MACHINE:I386 %(AdditionalOptions) + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UserM_Release/generic/glslang.dll + true + libcmtd.lib;libcd.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + UserM_Release/generic/glslang.pdb + Console + true + true + UserM_Release/generic/glslang.lib + + + UserM_Release/generic/glslang.tlb + + + copy dll + xcopy /y UserM_Release\generic\glslang.* StandAlone + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(IntDir)%(Filename)1.obj + true + $(IntDir)%(Filename)1.obj + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document + Executing Bison on glslang.y + SET BISON_SIMPLE=%(RootDir)%(Directory)..\..\tools\bison.simple +SET BISON_HAIRY=%(RootDir)%(Directory)..\..\tools\bison.simple +cd %(RootDir)%(Directory) +%(RootDir)%(Directory)..\..\tools\bison.exe -d -t glslang.y -o glslang_tab.cpp + + %(RootDir)%(Directory)glslang_tab.cpp;%(RootDir)%(Directory)glslang_tab.cpp.h + Executing Bison on %(FullPath) + SET BISON_SIMPLE=%(RootDir)%(Directory)..\..\tools\bison.simple +SET BISON_HAIRY=%(RootDir)%(Directory)..\..\tools\bison.simple +cd %(RootDir)%(Directory) +%(RootDir)%(Directory)..\..\tools\bison.exe -d -t -v %(Filename).y +if EXIST %(RootDir)%(Directory)Gen_%(Filename)_tab.cpp del %(RootDir)%(Directory)Gen_%(Filename)_tab.cpp +rename %(RootDir)%(Directory)%(Filename)_tab.c Gen_%(Filename)_tab.cpp + + %(RootDir)%(Directory)Gen_%(Filename)_tab.cpp;%(Outputs) + + + + + Document + cd %(RootDir)%(Directory) +%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l + + Executing flex on glslang.l + %(RootDir)%(Directory)gen_glslang.cpp + %(RootDir)%(Directory)glslang_tab.cpp.h + + + + + + \ No newline at end of file diff --git a/glslang.vcxproj.filters b/glslang.vcxproj.filters new file mode 100644 index 00000000..00f33d8a --- /dev/null +++ b/glslang.vcxproj.filters @@ -0,0 +1,234 @@ + + + + + {593f06dd-7981-4cb7-91ba-eae633fa547e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;y;l + + + {564543b5-6302-49ab-9d24-bd6bef91274a} + + + {5d320e20-4d64-4db1-9d8c-e7fdc234be36} + + + {d4faa328-f693-4b77-9fcb-9629ca0d8ee8} + + + {c79e7f4d-1836-4b72-b201-46e72e4e4b6b} + + + {b56dd525-2a9c-4ae5-a6b4-d024e624c6b4} + + + {d48b8f48-5784-4cb6-bead-7f98647a1c44} + + + {092b92ee-743a-407d-ad9b-92af399715d6} + + + {0c27903f-6ef2-4725-9d9c-70f50aeaa7a1} + + + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Generic Code Gen + + + Generic Code Gen + + + OSDependent\Windows + + + OSDependent\Windows + + + OSDependent\Linux + + + Machine Independent\Generated Source + + + Machine Independent\Generated Source + + + Machine Independent + + + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Machine Independent\CPP + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Public + + + OSDependent\Windows + + + OSDependent\Linux + + + Machine Independent\Generated Source + + + Machine Independent + + + + + Machine Independent + + + Machine Independent + + + \ No newline at end of file diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f2c77535..05575a09 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -739,8 +739,8 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) return true; } - if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects")) - return true; + if (type.qualifier == EvqConst) + profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array"); return false; } @@ -948,20 +948,6 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TType* type) } } -bool TParseContext::extensionErrorCheck(int line, const char* extension) -{ - if (extensionBehavior[extension] == EBhWarn) { - infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line); - return false; - } - if (extensionBehavior[extension] == EBhDisable) { - error(line, "extension", extension, "is disabled"); - return true; - } - - return false; -} - ///////////////////////////////////////////////////////////////////////////////// // // Non-Errors. @@ -1448,7 +1434,7 @@ void TParseContext::initializeExtensionBehavior() // example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of // supported extension // - extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire; + extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable; extensionBehavior["GL_3DL_array_objects"] = EBhDisable; } @@ -1457,7 +1443,7 @@ OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX; bool InitializeParseContextIndex() { if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); + assert(0 && "InitializeParseContextIndex(): Parse Context already initialised"); return false; } @@ -1467,7 +1453,7 @@ bool InitializeParseContextIndex() GlobalParseContextIndex = OS_AllocTLSIndex(); if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); + assert(0 && "InitializeParseContextIndex(): Parse Context already initialised"); return false; } @@ -1477,13 +1463,13 @@ bool InitializeParseContextIndex() bool InitializeGlobalParseContext() { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised"); + assert(0 && "InitializeGlobalParseContext(): Parse Context index not initialized"); return false; } TThreadParseContext *lpParseContext = static_cast(OS_GetTLSValue(GlobalParseContextIndex)); if (lpParseContext != 0) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); + assert(0 && "InitializeParseContextIndex(): Parse Context already initialized"); return false; } @@ -1513,7 +1499,7 @@ TParseContextPointer& GetGlobalParseContext() bool FreeParseContext() { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "FreeParseContext(): Parse Context index not initalised"); + assert(0 && "FreeParseContext(): Parse Context index not initialized"); return false; } @@ -1529,7 +1515,7 @@ bool FreeParseContextIndex() OS_TLSIndex tlsiIndex = GlobalParseContextIndex; if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "FreeParseContextIndex(): Parse Context index not initalised"); + assert(0 && "FreeParseContextIndex(): Parse Context index not initialized"); return false; } diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 704d3e47..3e1a125b 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -2,6 +2,8 @@ //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. //All rights reserved. // +//Copyright (C) 2012 LunarG, Inc. +// //Redistribution and use in source and binary forms, with or without //modification, are permitted provided that the following conditions //are met: @@ -34,6 +36,7 @@ #ifndef _PARSER_HELPER_INCLUDED_ #define _PARSER_HELPER_INCLUDED_ +#include "Versions.h" #include "../Include/ShHandle.h" #include "SymbolTable.h" #include "localintermediate.h" @@ -67,8 +70,9 @@ struct TParseContext { TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) : intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0), - switchNestingLevel(0), - inTypeParen(false), contextPragma(true, false) { } + switchNestingLevel(0), inTypeParen(false), + version(110), profile(ENoProfile), futureCompatibility(false), + contextPragma(true, false) { } TIntermediate& intermediate; // to hold and build a parse tree TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed TInfoSink& infoSink; @@ -82,7 +86,16 @@ struct TParseContext { bool inTypeParen; // true if in parentheses, looking only for an identifier 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 - TMap extensionBehavior; + + int version; // the declared version in the shader (110 by default) + EProfile profile; // the declared profile in the shader (core by default) + bool futureCompatibility; // true if requesting errors for future compatibility (false by default) + TMap extensionBehavior; // for each extension string, what it's current enablement is + + struct TPragma contextPragma; + TString HashErrMsg; + bool AfterEOF; + void initializeExtensionBehavior(); void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, @@ -117,7 +130,6 @@ struct TParseContext { bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type); bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type); bool paramErrorCheck(int line, TQualifier qualifier, TType* type); - bool extensionErrorCheck(int line, const char*); const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); @@ -131,9 +143,12 @@ struct TParseContext { TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line); TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); - struct TPragma contextPragma; - TString HashErrMsg; - bool AfterEOF; + void requireProfile(int line, EProfileMask profileMask, const char *featureDesc); + void requireStage(int line, EShLanguageMask languageMask, const char *featureDesc); + void profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc); + void profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc); + void checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc); + void requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc); }; int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&); diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 5d932d18..f38f856f 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -282,6 +282,8 @@ int ShCompile( GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage()); + // TODO: this is happening *after* initialization, which already parsed some things... what parse context was that? + // what extensions did it have? TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink); parseContext.initializeExtensionBehavior(); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp new file mode 100644 index 00000000..c1341b70 --- /dev/null +++ b/glslang/MachineIndependent/Versions.cpp @@ -0,0 +1,161 @@ +// +//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +//All rights reserved. +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// + +// +// Help manage multiple profiles, versions, extensions etc. +// +// These don't return error codes, as the presumption is parsing +// will always continue as if the feature were present, and there +// is no error recovery needed to enable that. +// + +#include "ParseHelper.h" + +char* StageName[EShLangCount] = { + "vertex", + "tessellation control", + "tessellation evaluation", + "geometry", + "fragment" +}; + +char* ProfileName[EProfileCount] = { + "none", + "core", + "compatibility", + "es" +}; + +// +// If only some profiles support a feature, use requireProfile() to specify +// which subset allows the feature. If the current profile is not present, +// give an error message. +// +void TParseContext::requireProfile(int line, EProfileMask profileMask, const char *featureDesc) +{ + if (((1 << profile) & profileMask) == 0) { + error(line, "not supported with this profile:", featureDesc, ProfileName[profile]); + recover(); + } +} + +// +// If only some stages support a feature, use requireStage() to specify +// which subset allows the feature. If the current stage is not present, +// give an error message. +// +void TParseContext::requireStage(int line, EShLanguageMask languageMask, const char *featureDesc) +{ + if (((1 << language) & languageMask) == 0) { + error(line, "not supported in this stage:", featureDesc, StageName[language]); + recover(); + } +} + +// +// Within a profile, if a feature requires a version level or extension, use +// ProfileRequires(). This only checks if the current profile matches +// the passed-in profile. +// + +// one that takes multiple extensions +void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc) +{ + if (profile == callingProfile) { + bool okay = false; + if (version >= minVersion) + okay = true; + for (int i = 0; i < numExtensions; ++i) { + TBehavior behavior = extensionBehavior[extensions[i]]; + switch (behavior) { + case EBhWarn: + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), line); + // fall through + case EBhRequire: + case EBhEnable: + okay = true; + break; + } + } + + if (! okay) { + error(line, "not supported for this version or the enabled extensions", featureDesc, ""); + recover(); + } + } +} + +// one that takes a single extension +void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc) +{ + profileRequires(line, callingProfile, minVersion, 1, &extension, featureDesc); +} + +// +// Within a profile, see if a feature is deprecated and error or warn based on whether +// a future compatibility context is being use. +// +void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc) +{ + if (profile == callingProfile) { + if (version >= depVersion) { + if (futureCompatibility) { + error(line, "deprecated, may be removed in future release", featureDesc, ""); + recover(); + } else { + infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " being used, but may be removed in future release").c_str(), line); + } + } + } +} + +// +// Within a profile, see if a feature has now been removed and if so, give an error. +// The version argument is the first version no longer having the feature. +// +void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc) +{ + if (profile == callingProfile) { + if (version >= removedVersion) { + const int maxSize = 60; + char buf[maxSize]; + sprintf_s(buf, maxSize, "%s profile; removed in version %d", ProfileName[profile], removedVersion); + error(line, "no longer supported in", featureDesc, buf); + recover(); + } + } +} diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h new file mode 100644 index 00000000..11dde5b3 --- /dev/null +++ b/glslang/MachineIndependent/Versions.h @@ -0,0 +1,59 @@ +// +//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +//All rights reserved. +// +//Copyright (C) 2012 LunarG, Inc. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +#ifndef _VERSIONS_INCLUDED_ +#define _VERSIONS_INCLUDED_ + +// +// Help manage multiple profiles, versions, extensions etc. +// + +typedef enum { + ENoProfile, // only for desktop, before profiles showed up + ECoreProfile, + ECompatibilityProfile, + EEsProfile, + EProfileCount, +} EProfile; + +typedef enum { + ENoProfileMask = (1 << ENoProfile), + ECoreProfileMask = (1 << ECoreProfile), + ECompatibilityProfileMask = (1 << ECompatibilityProfile), + EEsProfileMask = (1 << EEsProfile) +} EProfileMask; + +#endif // _VERSIONS_INCLUDED_ diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index 771d22c3..25ad9759 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -3,6 +3,8 @@ //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. //All rights reserved. // +//Copyright (C) 2012 LunarG, Inc. +// //Redistribution and use in source and binary forms, with or without //modification, are permitted provided that the following conditions //are met: @@ -568,7 +570,7 @@ void CPPShInfoLogMsg(const char *msg) void CPPErrorToInfoLog(char *msg) { - ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,""); + ((TParseContext *)cpp->pC)->error(yylineno, "CPP error:", "",msg,""); GlobalParseContext->recover(); } @@ -708,6 +710,48 @@ void ResetTString(void) ((TParseContext *)cpp->pC)->HashErrMsg = ""; } +void SetVersion(int version) +{ + ((TParseContext *)cpp->pC)->version = version; +} + +const int FirstProfileVersion = 150; + +// Important assumption: SetVersion() is called before SetProfile(), and is always called +// if there is a version, sending in a ENoProfile if there is no profile given. +void SetProfile(EProfile profile) +{ + int version = ((TParseContext *)cpp->pC)->version; + + if (profile == ENoProfile) { + if (version == 100 || version == 300) { + CPPErrorToInfoLog("versions 100 and 300 require specifying the es profile"); + ((TParseContext *)cpp->pC)->profile = ENoProfile; + } else if (version >= FirstProfileVersion) + ((TParseContext *)cpp->pC)->profile = ECoreProfile; + else + ((TParseContext *)cpp->pC)->profile = ENoProfile; + } else { + // a profile was provided... + if (version == 100 || version == 300) { + if (profile != EEsProfile) + CPPErrorToInfoLog("versions 100 and 300 only support the es profile"); + ((TParseContext *)cpp->pC)->profile = EEsProfile; + } else { + if (profile == EEsProfile) { + CPPErrorToInfoLog("only versions 100 and 300 support the es profile"); + if (version >= FirstProfileVersion) + ((TParseContext *)cpp->pC)->profile = ECoreProfile; + else + ((TParseContext *)cpp->pC)->profile = ENoProfile; + } else { + // typical desktop case... e.g., "#version 410 core" + ((TParseContext *)cpp->pC)->profile = profile; + } + } + } +} + TBehavior GetBehavior(const char* behavior) { if (!strcmp("require", behavior)) diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index e1f9fd6c..4d004fc6 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -2,6 +2,8 @@ //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. //All rights reserved. // +//Copyright (C) 2012 LunarG, Inc. +// //Redistribution and use in source and binary forms, with or without //modification, are permitted provided that the following conditions //are met: @@ -70,20 +72,6 @@ Jutta Degener, 1995 extern void yyerror(char*); #endif -#define VERTEX_ONLY(S, L) { \ - if (parseContext.language != EShLangVertex) { \ - parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define FRAG_ONLY(S, L) { \ - if (parseContext.language != EShLangFragment) { \ - parseContext.error(L, " supported in fragment shaders only ", S, "", "");\ - parseContext.recover(); \ - } \ -} - %} %union { struct { @@ -384,12 +372,8 @@ postfix_expression // TODO: if next token is not "(", then this is an error if (*$3.string == "length") { - if (parseContext.extensionErrorCheck($3.line, "GL_3DL_array_objects")) { - parseContext.recover(); - $$ = $1; - } else { - $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line); - } + parseContext.profileRequires($3.line, ENoProfile, 120, "GL_3DL_array_objects", ".length"); + $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line); } else { parseContext.error($3.line, "only the length method is supported for array", $3.string->c_str(), ""); parseContext.recover(); @@ -695,10 +679,7 @@ function_identifier $$.intermNode = 0; if ($1.array) { - if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) { - parseContext.recover(); - $1.setArray(false); - } + parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array"); } if ($1.userDef) { @@ -966,8 +947,8 @@ equality_expression constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); - } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects")) - parseContext.recover(); + } else if (($1->isArray() || $3->isArray())) + parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "=="); } | equality_expression NE_OP relational_expression { $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext.symbolTable); @@ -977,8 +958,8 @@ equality_expression constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); - } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects")) - parseContext.recover(); + } else if (($1->isArray() || $3->isArray())) + parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "!="); } ; @@ -1088,8 +1069,8 @@ assignment_expression parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString()); parseContext.recover(); $$ = $1; - } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects")) - parseContext.recover(); + } else if (($1->isArray() || $3->isArray())) + parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "="); } ; @@ -1394,22 +1375,20 @@ init_declarator_list parseContext.recover(); } - if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects")) + parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); + + TIntermNode* intermNode; + if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $6, intermNode, variable)) { + // + // build the intermediate representation + // + if (intermNode) + $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.line); + else + $$.intermAggregate = $1.intermAggregate; + } else { parseContext.recover(); - else { - TIntermNode* intermNode; - if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $6, intermNode, variable)) { - // - // build the intermediate representation - // - if (intermNode) - $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.line); - else - $$.intermAggregate = $1.intermAggregate; - } else { - parseContext.recover(); - $$.intermAggregate = 0; - } + $$.intermAggregate = 0; } } | init_declarator_list COMMA IDENTIFIER EQUAL initializer { @@ -1492,22 +1471,20 @@ single_declaration parseContext.recover(); } - if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects")) - parseContext.recover(); - else { - TIntermNode* intermNode; - if (!parseContext.executeInitializer($2.line, *$2.string, $1, $5, intermNode, variable)) { - // - // Build intermediate representation - // - if (intermNode) - $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.line); - else - $$.intermAggregate = 0; - } else { - parseContext.recover(); + parseContext.profileRequires($4.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); + + TIntermNode* intermNode; + if (!parseContext.executeInitializer($2.line, *$2.string, $1, $5, intermNode, variable)) { + // + // Build intermediate representation + // + if (intermNode) + $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.line); + else $$.intermAggregate = 0; - } + } else { + parseContext.recover(); + $$.intermAggregate = 0; } } | fully_specified_type IDENTIFIER EQUAL initializer { @@ -1538,17 +1515,13 @@ fully_specified_type $$ = $1; if ($1.array) { - if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) { - parseContext.recover(); - $1.setArray(false); - } + parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array"); } } | type_qualifier type_specifier { - if ($2.array && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects")) { - parseContext.recover(); - $2.setArray(false); - } + if ($2.array) + parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array"); + if ($2.array && parseContext.arrayQualifierErrorCheck($2.line, $1)) { parseContext.recover(); $2.setArray(false); @@ -1661,12 +1634,15 @@ storage_qualifier $$.setBasic(EbtVoid, EvqConst, $1.line); } | ATTRIBUTE { - VERTEX_ONLY("attribute", $1.line); + //parseContext.requireProfile($1.line, (EProfileMask)(ENoProfileMask | ECompatibilityProfileMask), "attribute"); + parseContext.requireStage($1.line, EShLangVertexMask, "attribute"); + parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "attribute"); if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute")) parseContext.recover(); $$.setBasic(EbtVoid, EvqAttribute, $1.line); } | VARYING { + parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying"); if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying")) parseContext.recover(); if (parseContext.language == EShLangVertex) @@ -2162,29 +2138,25 @@ type_specifier_nonarray $$.setBasic(EbtSampler2DShadow, qual, $1.line); } | SAMPLER2DRECT { - if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) - parseContext.recover(); + parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerRect, qual, $1.line); } | SAMPLER2DRECTSHADOW { - if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) - parseContext.recover(); + parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerRectShadow, qual, $1.line); } | ISAMPLER2DRECT { - if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) - parseContext.recover(); + parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerRect, qual, $1.line); } | USAMPLER2DRECT { - if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) - parseContext.recover(); + parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerRect, qual, $1.line); @@ -2760,7 +2732,7 @@ jump_statement } } | DISCARD SEMICOLON { - FRAG_ONLY("discard", $1.line); + parseContext.requireStage($1.line, EShLangFragmentMask, "discard"); $$ = parseContext.intermediate.addBranch(EOpKill, $1.line); } ; diff --git a/glslang/MachineIndependent/preprocessor/compile.h b/glslang/MachineIndependent/preprocessor/compile.h index 140a2159..08a92808 100644 --- a/glslang/MachineIndependent/preprocessor/compile.h +++ b/glslang/MachineIndependent/preprocessor/compile.h @@ -127,10 +127,6 @@ struct CPPStruct_Rec { int PaArgc; // count of strings in the array char** PaArgv; // our array of strings to parse unsigned int tokensBeforeEOF : 1; - - // Declared version of the shader - int version; - int profileAtom; }; #endif // !defined(__COMPILE_H) diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c index 72837050..83bb4b3a 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.c +++ b/glslang/MachineIndependent/preprocessor/cpp.c @@ -685,18 +685,22 @@ static int CPPversion(yystypepp * yylvalpp) yylvalpp->sc_int=atoi(yylvalpp->symbol_name); - cpp->version = yylvalpp->sc_int; + SetVersion(yylvalpp->sc_int); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - if (token == '\n'){ + if (token == '\n') { + SetProfile(ENoProfile); return token; } - else{ - cpp->profileAtom = yylvalpp->sc_ident; - if (cpp->profileAtom != coreAtom && - cpp->profileAtom != compatibilityAtom && - cpp->profileAtom != esAtom) + else { + if (yylvalpp->sc_ident == coreAtom) + SetProfile(ECoreProfile); + else if (yylvalpp->sc_ident == compatibilityAtom) + SetProfile(ECompatibilityProfile); + else if (yylvalpp->sc_ident == esAtom) + SetProfile(EEsProfile); + else CPPErrorToInfoLog("#version profile name"); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); diff --git a/glslang/MachineIndependent/preprocessor/cpp.h b/glslang/MachineIndependent/preprocessor/cpp.h index 10ecd123..f7195cda 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.h +++ b/glslang/MachineIndependent/preprocessor/cpp.h @@ -83,6 +83,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "parser.h" #include "tokens.h" +#include "Versions.h" int InitCPP(void); int FinalCPP(void); @@ -113,6 +114,8 @@ void SetStringNumber(int); // Set string number. int GetLineNumber(void); // Get the current String Number. int GetStringNumber(void); // Get the current String Number. const char* GetStrfromTStr(void); // Convert TString to String. +void SetVersion(int); +void SetProfile(EProfile); void updateExtensionBehavior(const char* extName, const char* behavior); int FreeCPP(void); diff --git a/glslang/MachineIndependent/preprocessor/cppstruct.c b/glslang/MachineIndependent/preprocessor/cppstruct.c index c924dc24..b1b15fa0 100644 --- a/glslang/MachineIndependent/preprocessor/cppstruct.c +++ b/glslang/MachineIndependent/preprocessor/cppstruct.c @@ -132,8 +132,6 @@ int ResetPreprocessor(void) cpp->elsedepth[cpp->elsetracker]=0; cpp->elsetracker=0; cpp->tokensBeforeEOF = 0; - cpp->version = 110; - cpp->profileAtom = 0; return 1; } diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 96e35d42..c4b69844 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -71,10 +71,23 @@ SH_IMPORT_EXPORT int __fastcall ShFinalize(); // typedef enum { EShLangVertex, + EShLangTessControl, + EShLangTessEvaluation, + EShLangGeometry, EShLangFragment, EShLangCount, } EShLanguage; +typedef enum { + EShLangVertexMask = (1 << EShLangVertex), + EShLangTessControlMask = (1 << EShLangTessControl), + EShLangTessEvaluationMask = (1 << EShLangTessEvaluation), + EShLangGeometryMask = (1 << EShLangGeometry), + EShLangFragmentMask = (1 << EShLangFragment), +} EShLanguageMask; + +extern char* StageName[EShLangCount]; + // // Types of output the linker will create. //