Commit 140152e7 by Olli Etuaho Committed by Commit Bot

Statically allocate built-in function symbols

A script gen_builtin_symbols.py now generates code for initializing built-in function symbols. The TFunction objects are initialized at C++ compile time. The source file used for the functions is in a format that's similar to how functions are given out in the GLSL spec, so it is easy to maintain. The function symbols are still inserted to the symbol table levels same as before. Getting rid of inserting the symbols at runtime is intended to be done as follow-up. This speeds up angle_unittests on Linux in release mode by a bit less than half, and in debug mode by more than half. BUG=angleproject:2267 TEST=angle_unittests Change-Id: I11c9de98c74d28e7e8cdf024516e2f6ee30ca33e Reviewed-on: https://chromium-review.googlesource.com/924155 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d05f964b
...@@ -147,6 +147,15 @@ generators = { ...@@ -147,6 +147,15 @@ generators = {
], ],
'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', 'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
}, },
'ESSL static builtins': {
'inputs': [
'src/compiler/translator/builtin_function_declarations.txt',
],
'outputs': [
'src/compiler/translator/SymbolTable_autogen.cpp',
],
'script': 'src/compiler/translator/gen_builtin_symbols.py',
},
} }
root_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) root_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
......
...@@ -150,12 +150,12 @@ ...@@ -150,12 +150,12 @@
'compiler/translator/SimplifyLoopConditions.h', 'compiler/translator/SimplifyLoopConditions.h',
'compiler/translator/SplitSequenceOperator.cpp', 'compiler/translator/SplitSequenceOperator.cpp',
'compiler/translator/SplitSequenceOperator.h', 'compiler/translator/SplitSequenceOperator.h',
'compiler/translator/StaticType.cpp',
'compiler/translator/StaticType.h', 'compiler/translator/StaticType.h',
'compiler/translator/Symbol.cpp', 'compiler/translator/Symbol.cpp',
'compiler/translator/Symbol.h', 'compiler/translator/Symbol.h',
'compiler/translator/SymbolTable.cpp', 'compiler/translator/SymbolTable.cpp',
'compiler/translator/SymbolTable.h', 'compiler/translator/SymbolTable.h',
'compiler/translator/SymbolTable_autogen.cpp',
'compiler/translator/SymbolUniqueId.cpp', 'compiler/translator/SymbolUniqueId.cpp',
'compiler/translator/SymbolUniqueId.h', 'compiler/translator/SymbolUniqueId.h',
'compiler/translator/Types.cpp', 'compiler/translator/Types.cpp',
......
...@@ -57,16 +57,8 @@ enum TBasicType ...@@ -57,16 +57,8 @@ enum TBasicType
EbtInt, EbtInt,
EbtUInt, EbtUInt,
EbtBool, EbtBool,
EbtGVec4, // non type: represents vec4, ivec4, and uvec4
EbtGenType, // non type: represents float, vec2, vec3, and vec4
EbtGenIType, // non type: represents int, ivec2, ivec3, and ivec4
EbtGenUType, // non type: represents uint, uvec2, uvec3, and uvec4
EbtGenBType, // non type: represents bool, bvec2, bvec3, and bvec4
EbtVec, // non type: represents vec2, vec3, and vec4
EbtIVec, // non type: represents ivec2, ivec3, and ivec4
EbtUVec, // non type: represents uvec2, uvec3, and uvec4
EbtBVec, // non type: represents bvec2, bvec3, and bvec4
EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists. EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
EbtGuardSamplerBegin, // non type: see implementation of IsSampler() EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D, EbtSampler2D,
EbtSampler3D, EbtSampler3D,
...@@ -90,12 +82,6 @@ enum TBasicType ...@@ -90,12 +82,6 @@ enum TBasicType
EbtSamplerCubeShadow, EbtSamplerCubeShadow,
EbtSampler2DArrayShadow, EbtSampler2DArrayShadow,
EbtGuardSamplerEnd, // non type: see implementation of IsSampler() EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and
// usampler2DArray
EbtGSampler2DMS, // non type: represents sampler2DMS, isampler2DMS, and usampler2DMS
// images // images
EbtGuardImageBegin, EbtGuardImageBegin,
...@@ -113,13 +99,6 @@ enum TBasicType ...@@ -113,13 +99,6 @@ enum TBasicType
EbtUImageCube, EbtUImageCube,
EbtGuardImageEnd, EbtGuardImageEnd,
EbtGuardGImageBegin,
EbtGImage2D, // non type: represents image2D, uimage2D, iimage2D
EbtGImage3D, // non type: represents image3D, uimage3D, iimage3D
EbtGImage2DArray, // non type: represents image2DArray, uimage2DArray, iimage2DArray
EbtGImageCube, // non type: represents imageCube, uimageCube, iimageCube
EbtGuardGImageEnd,
EbtStruct, EbtStruct,
EbtInterfaceBlock, EbtInterfaceBlock,
EbtAddress, // should be deprecated?? EbtAddress, // should be deprecated??
...@@ -233,11 +212,6 @@ inline bool IsImage(TBasicType type) ...@@ -233,11 +212,6 @@ inline bool IsImage(TBasicType type)
return type > EbtGuardImageBegin && type < EbtGuardImageEnd; return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
} }
inline bool IsGImage(TBasicType type)
{
return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
}
inline bool IsAtomicCounter(TBasicType type) inline bool IsAtomicCounter(TBasicType type)
{ {
return type == EbtAtomicCounter; return type == EbtAtomicCounter;
......
//
// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Compile-time instances of many common TType values. These are looked up
// (statically or dynamically) through the methods defined in the namespace.
//
#include "compiler/translator/StaticType.h"
namespace sh
{
namespace StaticType
{
const TType *GetForFloatImage(TBasicType basicType)
{
switch (basicType)
{
case EbtGImage2D:
return Get<EbtImage2D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage3D:
return Get<EbtImage3D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage2DArray:
return Get<EbtImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImageCube:
return Get<EbtImageCube, EbpUndefined, EvqGlobal, 1, 1>();
default:
UNREACHABLE();
return GetBasic<EbtVoid>();
}
}
const TType *GetForIntImage(TBasicType basicType)
{
switch (basicType)
{
case EbtGImage2D:
return Get<EbtIImage2D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage3D:
return Get<EbtIImage3D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage2DArray:
return Get<EbtIImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImageCube:
return Get<EbtIImageCube, EbpUndefined, EvqGlobal, 1, 1>();
default:
UNREACHABLE();
return GetBasic<EbtVoid>();
}
}
const TType *GetForUintImage(TBasicType basicType)
{
switch (basicType)
{
case EbtGImage2D:
return Get<EbtUImage2D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage3D:
return Get<EbtUImage3D, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImage2DArray:
return Get<EbtUImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
case EbtGImageCube:
return Get<EbtUImageCube, EbpUndefined, EvqGlobal, 1, 1>();
default:
UNREACHABLE();
return GetBasic<EbtVoid>();
}
}
} // namespace StaticType
} // namespace sh
...@@ -213,12 +213,6 @@ constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size) ...@@ -213,12 +213,6 @@ constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size)
} }
} }
const TType *GetForFloatImage(TBasicType basicType);
const TType *GetForIntImage(TBasicType basicType);
const TType *GetForUintImage(TBasicType basicType);
} // namespace StaticType } // namespace StaticType
} // namespace sh } // namespace sh
......
...@@ -145,31 +145,6 @@ TFunction::TFunction(TSymbolTable *symbolTable, ...@@ -145,31 +145,6 @@ TFunction::TFunction(TSymbolTable *symbolTable,
ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal); ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
} }
TFunction::TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
TExtension extension,
TConstParameter *parameters,
size_t paramCount,
const TType *retType,
TOperator op,
bool knownToNotHaveSideEffects)
: TSymbol(symbolTable, name, SymbolType::BuiltIn, extension),
mParametersVector(nullptr),
mParameters(parameters),
mParamCount(paramCount),
returnType(retType),
mMangledName(""),
mOp(op),
defined(false),
mHasPrototypeDeclaration(false),
mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{
ASSERT(name != nullptr);
ASSERT(op != EOpNull);
ASSERT(paramCount == 0 || parameters != nullptr);
mMangledName = buildMangledName();
}
void TFunction::addParameter(const TConstParameter &p) void TFunction::addParameter(const TConstParameter &p)
{ {
ASSERT(mParametersVector); ASSERT(mParametersVector);
......
...@@ -205,16 +205,6 @@ class TFunction : public TSymbol ...@@ -205,16 +205,6 @@ class TFunction : public TSymbol
const TType *retType, const TType *retType,
bool knownToNotHaveSideEffects); bool knownToNotHaveSideEffects);
// Built-in function
TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
TExtension extension,
TConstParameter *parameters,
size_t paramCount,
const TType *retType,
TOperator op,
bool knownToNotHaveSideEffects);
bool isFunction() const override { return true; } bool isFunction() const override { return true; }
void addParameter(const TConstParameter &p); void addParameter(const TConstParameter &p);
...@@ -246,7 +236,7 @@ class TFunction : public TSymbol ...@@ -246,7 +236,7 @@ class TFunction : public TSymbol
bool isMain() const; bool isMain() const;
bool isImageFunction() const; bool isImageFunction() const;
private: // Note: Only to be used for static built-in functions!
constexpr TFunction(const TSymbolUniqueId &id, constexpr TFunction(const TSymbolUniqueId &id,
const ImmutableString &name, const ImmutableString &name,
TExtension extension, TExtension extension,
...@@ -269,6 +259,7 @@ class TFunction : public TSymbol ...@@ -269,6 +259,7 @@ class TFunction : public TSymbol
{ {
} }
private:
ImmutableString buildMangledName() const; ImmutableString buildMangledName() const;
typedef TVector<TConstParameter> TParamVector; typedef TVector<TConstParameter> TParamVector;
......
...@@ -67,7 +67,7 @@ class TSymbolTable::TSymbolTableBuiltInLevel ...@@ -67,7 +67,7 @@ class TSymbolTable::TSymbolTableBuiltInLevel
const TSymbol *find(const ImmutableString &name) const; const TSymbol *find(const ImmutableString &name) const;
void insertUnmangledBuiltIn(const char *name, TExtension ext); void insertUnmangledBuiltIn(const ImmutableString &name, TExtension ext);
const UnmangledBuiltIn *getUnmangledBuiltIn(const ImmutableString &name) const; const UnmangledBuiltIn *getUnmangledBuiltIn(const ImmutableString &name) const;
private: private:
...@@ -119,14 +119,12 @@ const TSymbol *TSymbolTable::TSymbolTableBuiltInLevel::find(const ImmutableStrin ...@@ -119,14 +119,12 @@ const TSymbol *TSymbolTable::TSymbolTableBuiltInLevel::find(const ImmutableStrin
return (*it).second; return (*it).second;
} }
void TSymbolTable::TSymbolTableBuiltInLevel::insertUnmangledBuiltIn(const char *name, void TSymbolTable::TSymbolTableBuiltInLevel::insertUnmangledBuiltIn(const ImmutableString &name,
TExtension ext) TExtension ext)
{ {
ImmutableString immName(name); if (ext == TExtension::UNDEFINED || mUnmangledBuiltIns.find(name) == mUnmangledBuiltIns.end())
if (ext == TExtension::UNDEFINED ||
mUnmangledBuiltIns.find(immName) == mUnmangledBuiltIns.end())
{ {
mUnmangledBuiltIns[immName] = UnmangledBuiltIn(ext); mUnmangledBuiltIns[name] = UnmangledBuiltIn(ext);
} }
} }
...@@ -263,85 +261,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, ...@@ -263,85 +261,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
return nullptr; return nullptr;
} }
constexpr bool IsGenType(const TType *type)
{
if (type)
{
TBasicType basicType = type->getBasicType();
return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
basicType == EbtGenBType;
}
return false;
}
constexpr bool IsVecType(const TType *type)
{
if (type)
{
TBasicType basicType = type->getBasicType();
return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
basicType == EbtBVec;
}
return false;
}
constexpr const TType *SpecificType(const TType *type, int size)
{
ASSERT(size >= 1 && size <= 4);
if (!type)
{
return nullptr;
}
ASSERT(!IsVecType(type));
switch (type->getBasicType())
{
case EbtGenType:
return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
static_cast<unsigned char>(size));
case EbtGenIType:
return StaticType::GetForVec<EbtInt>(type->getQualifier(),
static_cast<unsigned char>(size));
case EbtGenUType:
return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
static_cast<unsigned char>(size));
case EbtGenBType:
return StaticType::GetForVec<EbtBool>(type->getQualifier(),
static_cast<unsigned char>(size));
default:
return type;
}
}
constexpr const TType *VectorType(const TType *type, int size)
{
ASSERT(size >= 2 && size <= 4);
if (!type)
{
return nullptr;
}
ASSERT(!IsGenType(type));
switch (type->getBasicType())
{
case EbtVec:
return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
case EbtIVec:
return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
case EbtUVec:
return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
case EbtBVec:
return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
default:
return type;
}
}
bool TSymbolTable::declare(TSymbol *symbol) bool TSymbolTable::declare(TSymbol *symbol)
{ {
...@@ -432,220 +351,6 @@ void TSymbolTable::insertConstIvec3(ESymbolLevel level, ...@@ -432,220 +351,6 @@ void TSymbolTable::insertConstIvec3(ESymbolLevel level,
insertBuiltIn(level, constantIvec3); insertBuiltIn(level, constantIvec3);
} }
void TSymbolTable::insertBuiltIn(ESymbolLevel level,
TOperator op,
TExtension ext,
const TType *rvalue,
const char *name,
const TType *ptype1,
const TType *ptype2,
const TType *ptype3,
const TType *ptype4,
const TType *ptype5)
{
if (ptype1->getBasicType() == EbtGSampler2D)
{
insertUnmangledBuiltIn(name, ext, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
}
else if (ptype1->getBasicType() == EbtGSampler3D)
{
insertUnmangledBuiltIn(name, ext, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
}
else if (ptype1->getBasicType() == EbtGSamplerCube)
{
insertUnmangledBuiltIn(name, ext, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
}
else if (ptype1->getBasicType() == EbtGSampler2DArray)
{
insertUnmangledBuiltIn(name, ext, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
ptype5);
}
else if (ptype1->getBasicType() == EbtGSampler2DMS)
{
insertUnmangledBuiltIn(name, ext, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
}
else if (IsGImage(ptype1->getBasicType()))
{
insertUnmangledBuiltIn(name, ext, level);
const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
const TType *intType = StaticType::GetBasic<EbtInt, 4>();
const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
// GLSL ES 3.10, Revision 4, 8.12 Image Functions
if (rvalue->getBasicType() == EbtGVec4)
{
// imageLoad
insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
}
else if (rvalue->getBasicType() == EbtVoid)
{
// imageStore
insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
}
else
{
// imageSize
insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
}
}
else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
IsGenType(ptype4))
{
ASSERT(!ptype5);
insertUnmangledBuiltIn(name, ext, level);
insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
}
else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
{
ASSERT(!ptype4 && !ptype5);
insertUnmangledBuiltIn(name, ext, level);
insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
VectorType(ptype2, 2), VectorType(ptype3, 2));
insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
VectorType(ptype2, 3), VectorType(ptype3, 3));
insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
VectorType(ptype2, 4), VectorType(ptype3, 4));
}
else
{
size_t paramCount = 1;
TConstParameter *params = new TConstParameter[5];
new (params) TConstParameter(ptype1);
if (ptype2)
{
new (params + 1) TConstParameter(ptype2);
paramCount = 2;
}
if (ptype3)
{
new (params + 2) TConstParameter(ptype3);
paramCount = 3;
}
if (ptype4)
{
new (params + 3) TConstParameter(ptype4);
paramCount = 4;
}
if (ptype5)
{
new (params + 4) TConstParameter(ptype5);
paramCount = 5;
}
TFunction *function =
new TFunction(this, ImmutableString(name), ext, params, paramCount, rvalue, op, false);
ASSERT(hasUnmangledBuiltInAtLevel(name, level));
insertBuiltIn(level, function);
}
}
void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
TOperator op,
const TType *rvalue,
const TType *ptype1,
const TType *ptype2,
const TType *ptype3,
const TType *ptype4,
const TType *ptype5)
{
const char *name = GetOperatorString(op);
ASSERT(strlen(name) > 0);
insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
ptype5);
}
void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
TOperator op,
TExtension ext,
const TType *rvalue,
const TType *ptype1,
const TType *ptype2,
const TType *ptype3,
const TType *ptype4,
const TType *ptype5)
{
const char *name = GetOperatorString(op);
insertUnmangledBuiltIn(name, ext, level);
insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
}
void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
TOperator op,
const TType *rvalue,
const char *name)
{
insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
insertBuiltIn(level, new TFunction(this, ImmutableString(name), TExtension::UNDEFINED, nullptr, 0,
rvalue, op, false));
}
void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
TExtension ext,
TOperator op,
const TType *rvalue,
const char *name)
{
insertUnmangledBuiltIn(name, ext, level);
insertBuiltIn(level, new TFunction(this, ImmutableString(name), ext, nullptr, 0, rvalue, op, false));
}
void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec) void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
{ {
int indexOfLastElement = static_cast<int>(mPrecisionStack.size()) - 1; int indexOfLastElement = static_cast<int>(mPrecisionStack.size()) - 1;
...@@ -696,7 +401,9 @@ void TSymbolTable::setGlobalInvariant(bool invariant) ...@@ -696,7 +401,9 @@ void TSymbolTable::setGlobalInvariant(bool invariant)
mTable.back()->setGlobalInvariant(invariant); mTable.back()->setGlobalInvariant(invariant);
} }
void TSymbolTable::insertUnmangledBuiltIn(const char *name, TExtension ext, ESymbolLevel level) void TSymbolTable::insertUnmangledBuiltIn(const ImmutableString &name,
TExtension ext,
ESymbolLevel level)
{ {
ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL); ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL);
ASSERT(mUserDefinedUniqueIdsStart == -1); ASSERT(mUserDefinedUniqueIdsStart == -1);
...@@ -798,7 +505,10 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type, ...@@ -798,7 +505,10 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type,
setDefaultPrecision(EbtAtomicCounter, EbpHigh); setDefaultPrecision(EbtAtomicCounter, EbpHigh);
initializeBuiltInFunctions(type); insertBuiltInFunctions(type);
insertBuiltInFunctionUnmangledNames(type);
mUniqueIdCounter = kLastStaticBuiltInId + 1;
initializeBuiltInVariables(type, spec, resources); initializeBuiltInVariables(type, spec, resources);
markBuiltInInitializationFinished(); markBuiltInInitializationFinished();
} }
...@@ -809,620 +519,6 @@ void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType) ...@@ -809,620 +519,6 @@ void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
setDefaultPrecision(samplerType, EbpLow); setDefaultPrecision(samplerType, EbpLow);
} }
void TSymbolTable::initializeBuiltInFunctions(sh::GLenum type)
{
const TType *voidType = StaticType::GetBasic<EbtVoid>();
const TType *float1 = StaticType::GetBasic<EbtFloat>();
const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
const TType *float3 = StaticType::GetBasic<EbtFloat, 3>();
const TType *float4 = StaticType::GetBasic<EbtFloat, 4>();
const TType *int1 = StaticType::GetBasic<EbtInt>();
const TType *int2 = StaticType::GetBasic<EbtInt, 2>();
const TType *int3 = StaticType::GetBasic<EbtInt, 3>();
const TType *uint1 = StaticType::GetBasic<EbtUInt>();
const TType *bool1 = StaticType::GetBasic<EbtBool>();
const TType *genType = StaticType::GetBasic<EbtGenType>();
const TType *genIType = StaticType::GetBasic<EbtGenIType>();
const TType *genUType = StaticType::GetBasic<EbtGenUType>();
const TType *genBType = StaticType::GetBasic<EbtGenBType>();
//
// Angle and Trigonometric Functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpTan, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpAsin, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpAcos, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpSinh, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpCosh, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpTanh, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpAsinh, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpAcosh, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpAtanh, genType, genType);
//
// Exponential Functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpPow, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpExp, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpLog, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpExp2, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpLog2, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpSqrt, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpInversesqrt, genType, genType);
//
// Common Functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpAbs, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpAbs, genIType, genIType);
insertBuiltInOp(COMMON_BUILTINS, EOpSign, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpSign, genIType, genIType);
insertBuiltInOp(COMMON_BUILTINS, EOpFloor, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpTrunc, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpRound, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpRoundEven, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpCeil, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpFract, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, float1);
insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, float1);
insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, genIType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, int1);
insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, genUType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, uint1);
insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, float1);
insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, genIType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, int1);
insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, genUType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, uint1);
insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, float1, float1);
insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, int1, int1);
insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, genIType, genIType);
insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, uint1, uint1);
insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, genUType, genUType);
insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1);
insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType);
insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpSmoothstep, genType, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpSmoothstep, genType, float1, float1, genType);
const TType *outGenType = StaticType::GetQualified<EbtGenType, EvqOut>();
const TType *outGenIType = StaticType::GetQualified<EbtGenIType, EvqOut>();
insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType);
insertBuiltInOp(ESSL3_BUILTINS, EOpIsnan, genBType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpIsinf, genBType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType);
insertBuiltInOp(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, genUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpFrexp, genType, genType, outGenIType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpLdexp, genType, genType, genIType);
insertBuiltInOp(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, uint1);
insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
//
// Geometric Functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpLength, float1, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpDistance, float1, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3);
insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType);
insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1);
const TType *mat2 = StaticType::GetBasic<EbtFloat, 2, 2>();
const TType *mat3 = StaticType::GetBasic<EbtFloat, 3, 3>();
const TType *mat4 = StaticType::GetBasic<EbtFloat, 4, 4>();
const TType *mat2x3 = StaticType::GetBasic<EbtFloat, 2, 3>();
const TType *mat3x2 = StaticType::GetBasic<EbtFloat, 3, 2>();
const TType *mat2x4 = StaticType::GetBasic<EbtFloat, 2, 4>();
const TType *mat4x2 = StaticType::GetBasic<EbtFloat, 4, 2>();
const TType *mat3x4 = StaticType::GetBasic<EbtFloat, 3, 4>();
const TType *mat4x3 = StaticType::GetBasic<EbtFloat, 4, 3>();
//
// Matrix Functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2);
insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3);
insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x2, mat3x2, mat3x2);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x4, mat2x4, mat2x4);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x2, mat4x2, mat4x2);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x4, mat3x4, mat3x4);
insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x3, mat4x3, mat4x3);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2, float2, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3, float3, float3);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4, float4, float4);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, float3, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, float2, float3);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, float4, float2);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, float2, float4);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, float4, float3);
insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, float3, float4);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2, mat2);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3, mat3);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4, mat4);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x3, mat3x2);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x2, mat2x3);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x4, mat4x2);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x2, mat2x4);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x4, mat4x3);
insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x3, mat3x4);
insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2);
insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3);
insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4);
insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2);
insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3);
insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4);
const TType *vec = StaticType::GetBasic<EbtVec>();
const TType *ivec = StaticType::GetBasic<EbtIVec>();
const TType *uvec = StaticType::GetBasic<EbtUVec>();
const TType *bvec = StaticType::GetBasic<EbtBVec>();
//
// Vector relational functions.
//
insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanEqualComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpEqualComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, bvec, bvec);
insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, vec, vec);
insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, ivec, ivec);
insertBuiltInOp(ESSL3_BUILTINS, EOpNotEqualComponentWise, bvec, uvec, uvec);
insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec);
insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec);
insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec);
insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec);
//
// Integer functions
//
const TType *outGenUType = StaticType::GetQualified<EbtGenUType, EvqOut>();
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1, int1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1, int1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType, int1, int1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType, int1, int1);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genIType, genIType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genUType, genUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genIType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genIType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genIType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpUaddCarry, genUType, genUType, genUType, outGenUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType, outGenUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType, outGenUType,
outGenUType);
insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType, outGenIType,
outGenIType);
const TType *sampler2D = StaticType::GetBasic<EbtSampler2D>();
const TType *samplerCube = StaticType::GetBasic<EbtSamplerCube>();
const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
//
// Texture Functions for GLSL ES 1.0
//
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
// 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.
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
// Note that ARB_texture_rectangle extension directive defaults to enabled in case the extension
// is supported. The symbols are still conditional on the extension.
const TType *sampler2DRect = StaticType::GetBasic<EbtSampler2DRect>();
insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRect",
sampler2DRect, float2);
insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRectProj",
sampler2DRect, float3);
insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRectProj",
sampler2DRect, float4);
/* The *Grad* variants are new to both vertex and fragment shaders; the fragment
* shader specific pieces are added separately below.
*/
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "texture2DGradEXT",
sampler2D, float2, float2, float2);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
"texture2DProjGradEXT", sampler2D, float3, float2, float2);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
"texture2DProjGradEXT", sampler2D, float4, float2, float2);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "textureCubeGradEXT",
samplerCube, float3, float3, float3);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1);
insertBuiltInOp(ESSL1_BUILTINS, EOpDFdx, TExtension::OES_standard_derivatives, genType,
genType);
insertBuiltInOp(ESSL1_BUILTINS, EOpDFdy, TExtension::OES_standard_derivatives, genType,
genType);
insertBuiltInOp(ESSL1_BUILTINS, EOpFwidth, TExtension::OES_standard_derivatives, genType,
genType);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "texture2DLodEXT",
sampler2D, float2, float1);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
"texture2DProjLodEXT", sampler2D, float3, float1);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
"texture2DProjLodEXT", sampler2D, float4, float1);
insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
"textureCubeLodEXT", samplerCube, float3, float1);
}
if (type == GL_VERTEX_SHADER)
{
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, float1);
insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1);
}
const TType *gvec4 = StaticType::GetBasic<EbtGVec4>();
const TType *gsampler2D = StaticType::GetBasic<EbtGSampler2D>();
const TType *gsamplerCube = StaticType::GetBasic<EbtGSamplerCube>();
const TType *gsampler3D = StaticType::GetBasic<EbtGSampler3D>();
const TType *gsampler2DArray = StaticType::GetBasic<EbtGSampler2DArray>();
const TType *gsampler2DMS = StaticType::GetBasic<EbtGSampler2DMS>();
//
// Texture Functions for GLSL ES 3.0
//
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texture",
samplerExternalOES, float2);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "textureProj",
samplerExternalOES, float3);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "textureProj",
samplerExternalOES, float4);
const TType *samplerExternal2DY2YEXT = StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
samplerExternal2DY2YEXT, float2);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
samplerExternal2DY2YEXT, float3);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
samplerExternal2DY2YEXT, float4);
const TType *yuvCscStandardEXT = StaticType::GetBasic<EbtYuvCscStandardEXT>();
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv", float3,
yuvCscStandardEXT);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb", float3,
yuvCscStandardEXT);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texture",
samplerExternalOES, float2, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4,
"textureProj", samplerExternalOES, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4,
"textureProj", samplerExternalOES, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
samplerExternal2DY2YEXT, float2, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
samplerExternal2DY2YEXT, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
samplerExternal2DY2YEXT, float4, float1);
}
const TType *sampler2DShadow = StaticType::GetBasic<EbtSampler2DShadow>();
const TType *samplerCubeShadow = StaticType::GetBasic<EbtSamplerCubeShadow>();
const TType *sampler2DArrayShadow = StaticType::GetBasic<EbtSampler2DArrayShadow>();
insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, float1);
}
insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1);
insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1);
insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1);
insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, int2, "textureSize",
samplerExternalOES, int1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize",
samplerExternal2DY2YEXT, int1);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpDFdy, genType, genType);
insertBuiltInOp(ESSL3_BUILTINS, EOpFwidth, genType, genType);
}
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2,
float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2,
float1);
}
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
if (type == GL_FRAGMENT_SHADER)
{
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3, float1);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2,
float1);
}
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, float1,
int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, float1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, float1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, float1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1,
int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texelFetch",
samplerExternalOES, int2, int1);
insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch",
samplerExternal2DY2YEXT, int2, int1);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2,
float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, float2, float2,
int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, float3, float3,
int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, float2,
float2, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, float2,
float2, int2);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, float4, float2,
float2, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, float3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, float2,
float2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, float2,
float2, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, float2,
float2, int2);
insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3,
float3, int3);
insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2,
float2, int2);
const TType *atomicCounter = StaticType::GetBasic<EbtAtomicCounter>();
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter);
// Insert all atomic memory functions
const TType *int1InOut = StaticType::GetQualified<EbtInt, EvqInOut>();
const TType *uint1InOut = StaticType::GetQualified<EbtUInt, EvqInOut>();
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1);
insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1);
insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicCompSwap", int1InOut, int1, int1);
const TType *gimage2D = StaticType::GetBasic<EbtGImage2D>();
const TType *gimage3D = StaticType::GetBasic<EbtGImage3D>();
const TType *gimage2DArray = StaticType::GetBasic<EbtGImage2DArray>();
const TType *gimageCube = StaticType::GetBasic<EbtGImageCube>();
insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimageCube);
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrier, voidType,
"memoryBarrier");
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierAtomicCounter, voidType,
"memoryBarrierAtomicCounter");
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierBuffer, voidType,
"memoryBarrierBuffer");
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierImage, voidType,
"memoryBarrierImage");
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "texelFetch", gsampler2DMS, int2, int1);
// Insert all variations of textureGather.
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2, int1);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3, int1);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3, int1);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2, float1);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3, float1);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3, float1);
// Insert all variations of textureGatherOffset.
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2, int1);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2);
insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2,
int1);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DShadow, float2, float1,
int2);
insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DArrayShadow, float3,
float1, int2);
if (type == GL_COMPUTE_SHADER)
{
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType, "barrier");
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared, voidType,
"memoryBarrierShared");
insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier, voidType,
"groupMemoryBarrier");
}
if (type == GL_GEOMETRY_SHADER_EXT)
{
TExtension extension = TExtension::EXT_geometry_shader;
insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex, voidType,
"EmitVertex");
insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEndPrimitive, voidType,
"EndPrimitive");
}
}
void TSymbolTable::initializeBuiltInVariables(sh::GLenum type, void TSymbolTable::initializeBuiltInVariables(sh::GLenum type,
ShShaderSpec spec, ShShaderSpec spec,
......
...@@ -163,78 +163,6 @@ class TSymbolTable : angle::NonCopyable ...@@ -163,78 +163,6 @@ class TSymbolTable : angle::NonCopyable
const ImmutableString &name, const ImmutableString &name,
const std::array<int, 3> &values); const std::array<int, 3> &values);
// Note that for inserted built-in functions the const char *name needs to remain valid for the
// lifetime of the SymbolTable. SymbolTable does not allocate a copy of it.
void insertBuiltIn(ESymbolLevel level,
TOperator op,
TExtension ext,
const TType *rvalue,
const char *name,
const TType *ptype1,
const TType *ptype2 = 0,
const TType *ptype3 = 0,
const TType *ptype4 = 0,
const TType *ptype5 = 0);
void insertBuiltIn(ESymbolLevel level,
const TType *rvalue,
const char *name,
const TType *ptype1,
const TType *ptype2 = 0,
const TType *ptype3 = 0,
const TType *ptype4 = 0,
const TType *ptype5 = 0)
{
insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
insertBuiltIn(level, EOpCallBuiltInFunction, TExtension::UNDEFINED, rvalue, name, ptype1,
ptype2, ptype3, ptype4, ptype5);
}
void insertBuiltIn(ESymbolLevel level,
TExtension ext,
const TType *rvalue,
const char *name,
const TType *ptype1,
const TType *ptype2 = 0,
const TType *ptype3 = 0,
const TType *ptype4 = 0,
const TType *ptype5 = 0)
{
insertUnmangledBuiltIn(name, ext, level);
insertBuiltIn(level, EOpCallBuiltInFunction, ext, rvalue, name, ptype1, ptype2, ptype3,
ptype4, ptype5);
}
void insertBuiltInOp(ESymbolLevel level,
TOperator op,
const TType *rvalue,
const TType *ptype1,
const TType *ptype2 = 0,
const TType *ptype3 = 0,
const TType *ptype4 = 0,
const TType *ptype5 = 0);
void insertBuiltInOp(ESymbolLevel level,
TOperator op,
TExtension ext,
const TType *rvalue,
const TType *ptype1,
const TType *ptype2 = 0,
const TType *ptype3 = 0,
const TType *ptype4 = 0,
const TType *ptype5 = 0);
void insertBuiltInFunctionNoParameters(ESymbolLevel level,
TOperator op,
const TType *rvalue,
const char *name);
void insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
TExtension ext,
TOperator op,
const TType *rvalue,
const char *name);
TVariable *insertVariable(ESymbolLevel level, TVariable *insertVariable(ESymbolLevel level,
const ImmutableString &name, const ImmutableString &name,
const TType *type, const TType *type,
...@@ -246,18 +174,20 @@ class TSymbolTable : angle::NonCopyable ...@@ -246,18 +174,20 @@ class TSymbolTable : angle::NonCopyable
// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
// above. // above.
void insertUnmangledBuiltIn(const char *name, TExtension ext, ESymbolLevel level); void insertUnmangledBuiltIn(const ImmutableString &name, TExtension ext, ESymbolLevel level);
bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level); bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level);
void initSamplerDefaultPrecision(TBasicType samplerType); void initSamplerDefaultPrecision(TBasicType samplerType);
void initializeBuiltInFunctions(sh::GLenum type);
void initializeBuiltInVariables(sh::GLenum type, void initializeBuiltInVariables(sh::GLenum type,
ShShaderSpec spec, ShShaderSpec spec,
const ShBuiltInResources &resources); const ShBuiltInResources &resources);
void markBuiltInInitializationFinished(); void markBuiltInInitializationFinished();
void insertBuiltInFunctions(sh::GLenum shaderType);
void insertBuiltInFunctionUnmangledNames(sh::GLenum shaderType);
std::vector<std::unique_ptr<TSymbolTableBuiltInLevel>> mBuiltInTable; std::vector<std::unique_ptr<TSymbolTableBuiltInLevel>> mBuiltInTable;
std::vector<std::unique_ptr<TSymbolTableLevel>> mTable; std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
...@@ -268,6 +198,8 @@ class TSymbolTable : angle::NonCopyable ...@@ -268,6 +198,8 @@ class TSymbolTable : angle::NonCopyable
int mUniqueIdCounter; int mUniqueIdCounter;
static const int kLastStaticBuiltInId;
// -1 before built-in init has finished, one past the last built-in id afterwards. // -1 before built-in init has finished, one past the last built-in id afterwards.
// TODO(oetuaho): Make this a compile-time constant once the symbol table is initialized at // TODO(oetuaho): Make this a compile-time constant once the symbol table is initialized at
// compile time. http://anglebug.com/1432 // compile time. http://anglebug.com/1432
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -20,7 +20,6 @@ class TSymbolUniqueId ...@@ -20,7 +20,6 @@ class TSymbolUniqueId
{ {
public: public:
POOL_ALLOCATOR_NEW_DELETE(); POOL_ALLOCATOR_NEW_DELETE();
explicit TSymbolUniqueId(TSymbolTable *symbolTable);
explicit TSymbolUniqueId(const TSymbol &symbol); explicit TSymbolUniqueId(const TSymbol &symbol);
constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default; constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default;
TSymbolUniqueId &operator=(const TSymbolUniqueId &); TSymbolUniqueId &operator=(const TSymbolUniqueId &);
...@@ -29,6 +28,10 @@ class TSymbolUniqueId ...@@ -29,6 +28,10 @@ class TSymbolUniqueId
int get() const; int get() const;
private: private:
friend class TSymbolTable;
explicit TSymbolUniqueId(TSymbolTable *symbolTable);
friend class BuiltInId;
constexpr TSymbolUniqueId(int staticId) : mId(staticId) {} constexpr TSymbolUniqueId(int staticId) : mId(staticId) {}
int mId; int mId;
......
// 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);
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
#!/usr/bin/python
# Copyright 2018 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_builtin_symbols.py:
# Code generation for the built-in symbol tables.
from collections import OrderedDict
from datetime import date
import argparse
import json
import re
import os
def set_working_dir():
script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)
set_working_dir()
parser = argparse.ArgumentParser()
parser.add_argument('--dump-intermediate-json', help='Dump parsed function data as a JSON file builtin_functions.json', action="store_true")
args = parser.parse_args()
# By having the variables defined in a cpp file we ensure that there's just one instance of each of the declared variables.
template_symboltable_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SymbolTable_autogen.cpp:
// Compile-time initialized built-ins.
#include "compiler/translator/SymbolTable.h"
#include "angle_gl.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolUniqueId.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
{{
// This is a class instead of a namespace so that we can restrict access to TSymbolUniqueId
// constructor taking an integer to here.
class BuiltInId
{{
public:
{builtin_id_declarations}
}};
const int TSymbolTable::kLastStaticBuiltInId = {last_static_builtin_id};
namespace BuiltInName
{{
{name_declarations}
}} // namespace BuiltInName
namespace BuiltInParameters
{{
{parameter_declarations}
}} // namespace BuiltInParameters
// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
// this from TFunction. Now symbol constructors taking an id have to be public even though they're
// not supposed to be accessible from outside of here. http://anglebug.com/2390
namespace BuiltInFunction
{{
{function_declarations}
}} // namespace BuiltInFunction
void TSymbolTable::insertBuiltInFunctions(sh::GLenum shaderType)
{{
{insert_functions}
}}
void TSymbolTable::insertBuiltInFunctionUnmangledNames(sh::GLenum shaderType)
{{
{insert_unmangled_functions}
}}
}} // namespace sh
"""
functions_txt_filename = 'builtin_function_declarations.txt'
basic_mangled_names = {
'Float': 'f',
'Int': 'i',
'UInt': 'u',
'Bool': 'b',
'YuvCscStandardEXT': 'y',
'Sampler2D': 's2',
'Sampler3D': 's3',
'SamplerCube': 'sC',
'Sampler2DArray': 'sA',
'SamplerExternalOES': 'sX',
'SamplerExternal2DY2YEXT': 'sY',
'Sampler2DRect': 'sR',
'Sampler2DMS': 'sM',
'ISampler2D': 'is2',
'ISampler3D': 'is3',
'ISamplerCube': 'isC',
'ISampler2DArray': 'isA',
'ISampler2DMS': 'isM',
'USampler2D': 'us2',
'USampler3D': 'us3',
'USamplerCube': 'usC',
'USampler2DArray': 'usA',
'USampler2DMS': 'usM',
'Sampler2DShadow': 's2s',
'SamplerCubeShadow': 'sCs',
'Sampler2DArrayShadow': 'sAs',
'Image2D': 'I2',
'IImage2D': 'iI2',
'UImage2D': 'uI2',
'Image3D': 'I3',
'IImage3D': 'iI3',
'UImage3D': 'uI3',
'Image2DArray': 'IA',
'IImage2DArray': 'iIA',
'UImage2DArray': 'uIA',
'ImageCube': 'Ic',
'IImageCube': 'iIc',
'UImageCube': 'uIc',
'AtomicCounter': 'a'
}
class TType:
def __init__(self, glsl_header_type):
if isinstance(glsl_header_type, basestring):
self.data = self.parse_type(glsl_header_type)
else:
self.data = glsl_header_type
self.normalize()
def normalize(self):
# Note that this will set primarySize and secondarySize also on genTypes. In that case they
# are overridden when the specific types are generated.
if 'primarySize' not in self.data:
if ('secondarySize' in self.data):
raise Exception('Unexpected secondarySize on type that does not have primarySize set')
self.data['primarySize'] = 1
if 'secondarySize' not in self.data:
self.data['secondarySize'] = 1
if 'precision' not in self.data:
self.data['precision'] = 'Undefined'
if 'qualifier' not in self.data:
self.data['qualifier'] = 'Global'
def get_statictype_string(self):
template_type = 'StaticType::Get<Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize}>()'
return template_type.format(**self.data)
def get_mangled_name(self, separator = ';'):
mangled_name = ''
if self.is_matrix():
mangled_name += str(self.data['primarySize'])
mangled_name += str(self.data['secondarySize'])
elif self.data['primarySize'] > 1:
mangled_name += str(self.data['primarySize'])
mangled_name += basic_mangled_names[self.data['basic']]
mangled_name += separator
return mangled_name
def is_vector(self):
return self.data['primarySize'] > 1 and self.data['secondarySize'] == 1
def is_matrix(self):
return self.data['secondarySize'] > 1
def specific_sampler_or_image_type(self, basic_type_prefix):
if 'genType' in self.data:
type = {}
if 'basic' not in self.data:
type['basic'] = {'': 'Float', 'I': 'Int', 'U': 'UInt'}[basic_type_prefix]
type['primarySize'] = self.data['primarySize']
else:
type['basic'] = basic_type_prefix + self.data['basic']
type['primarySize'] = 1
type['precision'] = 'Undefined'
return TType(type)
return self
def specific_type(self, vec_size):
type = {}
if 'genType' in self.data:
type['basic'] = self.data['basic']
type['precision'] = self.data['precision']
type['qualifier'] = self.data['qualifier']
type['primarySize'] = vec_size
type['secondarySize'] = 1
return TType(type)
return self
def parse_type(self, glsl_header_type):
if glsl_header_type.startswith('out '):
type_obj = self.parse_type(glsl_header_type[4:])
type_obj['qualifier'] = 'Out'
return type_obj
if glsl_header_type.startswith('inout '):
type_obj = self.parse_type(glsl_header_type[6:])
type_obj['qualifier'] = 'InOut'
return type_obj
basic_type_map = {
'float': 'Float',
'int': 'Int',
'uint': 'UInt',
'bool': 'Bool',
'void': 'Void',
'atomic_uint': 'AtomicCounter',
'yuvCscStandardEXT': 'YuvCscStandardEXT'
}
if glsl_header_type in basic_type_map:
return {'basic': basic_type_map[glsl_header_type]}
type_obj = {}
basic_type_prefix_map = {'': 'Float', 'i': 'Int', 'u': 'UInt', 'b': 'Bool', 'v': 'Void'}
vec_re = re.compile(r'^([iub]?)vec([234]?)$')
vec_match = vec_re.match(glsl_header_type)
if vec_match:
type_obj['basic'] = basic_type_prefix_map[vec_match.group(1)]
if vec_match.group(2) == '':
# Type like "ivec" that represents either ivec2, ivec3 or ivec4
type_obj['genType'] = 'vec'
else:
# vec with specific size
type_obj['primarySize'] = int(vec_match.group(2))
return type_obj
mat_re = re.compile(r'^mat([234])(x([234]))?$')
mat_match = mat_re.match(glsl_header_type)
if mat_match:
type_obj['basic'] = 'Float'
if len(glsl_header_type) == 4:
mat_size = int(mat_match.group(1))
type_obj['primarySize'] = mat_size
type_obj['secondarySize'] = mat_size
else:
type_obj['primarySize'] = int(mat_match.group(1))
type_obj['secondarySize'] = int(mat_match.group(3))
return type_obj
gen_re = re.compile(r'^gen([IUB]?)Type$')
gen_match = gen_re.match(glsl_header_type)
if gen_match:
type_obj['basic'] = basic_type_prefix_map[gen_match.group(1).lower()]
type_obj['genType'] = 'yes'
return type_obj
if glsl_header_type.startswith('sampler'):
type_obj['basic'] = glsl_header_type[0].upper() + glsl_header_type[1:]
return type_obj
if glsl_header_type.startswith('gsampler') or glsl_header_type.startswith('gimage'):
type_obj['basic'] = glsl_header_type[1].upper() + glsl_header_type[2:]
type_obj['genType'] = 'sampler_or_image'
return type_obj
if glsl_header_type == 'gvec4':
return {'primarySize': 4, 'genType': 'sampler_or_image'}
if glsl_header_type == 'gvec3':
return {'primarySize': 3, 'genType': 'sampler_or_image'}
raise Exception('Unrecognized type: ' + str(glsl_header_type))
def get_parsed_functions():
def parse_function_parameters(parameters):
if parameters == '':
return []
parametersOut = []
parameters = parameters.split(', ')
for parameter in parameters:
parametersOut.append(TType(parameter.strip()))
return parametersOut
lines = []
with open(functions_txt_filename) as f:
lines = f.readlines()
lines = [line.strip() for line in lines if line.strip() != '' and not line.strip().startswith('//')]
fun_re = re.compile(r'^(\w+) (\w+)\((.*)\);$')
parsed_functions = OrderedDict()
group_stack = []
default_metadata = {}
for line in lines:
fun_match = fun_re.match(line)
if line.startswith('GROUP BEGIN '):
group_rest = line[12:].strip()
group_parts = group_rest.split(' ', 1)
current_group = {
'functions': [],
'name': group_parts[0],
'subgroups': {}
}
if len(group_parts) > 1:
group_metadata = json.loads(group_parts[1])
current_group.update(group_metadata)
group_stack.append(current_group)
elif line.startswith('GROUP END '):
group_end_name = line[10:].strip()
current_group = group_stack[-1]
if current_group['name'] != group_end_name:
raise Exception('GROUP END: Unexpected function group name "' + group_end_name + '" was expecting "' + current_group['name'] + '"')
group_stack.pop()
is_top_level_group = (len(group_stack) == 0)
if is_top_level_group:
parsed_functions[current_group['name']] = current_group
default_metadata = {}
else:
super_group = group_stack[-1]
super_group['subgroups'][current_group['name']] = current_group
elif line.startswith('DEFAULT METADATA'):
line_rest = line[16:].strip()
default_metadata = json.loads(line_rest)
elif fun_match:
return_type = fun_match.group(1)
name = fun_match.group(2)
parameters = fun_match.group(3)
function_props = {
'name': name,
'returnType': TType(return_type),
'parameters': parse_function_parameters(parameters)
}
function_props.update(default_metadata)
group_stack[-1]['functions'].append(function_props)
else:
raise Exception('Unexpected function input line: ' + line)
return parsed_functions
parsed_functions = get_parsed_functions()
if args.dump_intermediate_json:
with open('builtin_functions.json', 'w') as outfile:
def serialize_obj(obj):
if isinstance(obj, TType):
return obj.data
else:
raise "Cannot serialize to JSON: " + str(obj)
json.dump(parsed_functions, outfile, indent=4, separators=(',', ': '), default=serialize_obj)
# Declarations of symbol unique ids
builtin_id_declarations = []
# Declarations of name string variables
name_declarations = set()
# Declarations of parameter arrays for builtin TFunctions
parameter_declarations = set()
# Declarations of builtin TFunctions
function_declarations = []
# Code for inserting builtin TFunctions to the symbol table. Grouped by condition.
insert_functions_by_condition = OrderedDict()
# Code for inserting unmangled builtin function names to the symbol table. Grouped by condition.
# Each item in the dictionary is an OrderedDict from function name + level to the insert call.
insert_unmangled_functions_by_condition = OrderedDict()
id_counter = 0
def get_suffix(props):
if 'suffix' in props:
return props['suffix']
return ''
def get_extension(props):
if 'extension' in props:
return props['extension']
return 'UNDEFINED'
def get_op(name, function_props):
if 'op' not in function_props:
raise Exception('function op not defined')
if function_props['op'] == 'auto':
return name[0].upper() + name[1:]
return function_props['op']
def get_known_to_not_have_side_effects(function_props):
if 'op' in function_props and function_props['op'] != 'CallBuiltInFunction':
if 'hasSideEffects' in function_props:
return 'false'
else:
for param in get_parameters(function_props):
if 'qualifier' in param.data and (param.data['qualifier'] == 'Out' or param.data['qualifier'] == 'InOut'):
return 'false'
return 'true'
return 'false'
def get_parameters(function_props):
if 'parameters' in function_props:
return function_props['parameters']
return []
def get_function_mangled_name(function_name, parameters):
mangled_name = function_name + '('
for param in parameters:
mangled_name += param.get_mangled_name()
return mangled_name
def get_unique_identifier_name(function_name, parameters):
unique_name = function_name + '_'
for param in parameters:
unique_name += param.get_mangled_name('_')
return unique_name
def get_variable_name_to_store_parameters(parameters):
if len(parameters) == 0:
return 'empty'
unique_name = 'p_'
for param in parameters:
if 'qualifier' in param.data:
if param.data['qualifier'] == 'Out':
unique_name += 'o_'
if param.data['qualifier'] == 'InOut':
unique_name += 'io_'
unique_name += param.get_mangled_name('_')
return unique_name
def gen_function_variants(function_name, function_props):
function_variants = []
parameters = get_parameters(function_props)
function_is_gen_type = False
gen_type = set()
for param in parameters:
if 'genType' in param.data:
if param.data['genType'] not in ['sampler_or_image', 'vec', 'yes']:
raise Exception('Unexpected value of genType "' + str(param.data['genType']) + '" should be "sampler_or_image", "vec", or "yes"')
gen_type.add(param.data['genType'])
if len(gen_type) > 1:
raise Exception('Unexpected multiple values of genType set on the same function: ' + str(list(gen_type)))
if len(gen_type) == 0:
function_variants.append(function_props)
return function_variants
# If we have a gsampler_or_image then we're generating variants for float, int and uint
# samplers.
if 'sampler_or_image' in gen_type:
types = ['', 'I', 'U']
for type in types:
variant_props = function_props.copy()
variant_parameters = []
for param in parameters:
variant_parameters.append(param.specific_sampler_or_image_type(type))
variant_props['parameters'] = variant_parameters
variant_props['returnType'] = function_props['returnType'].specific_sampler_or_image_type(type)
function_variants.append(variant_props)
return function_variants
# If we have a normal gentype then we're generating variants for different sizes of vectors.
sizes = range(1, 5)
if 'vec' in gen_type:
sizes = range(2, 5)
for size in sizes:
variant_props = function_props.copy()
variant_parameters = []
for param in parameters:
variant_parameters.append(param.specific_type(size))
variant_props['parameters'] = variant_parameters
variant_props['returnType'] = function_props['returnType'].specific_type(size)
function_variants.append(variant_props)
return function_variants
defined_function_variants = set()
def process_single_function_group(condition, group_name, group):
global id_counter
if 'functions' not in group:
return
for function_props in group['functions']:
function_name = function_props['name']
level = function_props['level']
extension = get_extension(function_props)
template_args = {
'name': function_name,
'name_with_suffix': function_name + get_suffix(function_props),
'level': level,
'extension': extension,
'op': get_op(function_name, function_props),
'known_to_not_have_side_effects': get_known_to_not_have_side_effects(function_props)
}
function_variants = gen_function_variants(function_name, function_props)
template_name_declaration = 'constexpr const ImmutableString {name_with_suffix}("{name}");'
name_declaration = template_name_declaration.format(**template_args)
if not name_declaration in name_declarations:
name_declarations.add(name_declaration)
template_insert_unmangled = ' insertUnmangledBuiltIn(BuiltInName::{name_with_suffix}, TExtension::{extension}, {level});'
insert_unmangled = template_insert_unmangled.format(**template_args)
if (function_name + ',' + level) not in insert_unmangled_functions_by_condition[condition] or extension == 'UNDEFINED':
insert_unmangled_functions_by_condition[condition][function_name + ',' + level] = insert_unmangled
for function_props in function_variants:
template_args['id'] = id_counter
parameters = get_parameters(function_props)
template_args['unique_name'] = get_unique_identifier_name(template_args['name_with_suffix'], parameters)
if template_args['unique_name'] in defined_function_variants:
continue
defined_function_variants.add(template_args['unique_name'])
template_args['param_count'] = len(parameters)
template_args['return_type'] = function_props['returnType'].get_statictype_string()
template_args['mangled_name'] = get_function_mangled_name(function_name, parameters)
template_builtin_id_declaration = ' static constexpr const TSymbolUniqueId {unique_name} = TSymbolUniqueId({id});'
builtin_id_declarations.append(template_builtin_id_declaration.format(**template_args))
template_mangled_name_declaration = 'constexpr const ImmutableString {unique_name}("{mangled_name}");'
name_declarations.add(template_mangled_name_declaration.format(**template_args))
parameters_list = []
for param in parameters:
template_parameter = 'TConstParameter({param_type})'
parameters_list.append(template_parameter.format(param_type = param.get_statictype_string()))
template_args['parameters_var_name'] = get_variable_name_to_store_parameters(parameters)
if len(parameters) > 0:
template_args['parameters_list'] = ', '.join(parameters_list)
template_parameter_list_declaration = 'constexpr const TConstParameter {parameters_var_name}[{param_count}] = {{ {parameters_list} }};'
parameter_declarations.add(template_parameter_list_declaration.format(**template_args))
else:
template_parameter_list_declaration = 'constexpr const TConstParameter *{parameters_var_name} = nullptr;'
parameter_declarations.add(template_parameter_list_declaration.format(**template_args))
template_function_declaration = 'constexpr const TFunction kFunction_{unique_name}(BuiltInId::{unique_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, BuiltInName::{unique_name}, EOp{op}, {known_to_not_have_side_effects});'
function_declarations.append(template_function_declaration.format(**template_args))
template_insert_function = ' insertBuiltIn({level}, &BuiltInFunction::kFunction_{unique_name});'
insert_functions_by_condition[condition].append(template_insert_function.format(**template_args))
id_counter += 1
def process_function_group(group_name, group):
condition = 'NO_CONDITION'
if 'condition' in group:
condition = group['condition']
if condition not in insert_functions_by_condition:
insert_functions_by_condition[condition] = []
insert_unmangled_functions_by_condition[condition] = OrderedDict()
process_single_function_group(condition, group_name, group)
if 'subgroups' in group:
for subgroup_name, subgroup in group['subgroups'].iteritems():
process_function_group(subgroup_name, subgroup)
for group_name, group in parsed_functions.iteritems():
process_function_group(group_name, group)
output_strings = {
'script_name': os.path.basename(__file__),
'copyright_year': date.today().year,
'builtin_id_declarations': '\n'.join(builtin_id_declarations),
'last_static_builtin_id': id_counter - 1,
'name_declarations': '\n'.join(sorted(list(name_declarations))),
'function_data_source_name': functions_txt_filename,
'function_declarations': '\n'.join(function_declarations),
'parameter_declarations': '\n'.join(sorted(parameter_declarations))
}
insert_functions = []
insert_unmangled_functions = []
for condition in insert_functions_by_condition:
if condition != 'NO_CONDITION':
condition_header = ' if ({condition})\n {{'.format(condition = condition)
insert_functions.append(condition_header)
insert_unmangled_functions.append(condition_header)
for insert_function in insert_functions_by_condition[condition]:
insert_functions.append(insert_function)
for function_name, insert_function in insert_unmangled_functions_by_condition[condition].iteritems():
insert_unmangled_functions.append(insert_function)
if condition != 'NO_CONDITION':
insert_functions.append('}')
insert_unmangled_functions.append('}')
output_strings['insert_functions'] = '\n'.join(insert_functions)
output_strings['insert_unmangled_functions'] = '\n'.join(insert_unmangled_functions)
with open('SymbolTable_autogen.cpp', 'wt') as outfile_cpp:
output_cpp = template_symboltable_cpp.format(**output_strings)
outfile_cpp.write(output_cpp)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment