// The format of this file:
//   C++ style single-line comments are supported.
//   Leading whitespace is only for formatting and doesn't have semantic meaning.
//
//   Grouping:
//   Groups of functions are denoted by "GROUP BEGIN" and "GROUP END". Groups can be nested.
//   Groups can have metadata related to the group itself. This is given at the end of the GROUP
//   BEGIN line in JSON object format.
//   Example:
//     GROUP BEGIN <group name> {"condition": "shaderType == GL_FRAGMENT_SHADER"}
//     GROUP END <group name>
//
//   Defaults:
//   Default metadata for functions can be set with "DEFAULT METADATA" followed by metadata in JSON
//   object format. The metadata is applied to all following functions regardless of grouping until
//   another "DEFAULT METADATA" line is encountered, or until the end of a top-level group.
//   Example:
//     DEFAULT METADATA {"op": "CallBuiltInFunction"}
//
//   Supported function metadata properties are:
//     "level"
//         string, one of COMMON_BUILTINS, ESSL1_BUILTINS, ESSL3_BUILTINS and ESSL3_1_BUILTINS.
//     "op"
//         string, either EOp code or "auto", in which case the op is derived from the function
//         name.
//     "suffix"
//         string, suffix that is used to disambiguate C++ variable names created based on the
//         function name from C++ keywords, or disambiguate two functions with the same name.
//     "extension"
//         string, GLSL extension where the function is defined.
//     "hasSideEffects"
//         boolean, can be used to mark a function as having side effects even if it has op other
//         than CallBuiltInFunction and it doesn't have out parameters. In case the op is
//         CallBuiltInFunction or the function has out parameters it is automatically treated as
//         having side effects.
//
//   Function declarations:
//   Lines that declare functions are in a similar format as in the GLSL spec:
//     <return type> <function name>(<param type>, ...);
//   Parameter types can have "out" or "inout" qualifiers.

GROUP BEGIN Trigonometric
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType radians(genType);
    genType degrees(genType);
    genType sin(genType);
    genType cos(genType);
    genType tan(genType);
    genType asin(genType);
    genType acos(genType);
    genType atan(genType, genType);
    genType atan(genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genType sinh(genType);
    genType cosh(genType);
    genType tanh(genType);
    genType asinh(genType);
    genType acosh(genType);
    genType atanh(genType);
GROUP END Trigonometric

GROUP BEGIN Exponential
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType pow(genType, genType);
    genType exp(genType);
    genType log(genType);
    genType exp2(genType);
    genType log2(genType);
    genType sqrt(genType);
    genType inversesqrt(genType);
GROUP END Exponential

GROUP BEGIN Common
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType abs(genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genIType abs(genIType);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType sign(genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genIType sign(genIType);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType floor(genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genType trunc(genType);
    genType round(genType);
    genType roundEven(genType);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType ceil(genType);
    genType fract(genType);
    genType mod(genType, float);
    genType mod(genType, genType);
    genType min(genType, float);
    genType min(genType, genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genIType min(genIType, genIType);
    genIType min(genIType, int);
    genUType min(genUType, genUType);
    genUType min(genUType, uint);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType max(genType, float);
    genType max(genType, genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genIType max(genIType, genIType);
    genIType max(genIType, int);
    genUType max(genUType, genUType);
    genUType max(genUType, uint);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType clamp(genType, float, float);
    genType clamp(genType, genType, genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genIType clamp(genIType, int, int);
    genIType clamp(genIType, genIType, genIType);
    genUType clamp(genUType, uint, uint);
    genUType clamp(genUType, genUType, genUType);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType mix(genType, genType, float);
    genType mix(genType, genType, genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genType mix(genType, genType, genBType);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    genType step(genType, genType);
    genType step(float, genType);
    genType smoothstep(genType, genType, genType);
    genType smoothstep(float, float, genType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    genType modf(genType, out genType);
    genBType isnan(genType);
    genBType isinf(genType);
    genIType floatBitsToInt(genType);
    genUType floatBitsToUint(genType);
    genType intBitsToFloat(genIType);
    genType uintBitsToFloat(genUType);
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto"}
    genType frexp(genType, out genIType);
    genType ldexp(genType, genIType);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    uint packSnorm2x16(vec2);
    uint packUnorm2x16(vec2);
    uint packHalf2x16(vec2);
    vec2 unpackSnorm2x16(uint);
    vec2 unpackUnorm2x16(uint);
    vec2 unpackHalf2x16(uint);
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto"}
    uint packUnorm4x8(vec4);
    uint packSnorm4x8(vec4);
    vec4 unpackUnorm4x8(uint);
    vec4 unpackSnorm4x8(uint);
GROUP END Common

GROUP BEGIN Geometric
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    float length(genType);
    float distance(genType, genType);
    float dot(genType, genType);
    vec3 cross(vec3, vec3);
    genType normalize(genType);
    genType faceforward(genType, genType, genType);
    genType reflect(genType, genType);
    genType refract(genType, genType, float);
GROUP END Geometric

GROUP BEGIN Matrix
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "MulMatrixComponentWise"}
    mat2 matrixCompMult(mat2, mat2);
    mat3 matrixCompMult(mat3, mat3);
    mat4 matrixCompMult(mat4, mat4);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "MulMatrixComponentWise"}
    mat2x3 matrixCompMult(mat2x3, mat2x3);
    mat3x2 matrixCompMult(mat3x2, mat3x2);
    mat2x4 matrixCompMult(mat2x4, mat2x4);
    mat4x2 matrixCompMult(mat4x2, mat4x2);
    mat3x4 matrixCompMult(mat3x4, mat3x4);
    mat4x3 matrixCompMult(mat4x3, mat4x3);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto"}
    mat2 outerProduct(vec2, vec2);
    mat3 outerProduct(vec3, vec3);
    mat4 outerProduct(vec4, vec4);
    mat2x3 outerProduct(vec3, vec2);
    mat3x2 outerProduct(vec2, vec3);
    mat2x4 outerProduct(vec4, vec2);
    mat4x2 outerProduct(vec2, vec4);
    mat3x4 outerProduct(vec4, vec3);
    mat4x3 outerProduct(vec3, vec4);
    mat2 transpose(mat2);
    mat3 transpose(mat3);
    mat4 transpose(mat4);
    mat2x3 transpose(mat3x2);
    mat3x2 transpose(mat2x3);
    mat2x4 transpose(mat4x2);
    mat4x2 transpose(mat2x4);
    mat3x4 transpose(mat4x3);
    mat4x3 transpose(mat3x4);
    float determinant(mat2);
    float determinant(mat3);
    float determinant(mat4);
    mat2 inverse(mat2);
    mat3 inverse(mat3);
    mat4 inverse(mat4);
GROUP END Matrix

GROUP BEGIN Vector
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "LessThanComponentWise"}
    bvec lessThan(vec, vec);
    bvec lessThan(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "LessThanComponentWise"}
    bvec lessThan(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "LessThanEqualComponentWise"}
    bvec lessThanEqual(vec, vec);
    bvec lessThanEqual(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "LessThanEqualComponentWise"}
    bvec lessThanEqual(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "GreaterThanComponentWise"}
    bvec greaterThan(vec, vec);
    bvec greaterThan(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "GreaterThanComponentWise"}
    bvec greaterThan(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "GreaterThanEqualComponentWise"}
    bvec greaterThanEqual(vec, vec);
    bvec greaterThanEqual(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "GreaterThanEqualComponentWise"}
    bvec greaterThanEqual(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "EqualComponentWise"}
    bvec equal(vec, vec);
    bvec equal(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "EqualComponentWise"}
    bvec equal(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "EqualComponentWise"}
    bvec equal(bvec, bvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "NotEqualComponentWise"}
    bvec notEqual(vec, vec);
    bvec notEqual(ivec, ivec);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "NotEqualComponentWise"}
    bvec notEqual(uvec, uvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "NotEqualComponentWise"}
    bvec notEqual(bvec, bvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "auto"}
    bool any(bvec);
    bool all(bvec);
  DEFAULT METADATA {"level": "COMMON_BUILTINS", "op": "LogicalNotComponentWise", "suffix": "Func"}
    bvec not(bvec);
GROUP END Vector

GROUP BEGIN Integer
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto"}
    genIType bitfieldExtract(genIType, int, int);
    genUType bitfieldExtract(genUType, int, int);
    genIType bitfieldInsert(genIType, genIType, int, int);
    genUType bitfieldInsert(genUType, genUType, int, int);
    genIType bitfieldReverse(genIType);
    genUType bitfieldReverse(genUType);
    genIType bitCount(genIType);
    genIType bitCount(genUType);
    genIType findLSB(genIType);
    genIType findLSB(genUType);
    genIType findMSB(genIType);
    genIType findMSB(genUType);
    genUType uaddCarry(genUType, genUType, out genUType);
    genUType usubBorrow(genUType, genUType, out genUType);
    void umulExtended(genUType, genUType, out genUType, out genUType);
    void imulExtended(genIType, genIType, out genIType, out genIType);
GROUP END Integer

GROUP BEGIN TextureESSL100
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction"}
    vec4 texture2D(sampler2D, vec2);
    vec4 texture2DProj(sampler2D, vec3);
    vec4 texture2DProj(sampler2D, vec4);
    vec4 textureCube(samplerCube, vec3);
GROUP END TextureESSL100

// These are extension functions from OES_EGL_image_external and
// NV_EGL_stream_consumer_external. We don't have a way to mark a built-in with two alternative
// extensions, so these are marked with none. This is fine, since these functions overload core
// function names and the functions require a samplerExternalOES parameter, which can only be
// created if one of the extensions is enabled.
// TODO(oetuaho): Consider implementing a cleaner solution.
GROUP BEGIN EGL_image_external
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction"}
    vec4 texture2D(samplerExternalOES, vec2);
    vec4 texture2DProj(samplerExternalOES, vec3);
    vec4 texture2DProj(samplerExternalOES, vec4);
GROUP END EGL_image_external

GROUP BEGIN ARB_texture_rectangle
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction", "extension": "ARB_texture_rectangle"}
    vec4 texture2DRect(sampler2DRect, vec2);
    vec4 texture2DRectProj(sampler2DRect, vec3);
    vec4 texture2DRectProj(sampler2DRect, vec4);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction", "extension": "ARB_texture_rectangle"}
    // We don't have a rectangle texture extension for OpenGL ES however based on the behavior of
    // rectangle texture in desktop OpenGL, they should be sampled with a "texture" overload in
    // GLSL version that have such an overload. This is the case for ESSL3 and above.
    vec4 texture(sampler2DRect, vec2);
    vec4 textureProj(sampler2DRect, vec3);
    vec4 textureProj(sampler2DRect, vec4);
GROUP END ARB_texture_rectangle

// The *Grad* variants are new to both vertex and fragment shaders; the fragment
// shader specific pieces are added separately below.
GROUP BEGIN EXT_shader_texture_lod
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction", "extension": "EXT_shader_texture_lod"}
    vec4 texture2DGradEXT(sampler2D, vec2, vec2, vec2);
    vec4 texture2DProjGradEXT(sampler2D, vec3, vec2, vec2);
    vec4 texture2DProjGradEXT(sampler2D, vec4, vec2, vec2);
    vec4 textureCubeGradEXT(samplerCube, vec3, vec3, vec3);
GROUP END EXT_shader_texture_lod

GROUP BEGIN TextureESSL100FS {"condition": "shaderType == GL_FRAGMENT_SHADER"}
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction"}
    vec4 texture2D(sampler2D, vec2, float);
    vec4 texture2DProj(sampler2D, vec3, float);
    vec4 texture2DProj(sampler2D, vec4, float);
    vec4 textureCube(samplerCube, vec3, float);
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "auto", "extension": "OES_standard_derivatives", "hasSideEffects": "true", "suffix": "Ext"}
    genType dFdx(genType);
    genType dFdy(genType);
    genType fwidth(genType);
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction", "extension": "EXT_shader_texture_lod"}
    vec4 texture2DLodEXT(sampler2D, vec2, float);
    vec4 texture2DProjLodEXT(sampler2D, vec3, float);
    vec4 texture2DProjLodEXT(sampler2D, vec4, float);
    vec4 textureCubeLodEXT(samplerCube, vec3, float);
GROUP END TextureESSL100FS

GROUP BEGIN TextureESSL100VS {"condition": "shaderType == GL_VERTEX_SHADER"}
  DEFAULT METADATA {"level": "ESSL1_BUILTINS", "op": "CallBuiltInFunction"}
    vec4 texture2DLod(sampler2D, vec2, float);
    vec4 texture2DProjLod(sampler2D, vec3, float);
    vec4 texture2DProjLod(sampler2D, vec4, float);
    vec4 textureCubeLod(samplerCube, vec3, float);
GROUP END TextureESSL100VS

GROUP BEGIN TextureESSL300
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 texture(gsampler2D, vec2);
    gvec4 texture(gsampler3D, vec3);
    gvec4 texture(gsamplerCube, vec3);
    gvec4 texture(gsampler2DArray, vec3);
    gvec4 textureProj(gsampler2D, vec3);
    gvec4 textureProj(gsampler2D, vec4);
    gvec4 textureProj(gsampler3D, vec4);
    gvec4 textureLod(gsampler2D, vec2, float);
    gvec4 textureLod(gsampler3D, vec3, float);
    gvec4 textureLod(gsamplerCube, vec3, float);
    gvec4 textureLod(gsampler2DArray, vec3, float);
    float texture(sampler2DShadow, vec3);
    float texture(samplerCubeShadow, vec4);
    float texture(sampler2DArrayShadow, vec4);
    float textureProj(sampler2DShadow, vec4);
    float textureLod(sampler2DShadow, vec3, float);
    ivec2 textureSize(gsampler2D, int);
    ivec3 textureSize(gsampler3D, int);
    ivec2 textureSize(gsamplerCube, int);
    ivec3 textureSize(gsampler2DArray, int);
    ivec2 textureSize(sampler2DShadow, int);
    ivec2 textureSize(samplerCubeShadow, int);
    ivec3 textureSize(sampler2DArrayShadow, int);
    ivec2 textureSize(gsampler2DMS);
    gvec4 textureProjLod(gsampler2D, vec3, float);
    gvec4 textureProjLod(gsampler2D, vec4, float);
    gvec4 textureProjLod(gsampler3D, vec4, float);
    float textureProjLod(sampler2DShadow, vec4, float);
    gvec4 texelFetch(gsampler2D, ivec2, int);
    gvec4 texelFetch(gsampler3D, ivec3, int);
    gvec4 texelFetch(gsampler2DArray, ivec3, int);
    gvec4 textureGrad(gsampler2D, vec2, vec2, vec2);
    gvec4 textureGrad(gsampler3D, vec3, vec3, vec3);
    gvec4 textureGrad(gsamplerCube, vec3, vec3, vec3);
    float textureGrad(sampler2DShadow, vec3, vec2, vec2);
    float textureGrad(samplerCubeShadow, vec4, vec3, vec3);
    gvec4 textureGrad(gsampler2DArray, vec3, vec2, vec2);
    float textureGrad(sampler2DArrayShadow, vec4, vec2, vec2);
    gvec4 textureProjGrad(gsampler2D, vec3, vec2, vec2);
    gvec4 textureProjGrad(gsampler2D, vec4, vec2, vec2);
    gvec4 textureProjGrad(gsampler3D, vec4, vec3, vec3);
    float textureProjGrad(sampler2DShadow, vec4, vec2, vec2);
GROUP END TextureESSL300

GROUP BEGIN TextureOffsetNoBias
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 textureOffset(gsampler2D, vec2, ivec2);
    gvec4 textureOffset(gsampler3D, vec3, ivec3);
    float textureOffset(sampler2DShadow, vec3, ivec2);
    gvec4 textureOffset(gsampler2DArray, vec3, ivec2);
    gvec4 textureProjOffset(gsampler2D, vec3, ivec2);
    gvec4 textureProjOffset(gsampler2D, vec4, ivec2);
    gvec4 textureProjOffset(gsampler3D, vec4, ivec3);
    float textureProjOffset(sampler2DShadow, vec4, ivec2);
    gvec4 textureLodOffset(gsampler2D, vec2, float, ivec2);
    gvec4 textureLodOffset(gsampler3D, vec3, float, ivec3);
    float textureLodOffset(sampler2DShadow, vec3, float, ivec2);
    gvec4 textureLodOffset(gsampler2DArray, vec3, float, ivec2);
    gvec4 textureProjLodOffset(gsampler2D, vec3, float, ivec2);
    gvec4 textureProjLodOffset(gsampler2D, vec4, float, ivec2);
    gvec4 textureProjLodOffset(gsampler3D, vec4, float, ivec3);
    float textureProjLodOffset(sampler2DShadow, vec4, float, ivec2);
    gvec4 texelFetchOffset(gsampler2D, ivec2, int, ivec2);
    gvec4 texelFetchOffset(gsampler3D, ivec3, int, ivec3);
    gvec4 texelFetchOffset(gsampler2DArray, ivec3, int, ivec2);
    gvec4 textureGradOffset(gsampler2D, vec2, vec2, vec2, ivec2);
    gvec4 textureGradOffset(gsampler3D, vec3, vec3, vec3, ivec3);
    float textureGradOffset(sampler2DShadow, vec3, vec2, vec2, ivec2);
    gvec4 textureGradOffset(gsampler2DArray, vec3, vec2, vec2, ivec2);
    float textureGradOffset(sampler2DArrayShadow, vec4, vec2, vec2, ivec2);
    gvec4 textureProjGradOffset(gsampler2D, vec3, vec2, vec2, ivec2);
    gvec4 textureProjGradOffset(gsampler2D, vec4, vec2, vec2, ivec2);
    gvec4 textureProjGradOffset(gsampler3D, vec4, vec3, vec3, ivec3);
    float textureProjGradOffset(sampler2DShadow, vec4, vec2, vec2, ivec2);
GROUP END TextureOffsetNoBias

GROUP BEGIN TextureOffsetBias {"condition": "shaderType == GL_FRAGMENT_SHADER"}
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 textureOffset(gsampler2D, vec2, ivec2, float);
    gvec4 textureOffset(gsampler3D, vec3, ivec3, float);
    float textureOffset(sampler2DShadow, vec3, ivec2, float);
    gvec4 textureOffset(gsampler2DArray, vec3, ivec2, float);
    gvec4 textureProjOffset(gsampler2D, vec3, ivec2, float);
    gvec4 textureProjOffset(gsampler2D, vec4, ivec2, float);
    gvec4 textureProjOffset(gsampler3D, vec4, ivec3, float);
    float textureProjOffset(sampler2DShadow, vec4, ivec2, float);
GROUP END TextureOffsetBias

GROUP BEGIN EGL_image_external_essl3
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction", "extension": "OES_EGL_image_external_essl3"}
    vec4 texture(samplerExternalOES, vec2);
    vec4 textureProj(samplerExternalOES, vec3);
    vec4 textureProj(samplerExternalOES, vec4);
    ivec2 textureSize(samplerExternalOES, int);
    vec4 texelFetch(samplerExternalOES, ivec2, int);
GROUP END EGL_image_external_essl3

GROUP BEGIN EXT_yuv_target
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction", "extension": "EXT_YUV_target"}
    vec4 texture(samplerExternal2DY2YEXT, vec2);
    vec4 textureProj(samplerExternal2DY2YEXT, vec3);
    vec4 textureProj(samplerExternal2DY2YEXT, vec4);
    vec3 rgb_2_yuv(vec3, yuvCscStandardEXT);
    vec3 yuv_2_rgb(vec3, yuvCscStandardEXT);
    ivec2 textureSize(samplerExternal2DY2YEXT, int);
    vec4 texelFetch(samplerExternal2DY2YEXT, ivec2, int);
GROUP END EXT_yuv_target

GROUP BEGIN TextureESSL300FS {"condition": "shaderType == GL_FRAGMENT_SHADER"}
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 texture(gsampler2D, vec2, float);
    gvec4 texture(gsampler3D, vec3, float);
    gvec4 texture(gsamplerCube, vec3, float);
    gvec4 texture(gsampler2DArray, vec3, float);
    gvec4 textureProj(gsampler2D, vec3, float);
    gvec4 textureProj(gsampler2D, vec4, float);
    gvec4 textureProj(gsampler3D, vec4, float);
    float texture(sampler2DShadow, vec3, float);
    float texture(samplerCubeShadow, vec4, float);
    float textureProj(sampler2DShadow, vec4, float);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction", "extension": "OES_EGL_image_external_essl3"}
    vec4 texture(samplerExternalOES, vec2, float);
    vec4 textureProj(samplerExternalOES, vec3, float);
    vec4 textureProj(samplerExternalOES, vec4, float);
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "CallBuiltInFunction", "extension": "EXT_YUV_target"}
    vec4 texture(samplerExternal2DY2YEXT, vec2, float);
    vec4 textureProj(samplerExternal2DY2YEXT, vec3, float);
    vec4 textureProj(samplerExternal2DY2YEXT, vec4, float);
GROUP END TextureESSL300FS

GROUP BEGIN TexelFetchMS
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 texelFetch(gsampler2DMS, ivec2, int);
GROUP END TexelFetchMS

GROUP BEGIN TextureGather
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction"}
    gvec4 textureGather(gsampler2D, vec2);
    gvec4 textureGather(gsampler2D, vec2, int);
    gvec4 textureGather(gsampler2DArray, vec3);
    gvec4 textureGather(gsampler2DArray, vec3, int);
    gvec4 textureGather(gsamplerCube, vec3);
    gvec4 textureGather(gsamplerCube, vec3, int);
    vec4 textureGather(sampler2DShadow, vec2);
    vec4 textureGather(sampler2DShadow, vec2, float);
    vec4 textureGather(sampler2DArrayShadow, vec3);
    vec4 textureGather(sampler2DArrayShadow, vec3, float);
    vec4 textureGather(samplerCubeShadow, vec3);
    vec4 textureGather(samplerCubeShadow, vec3, float);

    GROUP BEGIN Offset
        gvec4 textureGatherOffset(gsampler2D, vec2, ivec2);
        gvec4 textureGatherOffset(gsampler2D, vec2, ivec2, int);
        gvec4 textureGatherOffset(gsampler2DArray, vec3, ivec2);
        gvec4 textureGatherOffset(gsampler2DArray, vec3, ivec2, int);
        vec4 textureGatherOffset(sampler2DShadow, vec2, float, ivec2);
        vec4 textureGatherOffset(sampler2DArrayShadow, vec3, float, ivec2);
    GROUP END Offset
GROUP END TextureGather

GROUP BEGIN DerivativesESSL300FS {"condition": "shaderType == GL_FRAGMENT_SHADER"}
  DEFAULT METADATA {"level": "ESSL3_BUILTINS", "op": "auto", "hasSideEffects": "true"}
    genType dFdx(genType);
    genType dFdy(genType);
    genType fwidth(genType);
GROUP END DerivativesESSL300FS

GROUP BEGIN AtomicCounter
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction"}
    uint atomicCounter(atomic_uint);
    uint atomicCounterIncrement(atomic_uint);
    uint atomicCounterDecrement(atomic_uint);
GROUP END AtomicCounter

GROUP BEGIN AtomicMemory
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction"}
    uint atomicAdd(inout uint, uint);
    int atomicAdd(inout int, int);
    uint atomicMin(inout uint, uint);
    int atomicMin(inout int, int);
    uint atomicMax(inout uint, uint);
    int atomicMax(inout int, int);
    uint atomicAnd(inout uint, uint);
    int atomicAnd(inout int, int);
    uint atomicOr(inout uint, uint);
    int atomicOr(inout int, int);
    uint atomicXor(inout uint, uint);
    int atomicXor(inout int, int);
    uint atomicExchange(inout uint, uint);
    int atomicExchange(inout int, int);
    uint atomicCompSwap(inout uint, uint, uint);
    int atomicCompSwap(inout int, int, int);
GROUP END AtomicMemory

GROUP BEGIN Image
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction"}
    GROUP BEGIN Store
        void imageStore(gimage2D, ivec2, gvec4);
        void imageStore(gimage3D, ivec3, gvec4);
        void imageStore(gimage2DArray, ivec3, gvec4);
        void imageStore(gimageCube, ivec3, gvec4);
    GROUP END Store
    GROUP BEGIN Load
        gvec4 imageLoad(gimage2D, ivec2);
        gvec4 imageLoad(gimage3D, ivec3);
        gvec4 imageLoad(gimage2DArray, ivec3);
        gvec4 imageLoad(gimageCube, ivec3);
    GROUP END Load
    ivec2 imageSize(gimage2D);
    ivec3 imageSize(gimage3D);
    ivec3 imageSize(gimage2DArray);
    ivec2 imageSize(gimageCube);
GROUP END Image

GROUP BEGIN Barrier
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto", "hasSideEffects": true}
    void memoryBarrier();
    void memoryBarrierAtomicCounter();
    void memoryBarrierBuffer();
    void memoryBarrierImage();
GROUP END Barrier

GROUP BEGIN ESSL310CS {"condition": "shaderType == GL_COMPUTE_SHADER"}
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto", "hasSideEffects": true}
    void barrier();
    void memoryBarrierShared();
    void groupMemoryBarrier();
GROUP END ESSL310CS

GROUP BEGIN ESSL310GS {"condition": "shaderType == GL_GEOMETRY_SHADER_EXT"}
  DEFAULT METADATA {"level": "ESSL3_1_BUILTINS", "op": "auto", "extension": "EXT_geometry_shader", "hasSideEffects": true}
    void EmitVertex();
    void EndPrimitive();
GROUP END ESSL310GS
