| // |
| //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. |
| //Copyright (C) 2012-2013 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. |
| // |
| |
| // |
| // Create strings that declare built-in definitions, add built-ins programmatically |
| // that cannot be expressed in the strings, and establish mappings between |
| // built-in functions and operators. |
| // |
| // Where to put a built-in: |
| // TBuiltIns::initialize(version,profile) context-independent textual built-ins; add them to the right string |
| // TBuiltIns::initialize(resources,...) context-dependent textual built-ins; add them to the right string |
| // IdentifyBuiltIns(...,symbolTable) context-independent programmatic additions/mappings to the symbol table, |
| // including identifying what extensions are needed if a version does not allow a symbol |
| // IdentifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the symbol table, |
| // including identifying what extensions are needed if a version does not allow a symbol |
| // |
| |
| #include "../Include/intermediate.h" |
| #include "Initialize.h" |
| |
| namespace glslang { |
| |
| // TODO: ARB_Compatability: do full extension support |
| bool ARBCompatibility = true; |
| |
| const bool ForwardCompatibility = false; |
| |
| // change this back to false if depending on textual spellings of texturing calls when consuming the AST |
| // Using PureOperatorBuiltins=false is deprecated. |
| bool PureOperatorBuiltins = true; |
| |
| inline bool IncludeLegacy(int version, EProfile profile) |
| { |
| return profile != EEsProfile && (version <= 130 || ARBCompatibility || profile == ECompatibilityProfile); |
| } |
| |
| TBuiltIns::TBuiltIns() |
| { |
| // Set up textual representations for making all the permutations |
| // of texturing/imaging functions. |
| prefixes[EbtFloat] = ""; |
| prefixes[EbtInt] = "i"; |
| prefixes[EbtUint] = "u"; |
| postfixes[2] = "2"; |
| postfixes[3] = "3"; |
| postfixes[4] = "4"; |
| |
| // Map from symbolic class of texturing dimension to numeric dimensions. |
| dimMap[Esd1D] = 1; |
| dimMap[Esd2D] = 2; |
| dimMap[EsdRect] = 2; |
| dimMap[Esd3D] = 3; |
| dimMap[EsdCube] = 3; |
| dimMap[EsdBuffer] = 1; |
| } |
| |
| TBuiltIns::~TBuiltIns() |
| { |
| } |
| |
| // |
| // Add all context-independent built-in functions and variables that are present |
| // for the given version and profile. Share common ones across stages, otherwise |
| // make stage-specific entries. |
| // |
| // Most built-ins variables can be added as simple text strings. Some need to |
| // be added programmatically, which is done later in IdentifyBuiltIns() below. |
| // |
| void TBuiltIns::initialize(int version, EProfile profile) |
| { |
| //============================================================================ |
| // |
| // Prototypes for built-in functions seen by both vertex and fragment shaders. |
| // |
| //============================================================================ |
| |
| // |
| // Angle and Trigonometric Functions. |
| // |
| commonBuiltins.append( |
| "float radians(float degrees);" |
| "vec2 radians(vec2 degrees);" |
| "vec3 radians(vec3 degrees);" |
| "vec4 radians(vec4 degrees);" |
| |
| "float degrees(float radians);" |
| "vec2 degrees(vec2 radians);" |
| "vec3 degrees(vec3 radians);" |
| "vec4 degrees(vec4 radians);" |
| |
| "float sin(float angle);" |
| "vec2 sin(vec2 angle);" |
| "vec3 sin(vec3 angle);" |
| "vec4 sin(vec4 angle);" |
| |
| "float cos(float angle);" |
| "vec2 cos(vec2 angle);" |
| "vec3 cos(vec3 angle);" |
| "vec4 cos(vec4 angle);" |
| |
| "float tan(float angle);" |
| "vec2 tan(vec2 angle);" |
| "vec3 tan(vec3 angle);" |
| "vec4 tan(vec4 angle);" |
| |
| "float asin(float x);" |
| "vec2 asin(vec2 x);" |
| "vec3 asin(vec3 x);" |
| "vec4 asin(vec4 x);" |
| |
| "float acos(float x);" |
| "vec2 acos(vec2 x);" |
| "vec3 acos(vec3 x);" |
| "vec4 acos(vec4 x);" |
| |
| "float atan(float y, float x);" |
| "vec2 atan(vec2 y, vec2 x);" |
| "vec3 atan(vec3 y, vec3 x);" |
| "vec4 atan(vec4 y, vec4 x);" |
| |
| "float atan(float y_over_x);" |
| "vec2 atan(vec2 y_over_x);" |
| "vec3 atan(vec3 y_over_x);" |
| "vec4 atan(vec4 y_over_x);" |
| |
| "\n"); |
| |
| if (version >= 130) { |
| commonBuiltins.append( |
| "float sinh(float angle);" |
| "vec2 sinh(vec2 angle);" |
| "vec3 sinh(vec3 angle);" |
| "vec4 sinh(vec4 angle);" |
| |
| "float cosh(float angle);" |
| "vec2 cosh(vec2 angle);" |
| "vec3 cosh(vec3 angle);" |
| "vec4 cosh(vec4 angle);" |
| |
| "float tanh(float angle);" |
| "vec2 tanh(vec2 angle);" |
| "vec3 tanh(vec3 angle);" |
| "vec4 tanh(vec4 angle);" |
| |
| "float asinh(float x);" |
| "vec2 asinh(vec2 x);" |
| "vec3 asinh(vec3 x);" |
| "vec4 asinh(vec4 x);" |
| |
| "float acosh(float x);" |
| "vec2 acosh(vec2 x);" |
| "vec3 acosh(vec3 x);" |
| "vec4 acosh(vec4 x);" |
| |
| "float atanh(float y_over_x);" |
| "vec2 atanh(vec2 y_over_x);" |
| "vec3 atanh(vec3 y_over_x);" |
| "vec4 atanh(vec4 y_over_x);" |
| |
| "\n"); |
| } |
| |
| // |
| // Exponential Functions. |
| // |
| commonBuiltins.append( |
| "float pow(float x, float y);" |
| "vec2 pow(vec2 x, vec2 y);" |
| "vec3 pow(vec3 x, vec3 y);" |
| "vec4 pow(vec4 x, vec4 y);" |
| |
| "float exp(float x);" |
| "vec2 exp(vec2 x);" |
| "vec3 exp(vec3 x);" |
| "vec4 exp(vec4 x);" |
| |
| "float log(float x);" |
| "vec2 log(vec2 x);" |
| "vec3 log(vec3 x);" |
| "vec4 log(vec4 x);" |
| |
| "float exp2(float x);" |
| "vec2 exp2(vec2 x);" |
| "vec3 exp2(vec3 x);" |
| "vec4 exp2(vec4 x);" |
| |
| "float log2(float x);" |
| "vec2 log2(vec2 x);" |
| "vec3 log2(vec3 x);" |
| "vec4 log2(vec4 x);" |
| |
| "float sqrt(float x);" |
| "vec2 sqrt(vec2 x);" |
| "vec3 sqrt(vec3 x);" |
| "vec4 sqrt(vec4 x);" |
| |
| "float inversesqrt(float x);" |
| "vec2 inversesqrt(vec2 x);" |
| "vec3 inversesqrt(vec3 x);" |
| "vec4 inversesqrt(vec4 x);" |
| |
| "\n"); |
| |
| // |
| // Common Functions. |
| // |
| commonBuiltins.append( |
| "float abs(float x);" |
| "vec2 abs(vec2 x);" |
| "vec3 abs(vec3 x);" |
| "vec4 abs(vec4 x);" |
| |
| "float sign(float x);" |
| "vec2 sign(vec2 x);" |
| "vec3 sign(vec3 x);" |
| "vec4 sign(vec4 x);" |
| |
| "float floor(float x);" |
| "vec2 floor(vec2 x);" |
| "vec3 floor(vec3 x);" |
| "vec4 floor(vec4 x);" |
| |
| "float ceil(float x);" |
| "vec2 ceil(vec2 x);" |
| "vec3 ceil(vec3 x);" |
| "vec4 ceil(vec4 x);" |
| |
| "float fract(float x);" |
| "vec2 fract(vec2 x);" |
| "vec3 fract(vec3 x);" |
| "vec4 fract(vec4 x);" |
| |
| "float mod(float x, float y);" |
| "vec2 mod(vec2 x, float y);" |
| "vec3 mod(vec3 x, float y);" |
| "vec4 mod(vec4 x, float y);" |
| "vec2 mod(vec2 x, vec2 y);" |
| "vec3 mod(vec3 x, vec3 y);" |
| "vec4 mod(vec4 x, vec4 y);" |
| |
| "float min(float x, float y);" |
| "vec2 min(vec2 x, float y);" |
| "vec3 min(vec3 x, float y);" |
| "vec4 min(vec4 x, float y);" |
| "vec2 min(vec2 x, vec2 y);" |
| "vec3 min(vec3 x, vec3 y);" |
| "vec4 min(vec4 x, vec4 y);" |
| |
| "float max(float x, float y);" |
| "vec2 max(vec2 x, float y);" |
| "vec3 max(vec3 x, float y);" |
| "vec4 max(vec4 x, float y);" |
| "vec2 max(vec2 x, vec2 y);" |
| "vec3 max(vec3 x, vec3 y);" |
| "vec4 max(vec4 x, vec4 y);" |
| |
| "float clamp(float x, float minVal, float maxVal);" |
| "vec2 clamp(vec2 x, float minVal, float maxVal);" |
| "vec3 clamp(vec3 x, float minVal, float maxVal);" |
| "vec4 clamp(vec4 x, float minVal, float maxVal);" |
| "vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);" |
| "vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);" |
| "vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);" |
| |
| "float mix(float x, float y, float a);" |
| "vec2 mix(vec2 x, vec2 y, float a);" |
| "vec3 mix(vec3 x, vec3 y, float a);" |
| "vec4 mix(vec4 x, vec4 y, float a);" |
| "vec2 mix(vec2 x, vec2 y, vec2 a);" |
| "vec3 mix(vec3 x, vec3 y, vec3 a);" |
| "vec4 mix(vec4 x, vec4 y, vec4 a);" |
| |
| "float step(float edge, float x);" |
| "vec2 step(vec2 edge, vec2 x);" |
| "vec3 step(vec3 edge, vec3 x);" |
| "vec4 step(vec4 edge, vec4 x);" |
| "vec2 step(float edge, vec2 x);" |
| "vec3 step(float edge, vec3 x);" |
| "vec4 step(float edge, vec4 x);" |
| |
| "float smoothstep(float edge0, float edge1, float x);" |
| "vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);" |
| "vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);" |
| "vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);" |
| "vec2 smoothstep(float edge0, float edge1, vec2 x);" |
| "vec3 smoothstep(float edge0, float edge1, vec3 x);" |
| "vec4 smoothstep(float edge0, float edge1, vec4 x);" |
| |
| "\n"); |
| |
| if (version >= 130) { |
| commonBuiltins.append( |
| " int abs( int x);" |
| "ivec2 abs(ivec2 x);" |
| "ivec3 abs(ivec3 x);" |
| "ivec4 abs(ivec4 x);" |
| |
| " int sign( int x);" |
| "ivec2 sign(ivec2 x);" |
| "ivec3 sign(ivec3 x);" |
| "ivec4 sign(ivec4 x);" |
| |
| "float trunc(float x);" |
| "vec2 trunc(vec2 x);" |
| "vec3 trunc(vec3 x);" |
| "vec4 trunc(vec4 x);" |
| |
| "float round(float x);" |
| "vec2 round(vec2 x);" |
| "vec3 round(vec3 x);" |
| "vec4 round(vec4 x);" |
| |
| "float roundEven(float x);" |
| "vec2 roundEven(vec2 x);" |
| "vec3 roundEven(vec3 x);" |
| "vec4 roundEven(vec4 x);" |
| |
| "float modf(float, out float);" |
| "vec2 modf(vec2, out vec2 );" |
| "vec3 modf(vec3, out vec3 );" |
| "vec4 modf(vec4, out vec4 );" |
| |
| " int min(int x, int y);" |
| "ivec2 min(ivec2 x, int y);" |
| "ivec3 min(ivec3 x, int y);" |
| "ivec4 min(ivec4 x, int y);" |
| "ivec2 min(ivec2 x, ivec2 y);" |
| "ivec3 min(ivec3 x, ivec3 y);" |
| "ivec4 min(ivec4 x, ivec4 y);" |
| |
| " uint min(uint x, uint y);" |
| "uvec2 min(uvec2 x, uint y);" |
| "uvec3 min(uvec3 x, uint y);" |
| "uvec4 min(uvec4 x, uint y);" |
| "uvec2 min(uvec2 x, uvec2 y);" |
| "uvec3 min(uvec3 x, uvec3 y);" |
| "uvec4 min(uvec4 x, uvec4 y);" |
| |
| " int max(int x, int y);" |
| "ivec2 max(ivec2 x, int y);" |
| "ivec3 max(ivec3 x, int y);" |
| "ivec4 max(ivec4 x, int y);" |
| "ivec2 max(ivec2 x, ivec2 y);" |
| "ivec3 max(ivec3 x, ivec3 y);" |
| "ivec4 max(ivec4 x, ivec4 y);" |
| |
| " uint max(uint x, uint y);" |
| "uvec2 max(uvec2 x, uint y);" |
| "uvec3 max(uvec3 x, uint y);" |
| "uvec4 max(uvec4 x, uint y);" |
| "uvec2 max(uvec2 x, uvec2 y);" |
| "uvec3 max(uvec3 x, uvec3 y);" |
| "uvec4 max(uvec4 x, uvec4 y);" |
| |
| "int clamp(int x, int minVal, int maxVal);" |
| "ivec2 clamp(ivec2 x, int minVal, int maxVal);" |
| "ivec3 clamp(ivec3 x, int minVal, int maxVal);" |
| "ivec4 clamp(ivec4 x, int minVal, int maxVal);" |
| "ivec2 clamp(ivec2 x, ivec2 minVal, ivec2 maxVal);" |
| "ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal);" |
| "ivec4 clamp(ivec4 x, ivec4 minVal, ivec4 maxVal);" |
| |
| "uint clamp(uint x, uint minVal, uint maxVal);" |
| "uvec2 clamp(uvec2 x, uint minVal, uint maxVal);" |
| "uvec3 clamp(uvec3 x, uint minVal, uint maxVal);" |
| "uvec4 clamp(uvec4 x, uint minVal, uint maxVal);" |
| "uvec2 clamp(uvec2 x, uvec2 minVal, uvec2 maxVal);" |
| "uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal);" |
| "uvec4 clamp(uvec4 x, uvec4 minVal, uvec4 maxVal);" |
| |
| "float mix(float x, float y, bool a);" |
| "vec2 mix(vec2 x, vec2 y, bvec2 a);" |
| "vec3 mix(vec3 x, vec3 y, bvec3 a);" |
| "vec4 mix(vec4 x, vec4 y, bvec4 a);" |
| |
| "bool isnan(float x);" |
| "bvec2 isnan(vec2 x);" |
| "bvec3 isnan(vec3 x);" |
| "bvec4 isnan(vec4 x);" |
| |
| "bool isinf(float x);" |
| "bvec2 isinf(vec2 x);" |
| "bvec3 isinf(vec3 x);" |
| "bvec4 isinf(vec4 x);" |
| |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 430)) { |
| commonBuiltins.append( |
| "uint atomicAdd(coherent volatile inout uint, uint);" |
| " int atomicAdd(coherent volatile inout int, int);" |
| |
| "uint atomicMin(coherent volatile inout uint, uint);" |
| " int atomicMin(coherent volatile inout int, int);" |
| |
| "uint atomicMax(coherent volatile inout uint, uint);" |
| " int atomicMax(coherent volatile inout int, int);" |
| |
| "uint atomicAnd(coherent volatile inout uint, uint);" |
| " int atomicAnd(coherent volatile inout int, int);" |
| |
| "uint atomicOr (coherent volatile inout uint, uint);" |
| " int atomicOr (coherent volatile inout int, int);" |
| |
| "uint atomicXor(coherent volatile inout uint, uint);" |
| " int atomicXor(coherent volatile inout int, int);" |
| |
| "uint atomicExchange(coherent volatile inout uint, uint);" |
| " int atomicExchange(coherent volatile inout int, int);" |
| |
| "uint atomicCompSwap(coherent volatile inout uint, uint, uint);" |
| " int atomicCompSwap(coherent volatile inout int, int, int);" |
| |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 450)) { |
| commonBuiltins.append( |
| "int mix(int x, int y, bool a);" |
| "ivec2 mix(ivec2 x, ivec2 y, bvec2 a);" |
| "ivec3 mix(ivec3 x, ivec3 y, bvec3 a);" |
| "ivec4 mix(ivec4 x, ivec4 y, bvec4 a);" |
| |
| "uint mix(uint x, uint y, bool a);" |
| "uvec2 mix(uvec2 x, uvec2 y, bvec2 a);" |
| "uvec3 mix(uvec3 x, uvec3 y, bvec3 a);" |
| "uvec4 mix(uvec4 x, uvec4 y, bvec4 a);" |
| |
| "bool mix(bool x, bool y, bool a);" |
| "bvec2 mix(bvec2 x, bvec2 y, bvec2 a);" |
| "bvec3 mix(bvec3 x, bvec3 y, bvec3 a);" |
| "bvec4 mix(bvec4 x, bvec4 y, bvec4 a);" |
| |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 300) || |
| (profile != EEsProfile && version >= 330)) { |
| commonBuiltins.append( |
| "int floatBitsToInt(float value);" |
| "ivec2 floatBitsToInt(vec2 value);" |
| "ivec3 floatBitsToInt(vec3 value);" |
| "ivec4 floatBitsToInt(vec4 value);" |
| |
| "uint floatBitsToUint(float value);" |
| "uvec2 floatBitsToUint(vec2 value);" |
| "uvec3 floatBitsToUint(vec3 value);" |
| "uvec4 floatBitsToUint(vec4 value);" |
| |
| "float intBitsToFloat(int value);" |
| "vec2 intBitsToFloat(ivec2 value);" |
| "vec3 intBitsToFloat(ivec3 value);" |
| "vec4 intBitsToFloat(ivec4 value);" |
| |
| "float uintBitsToFloat(uint value);" |
| "vec2 uintBitsToFloat(uvec2 value);" |
| "vec3 uintBitsToFloat(uvec3 value);" |
| "vec4 uintBitsToFloat(uvec4 value);" |
| |
| "\n"); |
| } |
| |
| if ((profile != EEsProfile && version >= 400) || |
| (profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5 |
| |
| commonBuiltins.append( |
| "float fma(float, float, float );" |
| "vec2 fma(vec2, vec2, vec2 );" |
| "vec3 fma(vec3, vec3, vec3 );" |
| "vec4 fma(vec4, vec4, vec4 );" |
| "\n"); |
| |
| if (profile != EEsProfile) { |
| commonBuiltins.append( |
| "double fma(double, double, double);" |
| "dvec2 fma(dvec2, dvec2, dvec2 );" |
| "dvec3 fma(dvec3, dvec3, dvec3 );" |
| "dvec4 fma(dvec4, dvec4, dvec4 );" |
| "\n"); |
| } |
| } |
| |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 400)) { |
| commonBuiltins.append( |
| "highp float frexp(highp float, out highp int);" |
| "highp vec2 frexp(highp vec2, out highp ivec2);" |
| "highp vec3 frexp(highp vec3, out highp ivec3);" |
| "highp vec4 frexp(highp vec4, out highp ivec4);" |
| |
| "highp float ldexp(highp float, highp int);" |
| "highp vec2 ldexp(highp vec2, highp ivec2);" |
| "highp vec3 ldexp(highp vec3, highp ivec3);" |
| "highp vec4 ldexp(highp vec4, highp ivec4);" |
| |
| "\n"); |
| } |
| |
| if (profile != EEsProfile && version >= 400) { |
| commonBuiltins.append( |
| "double frexp(double, out int);" |
| "dvec2 frexp( dvec2, out ivec2);" |
| "dvec3 frexp( dvec3, out ivec3);" |
| "dvec4 frexp( dvec4, out ivec4);" |
| |
| "double ldexp(double, int);" |
| "dvec2 ldexp( dvec2, ivec2);" |
| "dvec3 ldexp( dvec3, ivec3);" |
| "dvec4 ldexp( dvec4, ivec4);" |
| |
| "double packDouble2x32(uvec2);" |
| "uvec2 unpackDouble2x32(double);" |
| |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 300) || |
| (profile != EEsProfile && version >= 400)) { |
| commonBuiltins.append( |
| "highp uint packUnorm2x16(vec2);" |
| "highp vec2 unpackUnorm2x16(highp uint);" |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 300) || |
| (profile != EEsProfile && version >= 420)) { |
| commonBuiltins.append( |
| "highp uint packSnorm2x16(vec2);" |
| "highp vec2 unpackSnorm2x16(highp uint);" |
| "highp uint packHalf2x16(mediump vec2);" |
| "mediump vec2 unpackHalf2x16(highp uint);" |
| "\n"); |
| } |
| |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 400)) { |
| commonBuiltins.append( |
| "highp uint packSnorm4x8 (mediump vec4);" |
| "mediump vec4 unpackSnorm4x8(highp uint);" |
| "highp uint packUnorm4x8 (mediump vec4);" |
| "mediump vec4 unpackUnorm4x8(highp uint);" |
| "\n"); |
| } |
| |
| // |
| // Geometric Functions. |
| // |
| commonBuiltins.append( |
| "float length(float x);" |
| "float length(vec2 x);" |
| "float length(vec3 x);" |
| "float length(vec4 x);" |
| |
| "float distance(float p0, float p1);" |
| "float distance(vec2 p0, vec2 p1);" |
| "float distance(vec3 p0, vec3 p1);" |
| "float distance(vec4 p0, vec4 p1);" |
| |
| "float dot(float x, float y);" |
| "float dot(vec2 x, vec2 y);" |
| "float dot(vec3 x, vec3 y);" |
| "float dot(vec4 x, vec4 y);" |
| |
| "vec3 cross(vec3 x, vec3 y);" |
| "float normalize(float x);" |
| "vec2 normalize(vec2 x);" |
| "vec3 normalize(vec3 x);" |
| "vec4 normalize(vec4 x);" |
| |
| "float faceforward(float N, float I, float Nref);" |
| "vec2 faceforward(vec2 N, vec2 I, vec2 Nref);" |
| "vec3 faceforward(vec3 N, vec3 I, vec3 Nref);" |
| "vec4 faceforward(vec4 N, vec4 I, vec4 Nref);" |
| |
| "float reflect(float I, float N);" |
| "vec2 reflect(vec2 I, vec2 N);" |
| "vec3 reflect(vec3 I, vec3 N);" |
| "vec4 reflect(vec4 I, vec4 N);" |
| |
| "float refract(float I, float N, float eta);" |
| "vec2 refract(vec2 I, vec2 N, float eta);" |
| "vec3 refract(vec3 I, vec3 N, float eta);" |
| "vec4 refract(vec4 I, vec4 N, float eta);" |
| |
| "\n"); |
| |
| // |
| // Matrix Functions. |
| // |
| commonBuiltins.append( |
| "mat2 matrixCompMult(mat2 x, mat2 y);" |
| "mat3 matrixCompMult(mat3 x, mat3 y);" |
| "mat4 matrixCompMult(mat4 x, mat4 y);" |
| |
| "\n"); |
| |
| // 120 is correct for both ES and desktop |
| if (version >= 120) { |
| commonBuiltins.append( |
| "mat2 outerProduct(vec2 c, vec2 r);" |
| "mat3 outerProduct(vec3 c, vec3 r);" |
| "mat4 outerProduct(vec4 c, vec4 r);" |
| "mat2x3 outerProduct(vec3 c, vec2 r);" |
| "mat3x2 outerProduct(vec2 c, vec3 r);" |
| "mat2x4 outerProduct(vec4 c, vec2 r);" |
| "mat4x2 outerProduct(vec2 c, vec4 r);" |
| "mat3x4 outerProduct(vec4 c, vec3 r);" |
| "mat4x3 outerProduct(vec3 c, vec4 r);" |
| |
| "mat2 transpose(mat2 m);" |
| "mat3 transpose(mat3 m);" |
| "mat4 transpose(mat4 m);" |
| "mat2x3 transpose(mat3x2 m);" |
| "mat3x2 transpose(mat2x3 m);" |
| "mat2x4 transpose(mat4x2 m);" |
| "mat4x2 transpose(mat2x4 m);" |
| "mat3x4 transpose(mat4x3 m);" |
| "mat4x3 transpose(mat3x4 m);" |
| |
| "mat2x3 matrixCompMult(mat2x3, mat2x3);" |
| "mat2x4 matrixCompMult(mat2x4, mat2x4);" |
| "mat3x2 matrixCompMult(mat3x2, mat3x2);" |
| "mat3x4 matrixCompMult(mat3x4, mat3x4);" |
| "mat4x2 matrixCompMult(mat4x2, mat4x2);" |
| "mat4x3 matrixCompMult(mat4x3, mat4x3);" |
| |
| "\n"); |
| |
| // 150 is correct for both ES and desktop |
| if (version >= 150) { |
| commonBuiltins.append( |
| "float determinant(mat2 m);" |
| "float determinant(mat3 m);" |
| "float determinant(mat4 m);" |
| |
| "mat2 inverse(mat2 m);" |
| "mat3 inverse(mat3 m);" |
| "mat4 inverse(mat4 m);" |
| |
| "\n"); |
| } |
| } |
| |
| // |
| // Vector relational functions. |
| // |
| commonBuiltins.append( |
| "bvec2 lessThan(vec2 x, vec2 y);" |
| "bvec3 lessThan(vec3 x, vec3 y);" |
| "bvec4 lessThan(vec4 x, vec4 y);" |
| |
| "bvec2 lessThan(ivec2 x, ivec2 y);" |
| "bvec3 lessThan(ivec3 x, ivec3 y);" |
| "bvec4 lessThan(ivec4 x, ivec4 y);" |
| |
| "bvec2 lessThanEqual(vec2 x, vec2 y);" |
| "bvec3 lessThanEqual(vec3 x, vec3 y);" |
| "bvec4 lessThanEqual(vec4 x, vec4 y);" |
| |
| "bvec2 lessThanEqual(ivec2 x, ivec2 y);" |
| "bvec3 lessThanEqual(ivec3 x, ivec3 y);" |
| "bvec4 lessThanEqual(ivec4 x, ivec4 y);" |
| |
| "bvec2 greaterThan(vec2 x, vec2 y);" |
| "bvec3 greaterThan(vec3 x, vec3 y);" |
| "bvec4 greaterThan(vec4 x, vec4 y);" |
| |
| "bvec2 greaterThan(ivec2 x, ivec2 y);" |
| "bvec3 greaterThan(ivec3 x, ivec3 y);" |
| "bvec4 greaterThan(ivec4 x, ivec4 y);" |
| |
| "bvec2 greaterThanEqual(vec2 x, vec2 y);" |
| "bvec3 greaterThanEqual(vec3 x, vec3 y);" |
| "bvec4 greaterThanEqual(vec4 x, vec4 y);" |
| |
| "bvec2 greaterThanEqual(ivec2 x, ivec2 y);" |
| "bvec3 greaterThanEqual(ivec3 x, ivec3 y);" |
| "bvec4 greaterThanEqual(ivec4 x, ivec4 y);" |
| |
| "bvec2 equal(vec2 x, vec2 y);" |
| "bvec3 equal(vec3 x, vec3 y);" |
| "bvec4 equal(vec4 x, vec4 y);" |
| |
| "bvec2 equal(ivec2 x, ivec2 y);" |
| "bvec3 equal(ivec3 x, ivec3 y);" |
| "bvec4 equal(ivec4 x, ivec4 y);" |
| |
| "bvec2 equal(bvec2 x, bvec2 y);" |
| "bvec3 equal(bvec3 x, bvec3 y);" |
| "bvec4 equal(bvec4 x, bvec4 y);" |
| |
| "bvec2 notEqual(vec2 x, vec2 y);" |
| "bvec3 notEqual(vec3 x, vec3 y);" |
| "bvec4 notEqual(vec4 x, vec4 y);" |
| |
| "bvec2 notEqual(ivec2 x, ivec2 y);" |
| "bvec3 notEqual(ivec3 x, ivec3 y);" |
| "bvec4 notEqual(ivec4 x, ivec4 y);" |
| |
| "bvec2 notEqual(bvec2 x, bvec2 y);" |
| "bvec3 notEqual(bvec3 x, bvec3 y);" |
| "bvec4 notEqual(bvec4 x, bvec4 y);" |
| |
| "bool any(bvec2 x);" |
| "bool any(bvec3 x);" |
| "bool any(bvec4 x);" |
| |
| "bool all(bvec2 x);" |
| "bool all(bvec3 x);" |
| "bool all(bvec4 x);" |
| |
| "bvec2 not(bvec2 x);" |
| "bvec3 not(bvec3 x);" |
| "bvec4 not(bvec4 x);" |
| |
| "\n"); |
| |
| if (version >= 130) { |
| commonBuiltins.append( |
| "bvec2 lessThan(uvec2 x, uvec2 y);" |
| "bvec3 lessThan(uvec3 x, uvec3 y);" |
| "bvec4 lessThan(uvec4 x, uvec4 y);" |
| |
| "bvec2 lessThanEqual(uvec2 x, uvec2 y);" |
| "bvec3 lessThanEqual(uvec3 x, uvec3 y);" |
| "bvec4 lessThanEqual(uvec4 x, uvec4 y);" |
| |
| "bvec2 greaterThan(uvec2 x, uvec2 y);" |
| "bvec3 greaterThan(uvec3 x, uvec3 y);" |
| "bvec4 greaterThan(uvec4 x, uvec4 y);" |
| |
| "bvec2 greaterThanEqual(uvec2 x, uvec2 y);" |
| "bvec3 greaterThanEqual(uvec3 x, uvec3 y);" |
| "bvec4 greaterThanEqual(uvec4 x, uvec4 y);" |
| |
| "bvec2 equal(uvec2 x, uvec2 y);" |
| "bvec3 equal(uvec3 x, uvec3 y);" |
| "bvec4 equal(uvec4 x, uvec4 y);" |
| |
| "bvec2 notEqual(uvec2 x, uvec2 y);" |
| "bvec3 notEqual(uvec3 x, uvec3 y);" |
| "bvec4 notEqual(uvec4 x, uvec4 y);" |
| |
| "\n"); |
| } |
| |
| // |
| // Original-style texture functions existing in all stages. |
| // (Per-stage functions below.) |
| // |
| if ((profile == EEsProfile && version == 100) || |
| profile == ECompatibilityProfile || |
| (profile == ECoreProfile && version < 420) || |
| profile == ENoProfile) { |
| commonBuiltins.append( |
| "vec4 texture2D(sampler2D, vec2);" |
| |
| "vec4 texture2DProj(sampler2D, vec3);" |
| "vec4 texture2DProj(sampler2D, vec4);" |
| |
| "vec4 texture3D(sampler3D, vec3);" // OES_texture_3D, but caught by keyword check |
| "vec4 texture3DProj(sampler3D, vec4);" // OES_texture_3D, but caught by keyword check |
| |
| "vec4 textureCube(samplerCube, vec3);" |
| |
| "\n"); |
| } |
| |
| if ( profile == ECompatibilityProfile || |
| (profile == ECoreProfile && version < 420) || |
| profile == ENoProfile) { |
| commonBuiltins.append( |
| "vec4 texture1D(sampler1D, float);" |
| |
| "vec4 texture1DProj(sampler1D, vec2);" |
| "vec4 texture1DProj(sampler1D, vec4);" |
| |
| "vec4 shadow1D(sampler1DShadow, vec3);" |
| "vec4 shadow2D(sampler2DShadow, vec3);" |
| "vec4 shadow1DProj(sampler1DShadow, vec4);" |
| "vec4 shadow2DProj(sampler2DShadow, vec4);" |
| |
| "vec4 texture2DRect(sampler2DRect, vec2);" // GL_ARB_texture_rectangle, caught by keyword check |
| "vec4 texture2DRectProj(sampler2DRect, vec3);" // GL_ARB_texture_rectangle, caught by keyword check |
| "vec4 texture2DRectProj(sampler2DRect, vec4);" // GL_ARB_texture_rectangle, caught by keyword check |
| "vec4 shadow2DRect(sampler2DRectShadow, vec3);" // GL_ARB_texture_rectangle, caught by keyword check |
| "vec4 shadow2DRectProj(sampler2DRectShadow, vec4);" // GL_ARB_texture_rectangle, caught by keyword check |
| |
| "\n"); |
| } |
| |
| if (profile == EEsProfile) { |
| commonBuiltins.append( |
| "vec4 texture2D(samplerExternalOES, vec2 coord);" // GL_OES_EGL_image_external, caught by keyword check |
| "vec4 texture2DProj(samplerExternalOES, vec3);" // GL_OES_EGL_image_external, caught by keyword check |
| "vec4 texture2DProj(samplerExternalOES, vec4);" // GL_OES_EGL_image_external, caught by keyword check |
| "vec4 texture2DGradEXT(sampler2D, vec2, vec2, vec2);" // GL_EXT_shader_texture_lod |
| "vec4 texture2DProjGradEXT(sampler2D, vec3, vec2, vec2);" // GL_EXT_shader_texture_lod |
| "vec4 texture2DProjGradEXT(sampler2D, vec4, vec2, vec2);" // GL_EXT_shader_texture_lod |
| "vec4 textureCubeGradEXT(samplerCube, vec3, vec3, vec3);" // GL_EXT_shader_texture_lod |
| |
| "\n"); |
| } |
| |
| // |
| // Noise functions. |
| // |
| if (profile != EEsProfile) { |
| commonBuiltins.append( |
| "float noise1(float x);" |
| "float noise1(vec2 x);" |
| "float noise1(vec3 x);" |
| "float noise1(vec4 x);" |
| |
| "vec2 noise2(float x);" |
| "vec2 noise2(vec2 x);" |
| "vec2 noise2(vec3 x);" |
| "vec2 noise2(vec4 x);" |
| |
| "vec3 noise3(float x);" |
| "vec3 noise3(vec2 x);" |
| "vec3 noise3(vec3 x);" |
| "vec3 noise3(vec4 x);" |
| |
| "vec4 noise4(float x);" |
| "vec4 noise4(vec2 x);" |
| "vec4 noise4(vec3 x);" |
| "vec4 noise4(vec4 x);" |
| |
| "\n"); |
| } |
| |
| // |
| // Atomic counter functions. |
| // |
| if ((profile != EEsProfile && version >= 300) || |
| (profile == EEsProfile && version >= 310)) { |
| commonBuiltins.append( |
| "uint atomicCounterIncrement(atomic_uint x);" |
| "uint atomicCounterDecrement(atomic_uint x);" |
| "uint atomicCounter(atomic_uint x);" |
| |
| "\n"); |
| } |
| |
| // Bitfield |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 400)) { |
| commonBuiltins.append( |
| " uint uaddCarry( uint, uint, out uint carry);" |
| "uvec2 uaddCarry(uvec2, uvec2, out uvec2 carry);" |
| "uvec3 uaddCarry(uvec3, uvec3, out uvec3 carry);" |
| "uvec4 uaddCarry(uvec4, uvec4, out uvec4 carry);" |
| |
| " uint usubBorrow( uint, uint, out uint borrow);" |
| "uvec2 usubBorrow(uvec2, uvec2, out uvec2 borrow);" |
| "uvec3 usubBorrow(uvec3, uvec3, out uvec3 borrow);" |
| "uvec4 usubBorrow(uvec4, uvec4, out uvec4 borrow);" |
| |
| "void umulExtended( uint, uint, out uint, out uint lsb);" |
| "void umulExtended(uvec2, uvec2, out uvec2, out uvec2 lsb);" |
| "void umulExtended(uvec3, uvec3, out uvec3, out uvec3 lsb);" |
| "void umulExtended(uvec4, uvec4, out uvec4, out uvec4 lsb);" |
| |
| "void imulExtended( int, int, out int, out int lsb);" |
| "void imulExtended(ivec2, ivec2, out ivec2, out ivec2 lsb);" |
| "void imulExtended(ivec3, ivec3, out ivec3, out ivec3 lsb);" |
| "void imulExtended(ivec4, ivec4, out ivec4, out ivec4 lsb);" |
| |
| " int bitfieldExtract( int, int, int);" |
| "ivec2 bitfieldExtract(ivec2, int, int);" |
| "ivec3 bitfieldExtract(ivec3, int, int);" |
| "ivec4 bitfieldExtract(ivec4, int, int);" |
| |
| " uint bitfieldExtract( uint, int, int);" |
| "uvec2 bitfieldExtract(uvec2, int, int);" |
| "uvec3 bitfieldExtract(uvec3, int, int);" |
| "uvec4 bitfieldExtract(uvec4, int, int);" |
| |
| " int bitfieldInsert( int base, int, int, int);" |
| "ivec2 bitfieldInsert(ivec2 base, ivec2, int, int);" |
| "ivec3 bitfieldInsert(ivec3 base, ivec3, int, int);" |
| "ivec4 bitfieldInsert(ivec4 base, ivec4, int, int);" |
| |
| " uint bitfieldInsert( uint base, uint, int, int);" |
| "uvec2 bitfieldInsert(uvec2 base, uvec2, int, int);" |
| "uvec3 bitfieldInsert(uvec3 base, uvec3, int, int);" |
| "uvec4 bitfieldInsert(uvec4 base, uvec4, int, int);" |
| |
| " int bitfieldReverse( int);" |
| "ivec2 bitfieldReverse(ivec2);" |
| "ivec3 bitfieldReverse(ivec3);" |
| "ivec4 bitfieldReverse(ivec4);" |
| |
| " uint bitfieldReverse( uint);" |
| "uvec2 bitfieldReverse(uvec2);" |
| "uvec3 bitfieldReverse(uvec3);" |
| "uvec4 bitfieldReverse(uvec4);" |
| |
| " int bitCount( int);" |
| "ivec2 bitCount(ivec2);" |
| "ivec3 bitCount(ivec3);" |
| "ivec4 bitCount(ivec4);" |
| |
| " int bitCount( uint);" |
| "ivec2 bitCount(uvec2);" |
| "ivec3 bitCount(uvec3);" |
| "ivec4 bitCount(uvec4);" |
| |
| " int findLSB( int);" |
| "ivec2 findLSB(ivec2);" |
| "ivec3 findLSB(ivec3);" |
| "ivec4 findLSB(ivec4);" |
| |
| " int findLSB( uint);" |
| "ivec2 findLSB(uvec2);" |
| "ivec3 findLSB(uvec3);" |
| "ivec4 findLSB(uvec4);" |
| |
| " int findMSB( int);" |
| "ivec2 findMSB(ivec2);" |
| "ivec3 findMSB(ivec3);" |
| "ivec4 findMSB(ivec4);" |
| |
| " int findMSB( uint);" |
| "ivec2 findMSB(uvec2);" |
| "ivec3 findMSB(uvec3);" |
| "ivec4 findMSB(uvec4);" |
| |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Prototypes for built-in functions seen by vertex shaders only. |
| // (Except legacy lod functions, where it depends which release they are |
| // vertex only.) |
| // |
| //============================================================================ |
| |
| // |
| // Geometric Functions. |
| // |
| if (IncludeLegacy(version, profile)) |
| stageBuiltins[EShLangVertex].append("vec4 ftransform();"); |
| |
| // |
| // Original-style texture Functions with lod. |
| // |
| TString* s; |
| if (version == 100) |
| s = &stageBuiltins[EShLangVertex]; |
| else |
| s = &commonBuiltins; |
| if ((profile == EEsProfile && version == 100) || |
| profile == ECompatibilityProfile || |
| (profile == ECoreProfile && version < 420) || |
| profile == ENoProfile) { |
| s->append( |
| "vec4 texture2DLod(sampler2D, vec2, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DProjLod(sampler2D, vec3, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DProjLod(sampler2D, vec4, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture3DLod(sampler3D, vec3, float);" // GL_ARB_shader_texture_lod // OES_texture_3D, but caught by keyword check |
| "vec4 texture3DProjLod(sampler3D, vec4, float);" // GL_ARB_shader_texture_lod // OES_texture_3D, but caught by keyword check |
| "vec4 textureCubeLod(samplerCube, vec3, float);" // GL_ARB_shader_texture_lod |
| |
| "\n"); |
| } |
| if ( profile == ECompatibilityProfile || |
| (profile == ECoreProfile && version < 420) || |
| profile == ENoProfile) { |
| s->append( |
| "vec4 texture1DLod(sampler1D, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture1DProjLod(sampler1D, vec2, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture1DProjLod(sampler1D, vec4, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow1DLod(sampler1DShadow, vec3, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DLod(sampler2DShadow, vec3, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow1DProjLod(sampler1DShadow, vec4, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DProjLod(sampler2DShadow, vec4, float);" // GL_ARB_shader_texture_lod |
| |
| "vec4 texture1DGradARB(sampler1D, float, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture1DProjGradARB(sampler1D, vec2, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture1DProjGradARB(sampler1D, vec4, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DGradARB(sampler2D, vec2, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DProjGradARB(sampler2D, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DProjGradARB(sampler2D, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture3DGradARB(sampler3D, vec3, vec3, vec3);" // GL_ARB_shader_texture_lod |
| "vec4 texture3DProjGradARB(sampler3D, vec4, vec3, vec3);" // GL_ARB_shader_texture_lod |
| "vec4 textureCubeGradARB(samplerCube, vec3, vec3, vec3);" // GL_ARB_shader_texture_lod |
| "vec4 shadow1DGradARB(sampler1DShadow, vec3, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow1DProjGradARB( sampler1DShadow, vec4, float, float);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DGradARB(sampler2DShadow, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DProjGradARB( sampler2DShadow, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DRectGradARB(sampler2DRect, vec2, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DRectProjGradARB( sampler2DRect, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 texture2DRectProjGradARB( sampler2DRect, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DRectGradARB( sampler2DRectShadow, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod |
| "vec4 shadow2DRectProjGradARB(sampler2DRectShadow, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod |
| |
| "\n"); |
| } |
| |
| if ((profile != EEsProfile && version >= 150) || |
| (profile == EEsProfile && version >= 310)) { |
| //============================================================================ |
| // |
| // Prototypes for built-in functions seen by geometry shaders only. |
| // |
| //============================================================================ |
| |
| if (profile != EEsProfile && version >= 400) { |
| stageBuiltins[EShLangGeometry].append( |
| "void EmitStreamVertex(int);" |
| "void EndStreamPrimitive(int);" |
| ); |
| } |
| stageBuiltins[EShLangGeometry].append( |
| "void EmitVertex();" |
| "void EndPrimitive();" |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Prototypes for all control functions. |
| // |
| //============================================================================ |
| bool esBarrier = (profile == EEsProfile && version >= 310); |
| if ((profile != EEsProfile && version >= 150) || esBarrier) |
| stageBuiltins[EShLangTessControl].append( |
| "void barrier();" |
| ); |
| if ((profile != EEsProfile && version >= 430) || esBarrier) |
| stageBuiltins[EShLangCompute].append( |
| "void barrier();" |
| ); |
| if ((profile != EEsProfile && version >= 130) || esBarrier) |
| commonBuiltins.append( |
| "void memoryBarrier();" |
| ); |
| if ((profile != EEsProfile && version >= 430) || esBarrier) { |
| commonBuiltins.append( |
| "void memoryBarrierAtomicCounter();" |
| "void memoryBarrierBuffer();" |
| "void memoryBarrierImage();" |
| ); |
| stageBuiltins[EShLangCompute].append( |
| "void memoryBarrierShared();" |
| "void groupMemoryBarrier();" |
| ); |
| } |
| |
| //============================================================================ |
| // |
| // Prototypes for built-in functions seen by fragment shaders only. |
| // |
| //============================================================================ |
| |
| // |
| // Original-style texture Functions with bias. |
| // |
| if (profile != EEsProfile || version == 100) { |
| stageBuiltins[EShLangFragment].append( |
| "vec4 texture2D(sampler2D, vec2, float);" |
| "vec4 texture2DProj(sampler2D, vec3, float);" |
| "vec4 texture2DProj(sampler2D, vec4, float);" |
| "vec4 texture3D(sampler3D, vec3, float);" // OES_texture_3D |
| "vec4 texture3DProj(sampler3D, vec4, float);" // OES_texture_3D |
| "vec4 textureCube(samplerCube, vec3, float);" |
| |
| "\n"); |
| } |
| if (profile != EEsProfile && version > 100) { |
| stageBuiltins[EShLangFragment].append( |
| "vec4 texture1D(sampler1D, float, float);" |
| "vec4 texture1DProj(sampler1D, vec2, float);" |
| "vec4 texture1DProj(sampler1D, vec4, float);" |
| "vec4 shadow1D(sampler1DShadow, vec3, float);" |
| "vec4 shadow2D(sampler2DShadow, vec3, float);" |
| "vec4 shadow1DProj(sampler1DShadow, vec4, float);" |
| "vec4 shadow2DProj(sampler2DShadow, vec4, float);" |
| |
| "\n"); |
| } |
| if (profile == EEsProfile) { |
| stageBuiltins[EShLangFragment].append( |
| "vec4 texture2DLodEXT(sampler2D, vec2, float);" // GL_EXT_shader_texture_lod |
| "vec4 texture2DProjLodEXT(sampler2D, vec3, float);" // GL_EXT_shader_texture_lod |
| "vec4 texture2DProjLodEXT(sampler2D, vec4, float);" // GL_EXT_shader_texture_lod |
| "vec4 textureCubeLodEXT(samplerCube, vec3, float);" // GL_EXT_shader_texture_lod |
| |
| "\n"); |
| } |
| |
| stageBuiltins[EShLangFragment].append( |
| "float dFdx(float p);" |
| "vec2 dFdx(vec2 p);" |
| "vec3 dFdx(vec3 p);" |
| "vec4 dFdx(vec4 p);" |
| |
| "float dFdy(float p);" |
| "vec2 dFdy(vec2 p);" |
| "vec3 dFdy(vec3 p);" |
| "vec4 dFdy(vec4 p);" |
| |
| "float fwidth(float p);" |
| "vec2 fwidth(vec2 p);" |
| "vec3 fwidth(vec3 p);" |
| "vec4 fwidth(vec4 p);" |
| |
| "\n"); |
| |
| // GL_ARB_derivative_control |
| if (profile != EEsProfile && version >= 400) { |
| stageBuiltins[EShLangFragment].append( |
| "float dFdxFine(float p);" |
| "vec2 dFdxFine(vec2 p);" |
| "vec3 dFdxFine(vec3 p);" |
| "vec4 dFdxFine(vec4 p);" |
| |
| "float dFdyFine(float p);" |
| "vec2 dFdyFine(vec2 p);" |
| "vec3 dFdyFine(vec3 p);" |
| "vec4 dFdyFine(vec4 p);" |
| |
| "float fwidthFine(float p);" |
| "vec2 fwidthFine(vec2 p);" |
| "vec3 fwidthFine(vec3 p);" |
| "vec4 fwidthFine(vec4 p);" |
| |
| "\n"); |
| |
| stageBuiltins[EShLangFragment].append( |
| "float dFdxCoarse(float p);" |
| "vec2 dFdxCoarse(vec2 p);" |
| "vec3 dFdxCoarse(vec3 p);" |
| "vec4 dFdxCoarse(vec4 p);" |
| |
| "float dFdyCoarse(float p);" |
| "vec2 dFdyCoarse(vec2 p);" |
| "vec3 dFdyCoarse(vec3 p);" |
| "vec4 dFdyCoarse(vec4 p);" |
| |
| "float fwidthCoarse(float p);" |
| "vec2 fwidthCoarse(vec2 p);" |
| "vec3 fwidthCoarse(vec3 p);" |
| "vec4 fwidthCoarse(vec4 p);" |
| |
| "\n"); |
| } |
| |
| // GL_OES_shader_multisample_interpolation |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 400)) { |
| stageBuiltins[EShLangFragment].append( |
| "float interpolateAtCentroid(float);" |
| "vec2 interpolateAtCentroid(vec2);" |
| "vec3 interpolateAtCentroid(vec3);" |
| "vec4 interpolateAtCentroid(vec4);" |
| |
| "float interpolateAtSample(float, int);" |
| "vec2 interpolateAtSample(vec2, int);" |
| "vec3 interpolateAtSample(vec3, int);" |
| "vec4 interpolateAtSample(vec4, int);" |
| |
| "float interpolateAtOffset(float, vec2);" |
| "vec2 interpolateAtOffset(vec2, vec2);" |
| "vec3 interpolateAtOffset(vec3, vec2);" |
| "vec4 interpolateAtOffset(vec4, vec2);" |
| |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Standard Uniforms |
| // |
| //============================================================================ |
| |
| // |
| // Depth range in window coordinates, p. 33 |
| // |
| commonBuiltins.append( |
| "struct gl_DepthRangeParameters {" |
| ); |
| if (profile == EEsProfile) { |
| commonBuiltins.append( |
| "highp float near;" // n |
| "highp float far;" // f |
| "highp float diff;" // f - n |
| ); |
| } else { |
| commonBuiltins.append( |
| "float near;" // n |
| "float far;" // f |
| "float diff;" // f - n |
| ); |
| } |
| commonBuiltins.append( |
| "};" |
| "uniform gl_DepthRangeParameters gl_DepthRange;" |
| "\n"); |
| |
| if (IncludeLegacy(version, profile)) { |
| // |
| // Matrix state. p. 31, 32, 37, 39, 40. |
| // |
| commonBuiltins.append( |
| "uniform mat4 gl_ModelViewMatrix;" |
| "uniform mat4 gl_ProjectionMatrix;" |
| "uniform mat4 gl_ModelViewProjectionMatrix;" |
| |
| // |
| // Derived matrix state that provides inverse and transposed versions |
| // of the matrices above. |
| // |
| "uniform mat3 gl_NormalMatrix;" |
| |
| "uniform mat4 gl_ModelViewMatrixInverse;" |
| "uniform mat4 gl_ProjectionMatrixInverse;" |
| "uniform mat4 gl_ModelViewProjectionMatrixInverse;" |
| |
| "uniform mat4 gl_ModelViewMatrixTranspose;" |
| "uniform mat4 gl_ProjectionMatrixTranspose;" |
| "uniform mat4 gl_ModelViewProjectionMatrixTranspose;" |
| |
| "uniform mat4 gl_ModelViewMatrixInverseTranspose;" |
| "uniform mat4 gl_ProjectionMatrixInverseTranspose;" |
| "uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;" |
| |
| // |
| // Normal scaling p. 39. |
| // |
| "uniform float gl_NormalScale;" |
| |
| // |
| // Point Size, p. 66, 67. |
| // |
| "struct gl_PointParameters {" |
| "float size;" |
| "float sizeMin;" |
| "float sizeMax;" |
| "float fadeThresholdSize;" |
| "float distanceConstantAttenuation;" |
| "float distanceLinearAttenuation;" |
| "float distanceQuadraticAttenuation;" |
| "};" |
| |
| "uniform gl_PointParameters gl_Point;" |
| |
| // |
| // Material State p. 50, 55. |
| // |
| "struct gl_MaterialParameters {" |
| "vec4 emission;" // Ecm |
| "vec4 ambient;" // Acm |
| "vec4 diffuse;" // Dcm |
| "vec4 specular;" // Scm |
| "float shininess;" // Srm |
| "};" |
| "uniform gl_MaterialParameters gl_FrontMaterial;" |
| "uniform gl_MaterialParameters gl_BackMaterial;" |
| |
| // |
| // Light State p 50, 53, 55. |
| // |
| "struct gl_LightSourceParameters {" |
| "vec4 ambient;" // Acli |
| "vec4 diffuse;" // Dcli |
| "vec4 specular;" // Scli |
| "vec4 position;" // Ppli |
| "vec4 halfVector;" // Derived: Hi |
| "vec3 spotDirection;" // Sdli |
| "float spotExponent;" // Srli |
| "float spotCutoff;" // Crli |
| // (range: [0.0,90.0], 180.0) |
| "float spotCosCutoff;" // Derived: cos(Crli) |
| // (range: [1.0,0.0],-1.0) |
| "float constantAttenuation;" // K0 |
| "float linearAttenuation;" // K1 |
| "float quadraticAttenuation;"// K2 |
| "};" |
| |
| |
| "struct gl_LightModelParameters {" |
| "vec4 ambient;" // Acs |
| "};" |
| |
| "uniform gl_LightModelParameters gl_LightModel;" |
| |
| // |
| // Derived state from products of light and material. |
| // |
| "struct gl_LightModelProducts {" |
| "vec4 sceneColor;" // Derived. Ecm + Acm * Acs |
| "};" |
| |
| "uniform gl_LightModelProducts gl_FrontLightModelProduct;" |
| "uniform gl_LightModelProducts gl_BackLightModelProduct;" |
| |
| "struct gl_LightProducts {" |
| "vec4 ambient;" // Acm * Acli |
| "vec4 diffuse;" // Dcm * Dcli |
| "vec4 specular;" // Scm * Scli |
| "};" |
| |
| // |
| // Fog p. 161 |
| // |
| "struct gl_FogParameters {" |
| "vec4 color;" |
| "float density;" |
| "float start;" |
| "float end;" |
| "float scale;" // 1 / (gl_FogEnd - gl_FogStart) |
| "};" |
| |
| "uniform gl_FogParameters gl_Fog;" |
| |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Define the interface to the compute shader. |
| // |
| //============================================================================ |
| |
| if ((profile != EEsProfile && version >= 430) || |
| (profile == EEsProfile && version >= 310)) { |
| stageBuiltins[EShLangCompute].append( |
| "in uvec3 gl_NumWorkGroups;" |
| "const uvec3 gl_WorkGroupSize = uvec3(1,1,1);" |
| |
| "in uvec3 gl_WorkGroupID;" |
| "in uvec3 gl_LocalInvocationID;" |
| |
| "in uvec3 gl_GlobalInvocationID;" |
| "in uint gl_LocalInvocationIndex;" |
| |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Define the interface to the vertex shader. |
| // |
| //============================================================================ |
| |
| if (profile != EEsProfile) { |
| if (version < 130) { |
| stageBuiltins[EShLangVertex].append( |
| "attribute vec4 gl_Color;" |
| "attribute vec4 gl_SecondaryColor;" |
| "attribute vec3 gl_Normal;" |
| "attribute vec4 gl_Vertex;" |
| "attribute vec4 gl_MultiTexCoord0;" |
| "attribute vec4 gl_MultiTexCoord1;" |
| "attribute vec4 gl_MultiTexCoord2;" |
| "attribute vec4 gl_MultiTexCoord3;" |
| "attribute vec4 gl_MultiTexCoord4;" |
| "attribute vec4 gl_MultiTexCoord5;" |
| "attribute vec4 gl_MultiTexCoord6;" |
| "attribute vec4 gl_MultiTexCoord7;" |
| "attribute float gl_FogCoord;" |
| "\n"); |
| } else if (IncludeLegacy(version, profile)) { |
| stageBuiltins[EShLangVertex].append( |
| "in vec4 gl_Color;" |
| "in vec4 gl_SecondaryColor;" |
| "in vec3 gl_Normal;" |
| "in vec4 gl_Vertex;" |
| "in vec4 gl_MultiTexCoord0;" |
| "in vec4 gl_MultiTexCoord1;" |
| "in vec4 gl_MultiTexCoord2;" |
| "in vec4 gl_MultiTexCoord3;" |
| "in vec4 gl_MultiTexCoord4;" |
| "in vec4 gl_MultiTexCoord5;" |
| "in vec4 gl_MultiTexCoord6;" |
| "in vec4 gl_MultiTexCoord7;" |
| "in float gl_FogCoord;" |
| "\n"); |
| } |
| |
| if (version < 150) { |
| if (version < 130) { |
| stageBuiltins[EShLangVertex].append( |
| " vec4 gl_ClipVertex;" // needs qualifier fixed later |
| "varying vec4 gl_FrontColor;" |
| "varying vec4 gl_BackColor;" |
| "varying vec4 gl_FrontSecondaryColor;" |
| "varying vec4 gl_BackSecondaryColor;" |
| "varying vec4 gl_TexCoord[];" |
| "varying float gl_FogFragCoord;" |
| "\n"); |
| } else if (IncludeLegacy(version, profile)) { |
| stageBuiltins[EShLangVertex].append( |
| " vec4 gl_ClipVertex;" // needs qualifier fixed later |
| "out vec4 gl_FrontColor;" |
| "out vec4 gl_BackColor;" |
| "out vec4 gl_FrontSecondaryColor;" |
| "out vec4 gl_BackSecondaryColor;" |
| "out vec4 gl_TexCoord[];" |
| "out float gl_FogFragCoord;" |
| "\n"); |
| } |
| stageBuiltins[EShLangVertex].append( |
| "vec4 gl_Position;" // needs qualifier fixed later |
| "float gl_PointSize;" // needs qualifier fixed later |
| ); |
| |
| if (version == 130 || version == 140) |
| stageBuiltins[EShLangVertex].append( |
| "out float gl_ClipDistance[];" |
| ); |
| } else { |
| // version >= 150 |
| stageBuiltins[EShLangVertex].append( |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" // needs qualifier fixed later |
| "float gl_PointSize;" // needs qualifier fixed later |
| "float gl_ClipDistance[];" |
| ); |
| if (IncludeLegacy(version, profile)) |
| stageBuiltins[EShLangVertex].append( |
| "vec4 gl_ClipVertex;" // needs qualifier fixed later |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (version >= 450) |
| stageBuiltins[EShLangVertex].append( |
| "float gl_CullDistance[];" |
| ); |
| stageBuiltins[EShLangVertex].append( |
| "};" |
| "\n"); |
| } |
| if (version >= 130) |
| stageBuiltins[EShLangVertex].append( |
| "int gl_VertexID;" // needs qualifier fixed later |
| ); |
| if (version >= 140) |
| stageBuiltins[EShLangVertex].append( |
| "int gl_InstanceID;" // needs qualifier fixed later |
| ); |
| if (version >= 440) { |
| stageBuiltins[EShLangVertex].append( |
| "in int gl_BaseVertexARB;" |
| "in int gl_BaseInstanceARB;" |
| "in int gl_DrawIDARB;" |
| ); |
| } |
| } else { |
| // ES profile |
| if (version == 100) { |
| stageBuiltins[EShLangVertex].append( |
| "highp vec4 gl_Position;" // needs qualifier fixed later |
| "mediump float gl_PointSize;" // needs qualifier fixed later |
| ); |
| } else { |
| stageBuiltins[EShLangVertex].append( |
| "highp int gl_VertexID;" // needs qualifier fixed later |
| "highp int gl_InstanceID;" // needs qualifier fixed later |
| ); |
| if (version < 310) |
| stageBuiltins[EShLangVertex].append( |
| "highp vec4 gl_Position;" // needs qualifier fixed later |
| "highp float gl_PointSize;" // needs qualifier fixed later |
| ); |
| else |
| stageBuiltins[EShLangVertex].append( |
| "out gl_PerVertex {" |
| "highp vec4 gl_Position;" // needs qualifier fixed later |
| "highp float gl_PointSize;" // needs qualifier fixed later |
| "};" |
| ); |
| } |
| } |
| |
| //============================================================================ |
| // |
| // Define the interface to the geometry shader. |
| // |
| //============================================================================ |
| |
| if (profile == ECoreProfile || profile == ECompatibilityProfile) { |
| stageBuiltins[EShLangGeometry].append( |
| "in gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "float gl_ClipDistance[];" |
| ); |
| if (profile == ECompatibilityProfile) |
| stageBuiltins[EShLangGeometry].append( |
| "vec4 gl_ClipVertex;" |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (version >= 450) |
| stageBuiltins[EShLangGeometry].append( |
| "float gl_CullDistance[];" |
| ); |
| stageBuiltins[EShLangGeometry].append( |
| "} gl_in[];" |
| |
| "in int gl_PrimitiveIDIn;" |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "float gl_ClipDistance[];" |
| "\n"); |
| if (profile == ECompatibilityProfile && version >= 400) |
| stageBuiltins[EShLangGeometry].append( |
| "vec4 gl_ClipVertex;" |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (version >= 450) |
| stageBuiltins[EShLangGeometry].append( |
| "float gl_CullDistance[];" |
| ); |
| stageBuiltins[EShLangGeometry].append( |
| "};" |
| |
| "out int gl_PrimitiveID;" |
| "out int gl_Layer;"); |
| |
| if (profile == ECompatibilityProfile && version < 400) |
| stageBuiltins[EShLangGeometry].append( |
| "out vec4 gl_ClipVertex;" |
| ); |
| |
| if (version >= 400) |
| stageBuiltins[EShLangGeometry].append( |
| "in int gl_InvocationID;" |
| ); |
| // GL_ARB_viewport_array |
| if (version >= 150) |
| stageBuiltins[EShLangGeometry].append( |
| "out int gl_ViewportIndex;" |
| ); |
| stageBuiltins[EShLangGeometry].append("\n"); |
| } else if (profile == EEsProfile && version >= 310) { |
| stageBuiltins[EShLangGeometry].append( |
| "in gl_PerVertex {" |
| "highp vec4 gl_Position;" |
| "highp float gl_PointSize;" |
| "} gl_in[];" |
| "\n" |
| "in highp int gl_PrimitiveIDIn;" |
| "in highp int gl_InvocationID;" |
| "\n" |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "};" |
| "\n" |
| "out int gl_PrimitiveID;" |
| "out int gl_Layer;" |
| "\n" |
| ); |
| } |
| |
| |
| //============================================================================ |
| // |
| // Define the interface to the tessellation control shader. |
| // |
| //============================================================================ |
| |
| if (profile != EEsProfile && version >= 150) { |
| // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, |
| // as it depends on the resource sizing of gl_MaxPatchVertices. |
| |
| stageBuiltins[EShLangTessControl].append( |
| "in int gl_PatchVerticesIn;" |
| "in int gl_PrimitiveID;" |
| "in int gl_InvocationID;" |
| |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "float gl_ClipDistance[];" |
| ); |
| if (profile == ECompatibilityProfile) |
| stageBuiltins[EShLangTessControl].append( |
| "vec4 gl_ClipVertex;" |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (version >= 450) |
| stageBuiltins[EShLangTessControl].append( |
| "float gl_CullDistance[];" |
| ); |
| stageBuiltins[EShLangTessControl].append( |
| "} gl_out[];" |
| |
| "patch out float gl_TessLevelOuter[4];" |
| "patch out float gl_TessLevelInner[2];" |
| "\n"); |
| } else { |
| // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, |
| // as it depends on the resource sizing of gl_MaxPatchVertices. |
| |
| stageBuiltins[EShLangTessControl].append( |
| "in highp int gl_PatchVerticesIn;" |
| "in highp int gl_PrimitiveID;" |
| "in highp int gl_InvocationID;" |
| |
| "out gl_PerVertex {" |
| "highp vec4 gl_Position;" |
| "highp float gl_PointSize;" |
| ); |
| stageBuiltins[EShLangTessControl].append( |
| "} gl_out[];" |
| |
| "patch out highp float gl_TessLevelOuter[4];" |
| "patch out highp float gl_TessLevelInner[2];" |
| "patch out highp vec4 gl_BoundingBoxOES[2];" |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Define the interface to the tessellation evaluation shader. |
| // |
| //============================================================================ |
| |
| if (profile != EEsProfile && version >= 150) { |
| // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, |
| // as it depends on the resource sizing of gl_MaxPatchVertices. |
| |
| stageBuiltins[EShLangTessEvaluation].append( |
| "in int gl_PatchVerticesIn;" |
| "in int gl_PrimitiveID;" |
| "in vec3 gl_TessCoord;" |
| |
| "patch in float gl_TessLevelOuter[4];" |
| "patch in float gl_TessLevelInner[2];" |
| |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "float gl_ClipDistance[];" |
| ); |
| if (version >= 400 && profile == ECompatibilityProfile) |
| stageBuiltins[EShLangTessEvaluation].append( |
| "vec4 gl_ClipVertex;" |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (version >= 450) |
| stageBuiltins[EShLangTessEvaluation].append( |
| "float gl_CullDistance[];" |
| ); |
| stageBuiltins[EShLangTessEvaluation].append( |
| "};" |
| "\n"); |
| } else if (profile == EEsProfile && version >= 310) { |
| // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, |
| // as it depends on the resource sizing of gl_MaxPatchVertices. |
| |
| stageBuiltins[EShLangTessEvaluation].append( |
| "in highp int gl_PatchVerticesIn;" |
| "in highp int gl_PrimitiveID;" |
| "in highp vec3 gl_TessCoord;" |
| |
| "patch in highp float gl_TessLevelOuter[4];" |
| "patch in highp float gl_TessLevelInner[2];" |
| |
| "out gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| ); |
| stageBuiltins[EShLangTessEvaluation].append( |
| "};" |
| "\n"); |
| } |
| |
| //============================================================================ |
| // |
| // Define the interface to the fragment shader. |
| // |
| //============================================================================ |
| |
| if (profile != EEsProfile) { |
| |
| stageBuiltins[EShLangFragment].append( |
| "vec4 gl_FragCoord;" // needs qualifier fixed later |
| "bool gl_FrontFacing;" // needs qualifier fixed later |
| "float gl_FragDepth;" // needs qualifier fixed later |
| ); |
| if (version >= 120) |
| stageBuiltins[EShLangFragment].append( |
| "vec2 gl_PointCoord;" // needs qualifier fixed later |
| ); |
| if (IncludeLegacy(version, profile) || (! ForwardCompatibility && version < 420)) |
| stageBuiltins[EShLangFragment].append( |
| "vec4 gl_FragColor;" // needs qualifier fixed later |
| ); |
| |
| if (version < 130) { |
| stageBuiltins[EShLangFragment].append( |
| "varying vec4 gl_Color;" |
| "varying vec4 gl_SecondaryColor;" |
| "varying vec4 gl_TexCoord[];" |
| "varying float gl_FogFragCoord;" |
| ); |
| } else { |
| stageBuiltins[EShLangFragment].append( |
| "in float gl_ClipDistance[];" |
| ); |
| |
| if (IncludeLegacy(version, profile)) { |
| if (version < 150) |
| stageBuiltins[EShLangFragment].append( |
| "in float gl_FogFragCoord;" |
| "in vec4 gl_TexCoord[];" |
| "in vec4 gl_Color;" |
| "in vec4 gl_SecondaryColor;" |
| ); |
| else |
| stageBuiltins[EShLangFragment].append( |
| "in gl_PerFragment {" |
| "in float gl_FogFragCoord;" |
| "in vec4 gl_TexCoord[];" |
| "in vec4 gl_Color;" |
| "in vec4 gl_SecondaryColor;" |
| "};" |
| ); |
| } |
| } |
| |
| if (version >= 150) |
| stageBuiltins[EShLangFragment].append( |
| "flat in int gl_PrimitiveID;" |
| ); |
| |
| if (version >= 400) |
| stageBuiltins[EShLangFragment].append( |
| "flat in int gl_SampleID;" |
| " in vec2 gl_SamplePosition;" |
| "flat in int gl_SampleMaskIn[];" |
| " out int gl_SampleMask[];" |
| "uniform int gl_NumSamples;" |
| ); |
| |
| if (version >= 430) |
| stageBuiltins[EShLangFragment].append( |
| "flat in int gl_Layer;" |
| "flat in int gl_ViewportIndex;" |
| ); |
| |
| if (version >= 450) |
| stageBuiltins[EShLangFragment].append( |
| "in float gl_CullDistance[];" |
| "bool gl_HelperInvocation;" // needs qualifier fixed later |
| ); |
| } else { |
| // ES profile |
| |
| if (version == 100) { |
| stageBuiltins[EShLangFragment].append( |
| "mediump vec4 gl_FragCoord;" // needs qualifier fixed later |
| " bool gl_FrontFacing;" // needs qualifier fixed later |
| "mediump vec4 gl_FragColor;" // needs qualifier fixed later |
| "mediump vec2 gl_PointCoord;" // needs qualifier fixed later |
| ); |
| } |
| if (version >= 300) { |
| stageBuiltins[EShLangFragment].append( |
| "highp vec4 gl_FragCoord;" // needs qualifier fixed later |
| " bool gl_FrontFacing;" // needs qualifier fixed later |
| "mediump vec2 gl_PointCoord;" // needs qualifier fixed later |
| "highp float gl_FragDepth;" // needs qualifier fixed later |
| ); |
| } |
| if (version >= 310) { |
| stageBuiltins[EShLangFragment].append( |
| "bool gl_HelperInvocation;" // needs qualifier fixed later |
| "flat in highp int gl_PrimitiveID;" // needs qualifier fixed later |
| "flat in highp int gl_Layer;" // needs qualifier fixed later |
| ); |
| |
| stageBuiltins[EShLangFragment].append( // GL_OES_sample_variables |
| "flat lowp in int gl_SampleID;" |
| " mediump in vec2 gl_SamplePosition;" |
| "flat highp in int gl_SampleMaskIn[];" |
| " highp out int gl_SampleMask[];" |
| "uniform lowp int gl_NumSamples;" |
| ); |
| } |
| stageBuiltins[EShLangFragment].append( |
| "highp float gl_FragDepthEXT;" // GL_EXT_frag_depth |
| ); |
| } |
| stageBuiltins[EShLangFragment].append("\n"); |
| |
| if (version >= 130) |
| add2ndGenerationSamplingImaging(version, profile); |
| |
| //printf("%s\n", commonBuiltins.c_str()); |
| //printf("%s\n", stageBuiltins[EShLangFragment].c_str()); |
| } |
| |
| // |
| // Helper function for initialize(), to add the second set of names for texturing, |
| // when adding context-independent built-in functions. |
| // |
| void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile) |
| { |
| // |
| // In this function proper, enumerate the types, then calls the next set of functions |
| // to enumerate all the uses for that type. |
| // |
| |
| TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint }; |
| bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); |
| bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); |
| |
| // enumerate all the types |
| for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler |
| |
| for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not |
| for (int ms = 0; ms <=1; ++ms) { |
| |
| if ((ms || image) && shadow) |
| continue; |
| if (ms && profile != EEsProfile && version < 150) |
| continue; |
| if (ms && image && profile == EEsProfile) |
| continue; |
| if (ms && profile == EEsProfile && version < 310) |
| continue; |
| |
| for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not |
| for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer |
| |
| if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) |
| continue; |
| if (dim != Esd2D && ms) |
| continue; |
| if ((dim == Esd3D || dim == EsdRect) && arrayed) |
| continue; |
| if (dim == Esd3D && shadow) |
| continue; |
| if (dim == EsdCube && arrayed && skipCubeArrayed) |
| continue; |
| if (dim == EsdBuffer && skipBuffer) |
| continue; |
| if (dim == EsdBuffer && (shadow || arrayed || ms)) |
| continue; |
| if (ms && arrayed && profile == EEsProfile && version < 310) |
| continue; |
| |
| for (int bType = 0; bType < 3; ++bType) { // float, int, uint results |
| |
| if (shadow && bType > 0) |
| continue; |
| |
| if (dim == EsdRect && version < 140 && bType > 0) |
| continue; |
| |
| // |
| // Now, make all the function prototypes for the type we just built... |
| // |
| |
| TSampler sampler; |
| sampler.set(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, |
| shadow ? true : false, |
| ms ? true : false); |
| if (image) |
| sampler.image = true; |
| |
| TString typeName = sampler.getString(); |
| |
| addQueryFunctions(sampler, typeName, version, profile); |
| |
| if (image) |
| addImageFunctions(sampler, typeName, version, profile); |
| else { |
| addSamplingFunctions(sampler, typeName, version, profile); |
| addGatherFunctions(sampler, typeName, version, profile); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // |
| // Helper function for add2ndGenerationSamplingImaging(), |
| // when adding context-independent built-in functions. |
| // |
| // Add all the query functions for the given type. |
| // |
| void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile) |
| { |
| if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) |
| return; |
| |
| // |
| // textureSize() and imageSize() |
| // |
| |
| int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); |
| if (profile == EEsProfile) |
| commonBuiltins.append("highp "); |
| if (sizeDims == 1) |
| commonBuiltins.append("int"); |
| else { |
| commonBuiltins.append("ivec"); |
| commonBuiltins.append(postfixes[sizeDims]); |
| } |
| if (sampler.image) |
| commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); |
| else |
| commonBuiltins.append(" textureSize("); |
| commonBuiltins.append(typeName); |
| if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms) |
| commonBuiltins.append(",int);\n"); |
| else |
| commonBuiltins.append(");\n"); |
| |
| // |
| // textureSamples() and imageSamples() |
| // |
| |
| // GL_ARB_shader_texture_image_samples |
| // TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? |
| if (profile != EEsProfile && version >= 430 && sampler.ms) { |
| commonBuiltins.append("int "); |
| if (sampler.image) |
| commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); |
| else |
| commonBuiltins.append("textureSamples("); |
| commonBuiltins.append(typeName); |
| commonBuiltins.append(");\n"); |
| } |
| |
| // |
| // textureQueryLod(), fragment stage only |
| // |
| |
| if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { |
| stageBuiltins[EShLangFragment].append("vec2 textureQueryLod("); |
| stageBuiltins[EShLangFragment].append(typeName); |
| if (dimMap[sampler.dim] == 1) |
| stageBuiltins[EShLangFragment].append(", float"); |
| else { |
| stageBuiltins[EShLangFragment].append(", vec"); |
| stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]); |
| } |
| stageBuiltins[EShLangFragment].append(");\n"); |
| } |
| |
| // |
| // textureQueryLevels() |
| // |
| |
| if (profile != EEsProfile && version >= 430 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { |
| commonBuiltins.append("int textureQueryLevels("); |
| commonBuiltins.append(typeName); |
| commonBuiltins.append(");\n"); |
| } |
| } |
| |
| // |
| // Helper function for add2ndGenerationSamplingImaging(), |
| // when adding context-independent built-in functions. |
| // |
| // Add all the image access functions for the given type. |
| // |
| void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile) |
| { |
| int dims = dimMap[sampler.dim]; |
| // most things with an array add a dimension, except for cubemaps |
| if (sampler.arrayed && sampler.dim != EsdCube) |
| ++dims; |
| |
| 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 volatile coherent "); |
| commonBuiltins.append(imageParams); |
| commonBuiltins.append(");\n"); |
| |
| commonBuiltins.append("void imageStore(writeonly volatile coherent "); |
| commonBuiltins.append(imageParams); |
| commonBuiltins.append(", "); |
| commonBuiltins.append(prefixes[sampler.type]); |
| commonBuiltins.append("vec4);\n"); |
| |
| if ( profile != EEsProfile || |
| (profile == EEsProfile && version >= 310)) { |
| 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(volatile coherent ", |
| " imageAtomicMin(volatile coherent ", |
| " imageAtomicMax(volatile coherent ", |
| " imageAtomicAnd(volatile coherent ", |
| " imageAtomicOr(volatile coherent ", |
| " imageAtomicXor(volatile coherent ", |
| " imageAtomicExchange(volatile coherent " |
| }; |
| |
| for (size_t i = 0; i < numBuiltins; ++i) { |
| commonBuiltins.append(dataType); |
| commonBuiltins.append(atomicFunc[i]); |
| commonBuiltins.append(imageParams); |
| commonBuiltins.append(", "); |
| commonBuiltins.append(dataType); |
| commonBuiltins.append(");\n"); |
| } |
| |
| commonBuiltins.append(dataType); |
| commonBuiltins.append(" imageAtomicCompSwap(volatile coherent "); |
| commonBuiltins.append(imageParams); |
| commonBuiltins.append(", "); |
| commonBuiltins.append(dataType); |
| commonBuiltins.append(", "); |
| commonBuiltins.append(dataType); |
| commonBuiltins.append(");\n"); |
| } else { |
| // not int or uint |
| // GL_ARB_ES3_1_compatibility |
| // TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers? |
| if ((profile != EEsProfile && version >= 450) || |
| (profile == EEsProfile && version >= 310)) { |
| commonBuiltins.append("float imageAtomicExchange(volatile coherent "); |
| commonBuiltins.append(imageParams); |
| commonBuiltins.append(", float);\n"); |
| } |
| } |
| } |
| } |
| |
| // |
| // Helper function for add2ndGenerationSamplingImaging(), |
| // when adding context-independent built-in functions. |
| // |
| // Add all the texture lookup functions for the given type. |
| // |
| void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int /*version*/, EProfile /*profile*/) |
| { |
| // |
| // texturing |
| // |
| for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not |
| |
| if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms)) |
| continue; |
| |
| for (int lod = 0; lod <= 1; ++lod) { |
| |
| if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms)) |
| continue; |
| if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) |
| continue; |
| if (lod && sampler.dim == EsdCube && sampler.shadow) |
| continue; |
| |
| for (int bias = 0; bias <= 1; ++bias) { |
| |
| if (bias && (lod || sampler.ms)) |
| continue; |
| if (bias && sampler.dim == Esd2D && sampler.shadow && sampler.arrayed) |
| continue; |
| if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) |
| continue; |
| |
| for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not |
| |
| if (proj + offset + bias + lod > 3) |
| continue; |
| if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) |
| continue; |
| |
| for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not |
| |
| if (proj + offset + fetch + bias + lod > 3) |
| continue; |
| if (fetch && (lod || bias)) |
| continue; |
| if (fetch && (sampler.shadow || sampler.dim == EsdCube)) |
| continue; |
| if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer)) |
| continue; |
| |
| for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not |
| |
| if (grad && (lod || bias || sampler.ms)) |
| continue; |
| if (grad && sampler.dim == EsdBuffer) |
| continue; |
| if (proj + offset + fetch + grad + bias + lod > 3) |
| continue; |
| |
| for (int extraProj = 0; extraProj <= 1; ++extraProj) { |
| bool compare = false; |
| int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); |
| // skip dummy unused second component for 1D non-array shadows |
| if (sampler.shadow && totalDims < 2) |
| totalDims = 2; |
| totalDims += (sampler.shadow ? 1 : 0) + proj; |
| if (totalDims > 4 && sampler.shadow) { |
| compare = true; |
| totalDims = 4; |
| } |
| assert(totalDims <= 4); |
| |
| if (extraProj && ! proj) |
| continue; |
| if (extraProj && (sampler.dim == Esd3D || sampler.shadow)) |
| continue; |
| |
| TString s; |
| |
| // return type |
| if (sampler.shadow) |
| s.append("float "); |
| else { |
| s.append(prefixes[sampler.type]); |
| s.append("vec4 "); |
| } |
| |
| // name |
| if (fetch) |
| s.append("texel"); |
| else |
| s.append("texture"); |
| if (proj) |
| s.append("Proj"); |
| if (lod) |
| s.append("Lod"); |
| if (grad) |
| s.append("Grad"); |
| if (fetch) |
| s.append("Fetch"); |
| if (offset) |
| s.append("Offset"); |
| s.append("("); |
| |
| // sampler type |
| s.append(typeName); |
| |
| // P coordinate |
| if (extraProj) |
| s.append(",vec4"); |
| else { |
| s.append(","); |
| TBasicType t = fetch ? EbtInt : EbtFloat; |
| if (totalDims == 1) |
| s.append(TType::getBasicString(t)); |
| else { |
| s.append(prefixes[t]); |
| s.append("vec"); |
| s.append(postfixes[totalDims]); |
| } |
| } |
| |
| if (bias && compare) |
| continue; |
| |
| // non-optional lod argument (lod that's not driven by lod loop) or sample |
| if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || |
| (sampler.ms && fetch)) |
| s.append(",int"); |
| |
| // non-optional lod |
| if (lod) |
| s.append(",float"); |
| |
| // gradient arguments |
| if (grad) { |
| if (dimMap[sampler.dim] == 1) |
| s.append(",float,float"); |
| else { |
| s.append(",vec"); |
| s.append(postfixes[dimMap[sampler.dim]]); |
| s.append(",vec"); |
| s.append(postfixes[dimMap[sampler.dim]]); |
| } |
| } |
| |
| // offset |
| if (offset) { |
| if (dimMap[sampler.dim] == 1) |
| s.append(",int"); |
| else { |
| s.append(",ivec"); |
| s.append(postfixes[dimMap[sampler.dim]]); |
| } |
| } |
| |
| // optional bias or non-optional compare |
| if (bias || compare) |
| s.append(",float"); |
| |
| s.append(");\n"); |
| |
| // Add to the per-language set of built-ins |
| |
| if (bias) |
| stageBuiltins[EShLangFragment].append(s); |
| else |
| commonBuiltins.append(s); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| // |
| // Helper function for add2ndGenerationSamplingImaging(), |
| // when adding context-independent built-in functions. |
| // |
| // Add all the texture gather functions for the given type. |
| // |
| void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int version, EProfile /* profile */) |
| { |
| switch (sampler.dim) { |
| case Esd2D: |
| case EsdRect: |
| case EsdCube: |
| break; |
| default: |
| return; |
| } |
| |
| if (sampler.ms) |
| return; |
| |
| if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) |
| return; |
| |
| for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets |
| |
| for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument |
| |
| if (comp > 0 && sampler.shadow) |
| continue; |
| |
| if (offset > 0 && sampler.dim == EsdCube) |
| continue; |
| |
| TString s; |
| |
| // return type |
| s.append(prefixes[sampler.type]); |
| s.append("vec4 "); |
| |
| // name |
| s.append("textureGather"); |
| switch (offset) { |
| case 1: |
| s.append("Offset"); |
| break; |
| case 2: |
| s.append("Offsets"); |
| default: |
| break; |
| } |
| s.append("("); |
| |
| // sampler type argument |
| s.append(typeName); |
| |
| // P coordinate argument |
| s.append(",vec"); |
| int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); |
| s.append(postfixes[totalDims]); |
| |
| // refZ argument |
| if (sampler.shadow) |
| s.append(",float"); |
| |
| // offset argument |
| if (offset > 0) { |
| s.append(",ivec2"); |
| if (offset == 2) |
| s.append("[4]"); |
| } |
| |
| // comp argument |
| if (comp) |
| s.append(",int"); |
| |
| s.append(");\n"); |
| commonBuiltins.append(s); |
| //printf("%s", s.c_str()); |
| } |
| } |
| } |
| |
| // |
| // Add context-dependent built-in functions and variables that are present |
| // for the given version and profile. All the results are put into just the |
| // commonBuiltins, because it is called for just a specific stage. So, |
| // add stage-specific entries to the commonBuiltins, and only if that stage |
| // was requested. |
| // |
| void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, EShLanguage language) |
| { |
| // |
| // Initialize the context-dependent (resource-dependent) built-in strings for parsing. |
| // |
| |
| //============================================================================ |
| // |
| // Standard Uniforms |
| // |
| //============================================================================ |
| |
| TString& s = commonBuiltins; |
| const int maxSize = 80; |
| char builtInConstant[maxSize]; |
| |
| // |
| // Build string of implementation dependent constants. |
| // |
| |
| if (profile == EEsProfile) { |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); |
| s.append(builtInConstant); |
| |
| if (version == 100) { |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors); |
| s.append(builtInConstant); |
| } else { |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentInputVectors = %d;", resources.maxFragmentInputVectors); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset); |
| s.append(builtInConstant); |
| } |
| |
| if (version >= 310) { |
| // geometry |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.maxGeometryTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.maxGeometryAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.maxGeometryAtomicCounterBuffers); |
| s.append(builtInConstant); |
| |
| // tessellation |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.maxTessControlInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.maxTessControlOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.maxTessControlTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.maxTessControlUniformComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.maxTessEvaluationTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.maxPatchVertices); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel); |
| s.append(builtInConstant); |
| |
| // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxPatchVertices |
| if (language == EShLangTessControl || language == EShLangTessEvaluation) { |
| s.append( |
| "in gl_PerVertex {" |
| "highp vec4 gl_Position;" |
| "highp float gl_PointSize;" |
| "} gl_in[gl_MaxPatchVertices];" |
| "\n"); |
| } |
| } |
| |
| } else { |
| // non-ES profile |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxLights = %d;", resources.maxLights); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxClipPlanes = %d;", resources.maxClipPlanes); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTextureUnits = %d;", resources.maxTextureUnits); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTextureCoords = %d;", resources.maxTextureCoords); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); |
| s.append(builtInConstant); |
| |
| if (version < 150 || ARBCompatibility) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); |
| s.append(builtInConstant); |
| } |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents); |
| s.append(builtInConstant); |
| |
| if (IncludeLegacy(version, profile)) { |
| // |
| // OpenGL'uniform' state. Page numbers are in reference to version |
| // 1.4 of the OpenGL specification. |
| // |
| |
| // |
| // Matrix state. p. 31, 32, 37, 39, 40. |
| // |
| s.append("uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];" |
| |
| // |
| // Derived matrix state that provides inverse and transposed versions |
| // of the matrices above. |
| // |
| "uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];" |
| |
| "uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];" |
| |
| "uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];" |
| |
| // |
| // Clip planes p. 42. |
| // |
| "uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];" |
| |
| // |
| // Light State p 50, 53, 55. |
| // |
| "uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];" |
| |
| // |
| // Derived state from products of light. |
| // |
| "uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];" |
| "uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];" |
| |
| // |
| // Texture Environment and Generation, p. 152, p. 40-42. |
| // |
| "uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];" |
| "uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];" |
| "uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];" |
| "uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];" |
| "uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];" |
| "uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];" |
| "uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];" |
| "uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];" |
| "uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];"); |
| } |
| |
| if (version >= 130) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxClipDistances = %d;", resources.maxClipDistances); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingComponents = %d;", resources.maxVaryingComponents); |
| s.append(builtInConstant); |
| |
| // GL_ARB_shading_language_420pack |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset); |
| s.append(builtInConstant); |
| } |
| |
| // geometry |
| if (version >= 150) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.maxGeometryTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryVaryingComponents = %d;", resources.maxGeometryVaryingComponents); |
| s.append(builtInConstant); |
| |
| } |
| |
| if (version >= 150) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexOutputComponents = %d;", resources.maxVertexOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentInputComponents = %d;", resources.maxFragmentInputComponents); |
| s.append(builtInConstant); |
| } |
| |
| // tessellation |
| if (version >= 150) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.maxTessControlInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.maxTessControlOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.maxTessControlTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.maxTessControlUniformComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.maxTessEvaluationTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.maxPatchVertices); |
| s.append(builtInConstant); |
| |
| // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxPatchVertices |
| if (language == EShLangTessControl || language == EShLangTessEvaluation) { |
| s.append( |
| "in gl_PerVertex {" |
| "vec4 gl_Position;" |
| "float gl_PointSize;" |
| "float gl_ClipDistance[];" |
| ); |
| if (profile == ECompatibilityProfile) |
| s.append( |
| "vec4 gl_ClipVertex;" |
| "vec4 gl_FrontColor;" |
| "vec4 gl_BackColor;" |
| "vec4 gl_FrontSecondaryColor;" |
| "vec4 gl_BackSecondaryColor;" |
| "vec4 gl_TexCoord[];" |
| "float gl_FogFragCoord;" |
| ); |
| if (profile != EEsProfile && version >= 450) |
| s.append( |
| "float gl_CullDistance[];" |
| ); |
| s.append( |
| "} gl_in[gl_MaxPatchVertices];" |
| "\n"); |
| } |
| } |
| |
| if (version >= 150) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxViewports = %d;", resources.maxViewports); |
| s.append(builtInConstant); |
| } |
| |
| // images |
| if (version >= 130) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.maxCombinedImageUnitsAndFragmentOutputs); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.maxImageSamples); |
| 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); |
| } |
| |
| // enhanced layouts |
| if (version >= 430) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackBuffers = %d;", resources.maxTransformFeedbackBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents); |
| s.append(builtInConstant); |
| } |
| } |
| |
| // images (some in compute below) |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 130)) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms); |
| 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); |
| } |
| |
| // atomic counters (some in compute below) |
| if ((profile == EEsProfile && version >= 310) || |
| (profile != EEsProfile && version >= 420)) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources. maxVertexAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources. maxFragmentAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources. maxCombinedAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources. maxAtomicCounterBindings); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources. maxVertexAtomicCounterBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources. maxFragmentAtomicCounterBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources. maxCombinedAtomicCounterBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources. maxAtomicCounterBufferSize); |
| s.append(builtInConstant); |
| } |
| if (profile != EEsProfile && version >= 420) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources. maxTessControlAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources. maxTessEvaluationAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources. maxGeometryAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources. maxTessControlAtomicCounterBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources. maxTessEvaluationAtomicCounterBuffers); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources. maxGeometryAtomicCounterBuffers); |
| s.append(builtInConstant); |
| |
| s.append("\n"); |
| } |
| |
| |
| // compute |
| if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) { |
| snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, |
| resources.maxComputeWorkGroupCountY, |
| resources.maxComputeWorkGroupCountZ); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, |
| resources.maxComputeWorkGroupSizeY, |
| resources.maxComputeWorkGroupSizeZ); |
| s.append(builtInConstant); |
| |
| snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); |
| s.append(builtInConstant); |
| |
| s.append("\n"); |
| } |
| |
| // GL_ARB_cull_distance |
| if (profile != EEsProfile && version >= 450) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCullDistances = %d;", resources.maxCullDistances); |
| s.append(builtInConstant); |
| snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedClipAndCullDistances = %d;", resources.maxCombinedClipAndCullDistances); |
| s.append(builtInConstant); |
| } |
| |
| // GL_ARB_ES3_1_compatibility |
| if ((profile != EEsProfile && version >= 450) || |
| (profile == EEsProfile && version >= 310)) { |
| snprintf(builtInConstant, maxSize, "const int gl_MaxSamples = %d;", resources.maxSamples); |
| s.append(builtInConstant); |
| } |
| |
| s.append("\n"); |
| } |
| |
| // |
| // To support special built-ins that have a special qualifier that cannot be declared textually |
| // in a shader, like gl_Position. |
| // |
| // This lets the type of the built-in be declared textually, and then have just its qualifier be |
| // updated afterward. |
| // |
| // Safe to call even if name is not present. |
| // |
| // Only use this for built-in variables that have a special qualifier in TStorageQualifier. |
| // New built-in variables should use a generic (textually declarable) qualifier in |
| // TStoraregQualifier and only call BuiltInVariable(). |
| // |
| void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBuiltInVariable builtIn, TSymbolTable& symbolTable) |
| { |
| TSymbol* symbol = symbolTable.find(name); |
| if (symbol) { |
| TQualifier& symQualifier = symbol->getWritableType().getQualifier(); |
| symQualifier.storage = qualifier; |
| symQualifier.builtIn = builtIn; |
| } |
| } |
| |
| // |
| // To tag built-in variables with their TBuiltInVariable enum. Use this when the |
| // normal declaration text already gets the qualifier right, and all that's needed |
| // is setting the builtIn field. This should be the normal way for all new |
| // built-in variables. |
| // |
| // If SpecialQualifier() was called, this does not need to be called. |
| // |
| // Safe to call even if name is not present. |
| // |
| void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) |
| { |
| TSymbol* symbol = symbolTable.find(name); |
| if (! symbol) |
| return; |
| |
| TQualifier& symQualifier = symbol->getWritableType().getQualifier(); |
| symQualifier.builtIn = builtIn; |
| } |
| |
| // |
| // For built-in variables inside a named block. |
| // SpecialQualifier() won't ever go inside a block; their member's qualifier come |
| // from the qualification of the block. |
| // |
| // See comments above for other detail. |
| // |
| void BuiltInVariable(const char* blockName, const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) |
| { |
| TSymbol* symbol = symbolTable.find(blockName); |
| if (! symbol) |
| return; |
| |
| TTypeList& structure = *symbol->getWritableType().getWritableStruct(); |
| for (int i = 0; i < (int)structure.size(); ++i) { |
| if (structure[i].type->getFieldName().compare(name) == 0) { |
| structure[i].type->getQualifier().builtIn = builtIn; |
| return; |
| } |
| } |
| } |
| |
| // |
| // Finish adding/processing context-independent built-in symbols. |
| // 1) Programmatically add symbols that could not be added by simple text strings above. |
| // 2) Map built-in functions to operators, for those that will turn into an operation node |
| // instead of remaining a function call. |
| // 3) Tag extension-related symbols added to their base version with their extensions, so |
| // that if an early version has the extension turned off, there is an error reported on use. |
| // |
| void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable) |
| { |
| // |
| // Tag built-in variables and functions with additional qualifier and extension information |
| // that cannot be declared with the text strings. |
| // |
| |
| // N.B.: a symbol should only be tagged once, and this function is called multiple times, once |
| // per stage that's used for this profile. So |
| // - generally, stick common ones in the fragment stage to ensure they are tagged exactly once |
| // - for ES, which has different precisions for different stages, the coarsest-grained tagging |
| // for a built-in used in many stages needs to be once for the fragment stage and once for |
| // the vertex stage |
| |
| switch(language) { |
| case EShLangVertex: |
| if (profile != EEsProfile && version >= 440) { |
| symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); |
| symbolTable.setVariableExtensions("gl_BaseInstanceARB", 1, &E_GL_ARB_shader_draw_parameters); |
| symbolTable.setVariableExtensions("gl_DrawIDARB", 1, &E_GL_ARB_shader_draw_parameters); |
| |
| BuiltInVariable("gl_BaseVertexARB", EbvBaseVertex, symbolTable); |
| BuiltInVariable("gl_BaseInstanceARB", EbvBaseInstance, symbolTable); |
| BuiltInVariable("gl_DrawIDARB", EbvDrawId, symbolTable); |
| } |
| |
| // Compatibility variables, vertex only |
| BuiltInVariable("gl_Color", EbvColor, symbolTable); |
| BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable); |
| BuiltInVariable("gl_Normal", EbvNormal, symbolTable); |
| BuiltInVariable("gl_Vertex", EbvVertex, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord0", EbvMultiTexCoord0, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord1", EbvMultiTexCoord1, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord2", EbvMultiTexCoord2, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord3", EbvMultiTexCoord3, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord4", EbvMultiTexCoord4, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord5", EbvMultiTexCoord5, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord6", EbvMultiTexCoord6, symbolTable); |
| BuiltInVariable("gl_MultiTexCoord7", EbvMultiTexCoord7, symbolTable); |
| BuiltInVariable("gl_FogCoord", EbvFogFragCoord, symbolTable); |
| |
| if (profile == EEsProfile) { |
| symbolTable.setFunctionExtensions("texture2DGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DProjGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureCubeGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureGatherOffsets", Num_AEP_gpu_shader5, AEP_gpu_shader5); |
| if (version >= 310) |
| symbolTable.setFunctionExtensions("fma", Num_AEP_gpu_shader5, AEP_gpu_shader5); |
| } |
| |
| if (profile == EEsProfile) { |
| symbolTable.setFunctionExtensions("imageAtomicAdd", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicMin", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicMax", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicAnd", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicOr", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicXor", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); |
| } |
| |
| // Fall through |
| |
| case EShLangTessControl: |
| if (profile == EEsProfile && version >= 310) { |
| symbolTable.setVariableExtensions("gl_BoundingBoxOES", Num_AEP_primitive_bounding_box, AEP_primitive_bounding_box); |
| BuiltInVariable("gl_BoundingBoxOES", EbvBoundingBox, symbolTable); |
| } |
| |
| // Fall through |
| |
| case EShLangTessEvaluation: |
| case EShLangGeometry: |
| SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); |
| SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); |
| SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); |
| SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); |
| SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); |
| |
| BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); |
| BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); |
| BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); |
| BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); |
| |
| BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable); |
| BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable); |
| BuiltInVariable("gl_out", "gl_ClipDistance", EbvClipDistance, symbolTable); |
| BuiltInVariable("gl_out", "gl_CullDistance", EbvCullDistance, symbolTable); |
| |
| BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); |
| BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable); |
| BuiltInVariable("gl_PrimitiveIDIn", EbvPrimitiveId, symbolTable); |
| BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); |
| BuiltInVariable("gl_InvocationID", EbvInvocationId, symbolTable); |
| BuiltInVariable("gl_Layer", EbvLayer, symbolTable); |
| BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); |
| BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices, symbolTable); |
| BuiltInVariable("gl_TessLevelOuter", EbvTessLevelOuter, symbolTable); |
| BuiltInVariable("gl_TessLevelInner", EbvTessLevelInner, symbolTable); |
| BuiltInVariable("gl_TessCoord", EbvTessCoord, symbolTable); |
| |
| if (version < 410) |
| symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &E_GL_ARB_viewport_array); |
| |
| // Compatibility variables |
| |
| BuiltInVariable("gl_in", "gl_ClipVertex", EbvClipVertex, symbolTable); |
| BuiltInVariable("gl_in", "gl_FrontColor", EbvFrontColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_BackColor", EbvBackColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| |
| BuiltInVariable("gl_out", "gl_ClipVertex", EbvClipVertex, symbolTable); |
| BuiltInVariable("gl_out", "gl_FrontColor", EbvFrontColor, symbolTable); |
| BuiltInVariable("gl_out", "gl_BackColor", EbvBackColor, symbolTable); |
| BuiltInVariable("gl_out", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); |
| BuiltInVariable("gl_out", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); |
| BuiltInVariable("gl_out", "gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_out", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| |
| BuiltInVariable("gl_ClipVertex", EbvClipVertex, symbolTable); |
| BuiltInVariable("gl_FrontColor", EbvFrontColor, symbolTable); |
| BuiltInVariable("gl_BackColor", EbvBackColor, symbolTable); |
| BuiltInVariable("gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); |
| BuiltInVariable("gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); |
| BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| |
| // gl_PointSize, when it needs to be tied to an extension, is always a member of a block. |
| // (Sometimes with an instance name, sometimes anonymous). |
| // However, the current automatic extension scheme does not work per block member, |
| // so for now check when parsing. |
| // |
| //if (profile == EEsProfile) { |
| // if (language == EShLangGeometry) |
| // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_geometry_point_size, AEP_geometry_point_size); |
| // else if (language == EShLangTessEvaluation || language == EShLangTessControl) |
| // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); |
| //} |
| |
| break; |
| |
| case EShLangFragment: |
| SpecialQualifier("gl_FrontFacing", EvqFace, EbvFace, symbolTable); |
| SpecialQualifier("gl_FragCoord", EvqFragCoord, EbvFragCoord, symbolTable); |
| SpecialQualifier("gl_PointCoord", EvqPointCoord, EbvPointCoord, symbolTable); |
| SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable); |
| SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); |
| SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); |
| SpecialQualifier("gl_HelperInvocation", EvqIn, EbvHelperInvocation, symbolTable); |
| |
| BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); |
| BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable); |
| BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); |
| |
| if ((profile != EEsProfile && version >= 400) || |
| (profile == EEsProfile && version >= 310)) { |
| BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); |
| BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); |
| BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); |
| BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); |
| if (profile == EEsProfile) { |
| symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); |
| symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); |
| symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); |
| symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); |
| symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); |
| } |
| } |
| |
| BuiltInVariable("gl_Layer", EbvLayer, symbolTable); |
| BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); |
| |
| // Compatibility variables |
| |
| BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_in", "gl_Color", EbvColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_SecondaryColor", EbvSecondaryColor, symbolTable); |
| |
| BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_Color", EbvColor, symbolTable); |
| BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable); |
| |
| // built-in functions |
| |
| if (profile == EEsProfile) { |
| symbolTable.setFunctionExtensions("texture2DLodEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DProjLodEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureCubeLodEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DProjGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureCubeGradEXT", 1, &E_GL_EXT_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureGatherOffsets", Num_AEP_gpu_shader5, AEP_gpu_shader5); |
| if (version == 100) { |
| symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_OES_standard_derivatives); |
| symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_OES_standard_derivatives); |
| symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_OES_standard_derivatives); |
| } |
| if (version >= 310) { |
| symbolTable.setFunctionExtensions("fma", Num_AEP_gpu_shader5, AEP_gpu_shader5); |
| symbolTable.setFunctionExtensions("interpolateAtCentroid", 1, &E_GL_OES_shader_multisample_interpolation); |
| symbolTable.setFunctionExtensions("interpolateAtSample", 1, &E_GL_OES_shader_multisample_interpolation); |
| symbolTable.setFunctionExtensions("interpolateAtOffset", 1, &E_GL_OES_shader_multisample_interpolation); |
| } |
| } else if (version < 130) { |
| symbolTable.setFunctionExtensions("texture1DLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture3DLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureCubeLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture1DProjLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DProjLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture3DProjLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow1DLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow1DProjLod", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DProjLod", 1, &E_GL_ARB_shader_texture_lod); |
| } |
| |
| // E_GL_ARB_shader_texture_lod functions usable only with the extension enabled |
| if (profile != EEsProfile) { |
| symbolTable.setFunctionExtensions("texture1DGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture1DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture3DGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture3DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("textureCubeGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow1DGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow1DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DRectGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("texture2DRectProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DRectGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| symbolTable.setFunctionExtensions("shadow2DRectProjGradARB", 1, &E_GL_ARB_shader_texture_lod); |
| } |
| |
| // E_GL_ARB_shader_image_load_store |
| if (profile != EEsProfile && version < 420) |
| symbolTable.setFunctionExtensions("memoryBarrier", 1, &E_GL_ARB_shader_image_load_store); |
| // All the image access functions are protected by checks on the type of the first argument. |
| |
| // E_GL_ARB_shader_atomic_counters |
| if (profile != EEsProfile && version < 420) { |
| symbolTable.setFunctionExtensions("atomicCounterIncrement", 1, &E_GL_ARB_shader_atomic_counters); |
| symbolTable.setFunctionExtensions("atomicCounterDecrement", 1, &E_GL_ARB_shader_atomic_counters); |
| symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters); |
| } |
| |
| // E_GL_ARB_derivative_control |
| if (profile != EEsProfile && version < 450) { |
| symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control); |
| symbolTable.setFunctionExtensions("dFdyFine", 1, &E_GL_ARB_derivative_control); |
| symbolTable.setFunctionExtensions("fwidthFine", 1, &E_GL_ARB_derivative_control); |
| symbolTable.setFunctionExtensions("dFdxCoarse", 1, &E_GL_ARB_derivative_control); |
| symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_ARB_derivative_control); |
| symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_ARB_derivative_control); |
| } |
| |
| symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth); |
| symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader); |
| symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader); |
| |
| if (profile == EEsProfile) { |
| symbolTable.setFunctionExtensions("imageAtomicAdd", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicMin", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicMax", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicAnd", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicOr", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicXor", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic); |
| symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); |
| } |
| break; |
| |
| case EShLangCompute: |
| BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable); |
| BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable); |
| BuiltInVariable("gl_WorkGroupID", EbvWorkGroupId, symbolTable); |
| BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); |
| BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); |
| BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); |
| break; |
| |
| default: |
| assert(false && "Language not supported"); |
| break; |
| } |
| |
| // |
| // Next, identify which built-ins have a mapping to an operator. |
| // If PureOperatorBuiltins is false, those that are not identified as such are |
| // expected to be resolved through a library of functions, versus as |
| // operations. |
| // |
| symbolTable.relateToOperator("not", EOpVectorLogicalNot); |
| |
| symbolTable.relateToOperator("matrixCompMult", EOpMul); |
| // 120 and 150 are correct for both ES and desktop |
| if (version >= 120) { |
| symbolTable.relateToOperator("outerProduct", EOpOuterProduct); |
| symbolTable.relateToOperator("transpose", EOpTranspose); |
| if (version >= 150) { |
| symbolTable.relateToOperator("determinant", EOpDeterminant); |
| symbolTable.relateToOperator("inverse", EOpMatrixInverse); |
| } |
| } |
| |
| symbolTable.relateToOperator("mod", EOpMod); |
| symbolTable.relateToOperator("modf", EOpModf); |
| |
| symbolTable.relateToOperator("equal", EOpVectorEqual); |
| symbolTable.relateToOperator("notEqual", EOpVectorNotEqual); |
| symbolTable.relateToOperator("lessThan", EOpLessThan); |
| symbolTable.relateToOperator("greaterThan", EOpGreaterThan); |
| symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual); |
| symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual); |
| |
| symbolTable.relateToOperator("radians", EOpRadians); |
| symbolTable.relateToOperator("degrees", EOpDegrees); |
| symbolTable.relateToOperator("sin", EOpSin); |
| symbolTable.relateToOperator("cos", EOpCos); |
| symbolTable.relateToOperator("tan", EOpTan); |
| symbolTable.relateToOperator("asin", EOpAsin); |
| symbolTable.relateToOperator("acos", EOpAcos); |
| symbolTable.relateToOperator("atan", EOpAtan); |
| symbolTable.relateToOperator("sinh", EOpSinh); |
| symbolTable.relateToOperator("cosh", EOpCosh); |
| symbolTable.relateToOperator("tanh", EOpTanh); |
| symbolTable.relateToOperator("asinh", EOpAsinh); |
| symbolTable.relateToOperator("acosh", EOpAcosh); |
| symbolTable.relateToOperator("atanh", EOpAtanh); |
| |
| symbolTable.relateToOperator("pow", EOpPow); |
| symbolTable.relateToOperator("exp2", EOpExp2); |
| symbolTable.relateToOperator("log", EOpLog); |
| symbolTable.relateToOperator("exp", EOpExp); |
| symbolTable.relateToOperator("log2", EOpLog2); |
| symbolTable.relateToOperator("sqrt", EOpSqrt); |
| symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt); |
| |
| symbolTable.relateToOperator("abs", EOpAbs); |
| symbolTable.relateToOperator("sign", EOpSign); |
| symbolTable.relateToOperator("floor", EOpFloor); |
| symbolTable.relateToOperator("trunc", EOpTrunc); |
| symbolTable.relateToOperator("round", EOpRound); |
| symbolTable.relateToOperator("roundEven", EOpRoundEven); |
| symbolTable.relateToOperator("ceil", EOpCeil); |
| symbolTable.relateToOperator("fract", EOpFract); |
| symbolTable.relateToOperator("min", EOpMin); |
| symbolTable.relateToOperator("max", EOpMax); |
| symbolTable.relateToOperator("clamp", EOpClamp); |
| symbolTable.relateToOperator("mix", EOpMix); |
| symbolTable.relateToOperator("step", EOpStep); |
| symbolTable.relateToOperator("smoothstep", EOpSmoothStep); |
| |
| symbolTable.relateToOperator("isnan", EOpIsNan); |
| symbolTable.relateToOperator("isinf", EOpIsInf); |
| |
| symbolTable.relateToOperator("floatBitsToInt", EOpFloatBitsToInt); |
| symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint); |
| symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat); |
| symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat); |
| |
| symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16); |
| symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); |
| symbolTable.relateToOperator("packUnorm2x16", EOpPackUnorm2x16); |
| symbolTable.relateToOperator("unpackUnorm2x16", EOpUnpackUnorm2x16); |
| |
| symbolTable.relateToOperator("packSnorm4x8", EOpPackSnorm4x8); |
| symbolTable.relateToOperator("unpackSnorm4x8", EOpUnpackSnorm4x8); |
| symbolTable.relateToOperator("packUnorm4x8", EOpPackUnorm4x8); |
| symbolTable.relateToOperator("unpackUnorm4x8", EOpUnpackUnorm4x8); |
| |
| symbolTable.relateToOperator("packDouble2x32", EOpPackUnorm4x8); |
| symbolTable.relateToOperator("unpackDouble2x32", EOpUnpackUnorm4x8); |
| |
| symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16); |
| symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16); |
| |
| symbolTable.relateToOperator("length", EOpLength); |
| symbolTable.relateToOperator("distance", EOpDistance); |
| symbolTable.relateToOperator("dot", EOpDot); |
| symbolTable.relateToOperator("cross", EOpCross); |
| symbolTable.relateToOperator("normalize", EOpNormalize); |
| symbolTable.relateToOperator("faceforward", EOpFaceForward); |
| symbolTable.relateToOperator("reflect", EOpReflect); |
| symbolTable.relateToOperator("refract", EOpRefract); |
| |
| symbolTable.relateToOperator("any", EOpAny); |
| symbolTable.relateToOperator("all", EOpAll); |
| |
| symbolTable.relateToOperator("barrier", EOpBarrier); |
| symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier); |
| symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); |
| symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer); |
| symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); |
| |
| symbolTable.relateToOperator("atomicAdd", EOpAtomicAdd); |
| symbolTable.relateToOperator("atomicMin", EOpAtomicMin); |
| symbolTable.relateToOperator("atomicMax", EOpAtomicMax); |
| symbolTable.relateToOperator("atomicAnd", EOpAtomicAnd); |
| symbolTable.relateToOperator("atomicOr", EOpAtomicOr); |
| symbolTable.relateToOperator("atomicXor", EOpAtomicXor); |
| symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange); |
| symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap); |
| |
| symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement); |
| symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); |
| symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); |
| |
| symbolTable.relateToOperator("fma", EOpFma); |
| symbolTable.relateToOperator("frexp", EOpFrexp); |
| symbolTable.relateToOperator("ldexp", EOpLdexp); |
| symbolTable.relateToOperator("uaddCarry", EOpAddCarry); |
| symbolTable.relateToOperator("usubBorrow", EOpSubBorrow); |
| symbolTable.relateToOperator("umulExtended", EOpUMulExtended); |
| symbolTable.relateToOperator("imulExtended", EOpIMulExtended); |
| symbolTable.relateToOperator("bitfieldExtract", EOpBitfieldExtract); |
| symbolTable.relateToOperator("bitfieldInsert", EOpBitfieldInsert); |
| symbolTable.relateToOperator("bitfieldReverse", EOpBitFieldReverse); |
| symbolTable.relateToOperator("bitCount", EOpBitCount); |
| symbolTable.relateToOperator("findLSB", EOpFindLSB); |
| symbolTable.relateToOperator("findMSB", EOpFindMSB); |
| |
| if (PureOperatorBuiltins) { |
| symbolTable.relateToOperator("imageSize", EOpImageQuerySize); |
| symbolTable.relateToOperator("imageSamples", EOpImageQuerySamples); |
| symbolTable.relateToOperator("imageLoad", EOpImageLoad); |
| symbolTable.relateToOperator("imageStore", EOpImageStore); |
| symbolTable.relateToOperator("imageAtomicAdd", EOpImageAtomicAdd); |
| symbolTable.relateToOperator("imageAtomicMin", EOpImageAtomicMin); |
| symbolTable.relateToOperator("imageAtomicMax", EOpImageAtomicMax); |
| symbolTable.relateToOperator("imageAtomicAnd", EOpImageAtomicAnd); |
| symbolTable.relateToOperator("imageAtomicOr", EOpImageAtomicOr); |
| symbolTable.relateToOperator("imageAtomicXor", EOpImageAtomicXor); |
| symbolTable.relateToOperator("imageAtomicExchange", EOpImageAtomicExchange); |
| symbolTable.relateToOperator("imageAtomicCompSwap", EOpImageAtomicCompSwap); |
| |
| symbolTable.relateToOperator("textureSize", EOpTextureQuerySize); |
| symbolTable.relateToOperator("textureQueryLod", EOpTextureQueryLod); |
| symbolTable.relateToOperator("textureQueryLevels", EOpTextureQueryLevels); |
| symbolTable.relateToOperator("textureSamples", EOpTextureQuerySamples); |
| symbolTable.relateToOperator("texture", EOpTexture); |
| symbolTable.relateToOperator("textureProj", EOpTextureProj); |
| symbolTable.relateToOperator("textureLod", EOpTextureLod); |
| symbolTable.relateToOperator("textureOffset", EOpTextureOffset); |
| symbolTable.relateToOperator("texelFetch", EOpTextureFetch); |
| symbolTable.relateToOperator("texelFetchOffset", EOpTextureFetchOffset); |
| symbolTable.relateToOperator("textureProjOffset", EOpTextureProjOffset); |
| symbolTable.relateToOperator("textureLodOffset", EOpTextureLodOffset); |
| symbolTable.relateToOperator("textureProjLod", EOpTextureProjLod); |
| symbolTable.relateToOperator("textureProjLodOffset", EOpTextureProjLodOffset); |
| symbolTable.relateToOperator("textureGrad", EOpTextureGrad); |
| symbolTable.relateToOperator("textureGradOffset", EOpTextureGradOffset); |
| symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); |
| symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); |
| symbolTable.relateToOperator("textureGather", EOpTextureGather); |
| symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); |
| symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); |
| |
| if (IncludeLegacy(version, profile) || (profile == EEsProfile && version == 100)) { |
| symbolTable.relateToOperator("ftransform", EOpFtransform); |
| |
| symbolTable.relateToOperator("texture1D", EOpTexture); |
| symbolTable.relateToOperator("texture1DGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("texture1DProj", EOpTextureProj); |
| symbolTable.relateToOperator("texture1DProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("texture1DLod", EOpTextureLod); |
| symbolTable.relateToOperator("texture1DProjLod", EOpTextureProjLod); |
| |
| symbolTable.relateToOperator("texture2DRect", EOpTexture); |
| symbolTable.relateToOperator("texture2DRectProj", EOpTextureProj); |
| symbolTable.relateToOperator("texture2DRectGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("texture2DRectProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("shadow2DRect", EOpTexture); |
| symbolTable.relateToOperator("shadow2DRectProj", EOpTextureProj); |
| symbolTable.relateToOperator("shadow2DRectGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("shadow2DRectProjGradARB", EOpTextureProjGrad); |
| |
| symbolTable.relateToOperator("texture2D", EOpTexture); |
| symbolTable.relateToOperator("texture2DProj", EOpTextureProj); |
| symbolTable.relateToOperator("texture2DGradEXT", EOpTextureGrad); |
| symbolTable.relateToOperator("texture2DGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("texture2DProjGradEXT", EOpTextureProjGrad); |
| symbolTable.relateToOperator("texture2DProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("texture2DLod", EOpTextureLod); |
| symbolTable.relateToOperator("texture2DLodEXT", EOpTextureLod); |
| symbolTable.relateToOperator("texture2DProjLod", EOpTextureProjLod); |
| symbolTable.relateToOperator("texture2DProjLodEXT", EOpTextureProjLod); |
| |
| symbolTable.relateToOperator("texture3D", EOpTexture); |
| symbolTable.relateToOperator("texture3DGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("texture3DProj", EOpTextureProj); |
| symbolTable.relateToOperator("texture3DProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("texture3DLod", EOpTextureLod); |
| symbolTable.relateToOperator("texture3DProjLod", EOpTextureProjLod); |
| symbolTable.relateToOperator("textureCube", EOpTexture); |
| symbolTable.relateToOperator("textureCubeGradEXT", EOpTextureGrad); |
| symbolTable.relateToOperator("textureCubeGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("textureCubeLod", EOpTextureLod); |
| symbolTable.relateToOperator("textureCubeLodEXT", EOpTextureLod); |
| symbolTable.relateToOperator("shadow1D", EOpTexture); |
| symbolTable.relateToOperator("shadow1DGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("shadow2D", EOpTexture); |
| symbolTable.relateToOperator("shadow2DGradARB", EOpTextureGrad); |
| symbolTable.relateToOperator("shadow1DProj", EOpTextureProj); |
| symbolTable.relateToOperator("shadow2DProj", EOpTextureProj); |
| symbolTable.relateToOperator("shadow1DProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("shadow2DProjGradARB", EOpTextureProjGrad); |
| symbolTable.relateToOperator("shadow1DLod", EOpTextureLod); |
| symbolTable.relateToOperator("shadow2DLod", EOpTextureLod); |
| symbolTable.relateToOperator("shadow1DProjLod", EOpTextureProjLod); |
| symbolTable.relateToOperator("shadow2DProjLod", EOpTextureProjLod); |
| } |
| } |
| |
| switch(language) { |
| case EShLangVertex: |
| break; |
| |
| case EShLangTessControl: |
| case EShLangTessEvaluation: |
| break; |
| |
| case EShLangGeometry: |
| symbolTable.relateToOperator("EmitStreamVertex", EOpEmitStreamVertex); |
| symbolTable.relateToOperator("EndStreamPrimitive", EOpEndStreamPrimitive); |
| symbolTable.relateToOperator("EmitVertex", EOpEmitVertex); |
| symbolTable.relateToOperator("EndPrimitive", EOpEndPrimitive); |
| break; |
| |
| case EShLangFragment: |
| symbolTable.relateToOperator("dFdx", EOpDPdx); |
| symbolTable.relateToOperator("dFdy", EOpDPdy); |
| symbolTable.relateToOperator("fwidth", EOpFwidth); |
| if (profile != EEsProfile && version >= 400) { |
| symbolTable.relateToOperator("dFdxFine", EOpDPdxFine); |
| symbolTable.relateToOperator("dFdyFine", EOpDPdyFine); |
| symbolTable.relateToOperator("fwidthFine", EOpFwidthFine); |
| symbolTable.relateToOperator("dFdxCoarse", EOpDPdxCoarse); |
| symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); |
| symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse); |
| } |
| symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid); |
| symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample); |
| symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset); |
| break; |
| |
| case EShLangCompute: |
| symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); |
| symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); |
| break; |
| |
| default: |
| assert(false && "Language not supported"); |
| } |
| } |
| |
| // |
| // Add context-dependent (resource-specific) built-ins not handled by the above. These |
| // would be ones that need to be programmatically added because they cannot |
| // be added by simple text strings. For these, also |
| // 1) Map built-in functions to operators, for those that will turn into an operation node |
| // instead of remaining a function call. |
| // 2) Tag extension-related symbols added to their base version with their extensions, so |
| // that if an early version has the extension turned off, there is an error reported on use. |
| // |
| void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) |
| { |
| if (profile != EEsProfile && version >= 430 && version < 440) { |
| symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); |
| symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); |
| } |
| if (profile != EEsProfile && version >= 130 && version < 420) { |
| symbolTable.setVariableExtensions("gl_MinProgramTexelOffset", 1, &E_GL_ARB_shading_language_420pack); |
| symbolTable.setVariableExtensions("gl_MaxProgramTexelOffset", 1, &E_GL_ARB_shading_language_420pack); |
| } |
| if (profile != EEsProfile && version >= 150 && version < 410) |
| symbolTable.setVariableExtensions("gl_MaxViewports", 1, &E_GL_ARB_viewport_array); |
| |
| switch(language) { |
| case EShLangFragment: |
| // Set up gl_FragData based on current array size. |
| if (version == 100 || IncludeLegacy(version, profile) || (! ForwardCompatibility && profile != EEsProfile && version < 420)) { |
| TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone; |
| TType fragData(EbtFloat, EvqFragColor, pq, 4); |
| TArraySizes& arraySizes = *new TArraySizes; |
| arraySizes.addInnerSize(resources.maxDrawBuffers); |
| fragData.newArraySizes(arraySizes); |
| symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); |
| SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); |
| } |
| break; |
| |
| case EShLangTessControl: |
| case EShLangTessEvaluation: |
| // Because of the context-dependent array size (gl_MaxPatchVertices), |
| // these variables were added later than the others and need to be mapped now. |
| |
| // standard members |
| BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); |
| BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); |
| BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); |
| BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); |
| |
| // compatibility members |
| BuiltInVariable("gl_in", "gl_ClipVertex", EbvClipVertex, symbolTable); |
| BuiltInVariable("gl_in", "gl_FrontColor", EbvFrontColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_BackColor", EbvBackColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); |
| BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); |
| BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| } // end namespace glslang |