Updated glslang.

This commit is contained in:
Бранимир Караџић 2023-12-22 18:15:11 -08:00
parent 588e23eac0
commit 0489440481
26 changed files with 2503 additions and 2058 deletions

View File

@ -1,37 +0,0 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
namespace glslang {
} // end namespace glslang

View File

@ -1,49 +0,0 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef __INITIALIZEDLL_H
#define __INITIALIZEDLL_H
#include "../glslang/OSDependent/osinclude.h"
namespace glslang {
inline bool InitProcess() { return true; } // DEPRECATED
inline bool InitThread() { return true; } // DEPRECATED
inline bool DetachThread() { return true; } // DEPRECATED
inline bool DetachProcess() { return true; } // DEPRECATED
} // end namespace glslang
#endif // __INITIALIZEDLL_H

View File

@ -4407,7 +4407,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
if (explicitLayout != glslang::ElpNone)
spvType = builder.makeUintType(32);
else
spvType = builder.makeBoolType(false);
spvType = builder.makeBoolType();
break;
case glslang::EbtInt:
spvType = builder.makeIntType(32);

View File

@ -182,7 +182,7 @@ Id Builder::makeVoidType()
return type->getResultId();
}
Id Builder::makeBoolType(bool const compilerGenerated)
Id Builder::makeBoolType()
{
Instruction* type;
if (groupedTypes[OpTypeBool].size() == 0) {
@ -190,14 +190,15 @@ Id Builder::makeBoolType(bool const compilerGenerated)
groupedTypes[OpTypeBool].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
if (emitNonSemanticShaderDebugInfo) {
auto const debugResultId = makeBoolDebugType(32);
debugId[type->getResultId()] = debugResultId;
}
} else
type = groupedTypes[OpTypeBool].back();
if (emitNonSemanticShaderDebugInfo && !compilerGenerated)
{
auto const debugResultId = makeBoolDebugType(32);
debugId[type->getResultId()] = debugResultId;
}
return type->getResultId();
}
@ -2740,6 +2741,14 @@ Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& op
module.mapInstruction(op);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(op));
// OpSpecConstantOp's using 8 or 16 bit types require the associated capability
if (containsType(typeId, OpTypeInt, 8))
addCapability(CapabilityInt8);
if (containsType(typeId, OpTypeInt, 16))
addCapability(CapabilityInt16);
if (containsType(typeId, OpTypeFloat, 16))
addCapability(CapabilityFloat16);
return op->getResultId();
}

View File

@ -185,7 +185,7 @@ public:
// For creating new types (will return old type if the requested one was already made).
Id makeVoidType();
Id makeBoolType(bool const compilerGenerated = true);
Id makeBoolType();
Id makePointer(StorageClass, Id pointee);
Id makeForwardPointer(StorageClass);
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);

View File

@ -240,8 +240,8 @@ public:
OperandParameters operands;
protected:
int typePresent : 1;
int resultPresent : 1;
bool typePresent : 1;
bool resultPresent : 1;
};
// The set of objects that hold all the instruction/operand

View File

@ -34,9 +34,9 @@
#ifndef GLSLANG_BUILD_INFO
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 13
#define GLSLANG_VERSION_MINOR 1
#define GLSLANG_VERSION_PATCH 1
#define GLSLANG_VERSION_MAJOR 14
#define GLSLANG_VERSION_MINOR 0
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""
#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \

View File

@ -503,7 +503,7 @@ public:
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
case EbtInt16: returnValue.setI16Const(i16Const % constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;

View File

@ -1451,9 +1451,9 @@ public:
TSampler sampler;
TQualifier qualifier;
TShaderQualifiers shaderQualifiers;
int vectorSize : 4;
int matrixCols : 4;
int matrixRows : 4;
uint32_t vectorSize : 4;
uint32_t matrixCols : 4;
uint32_t matrixRows : 4;
bool coopmatNV : 1;
bool coopmatKHR : 1;
TArraySizes* arraySizes;
@ -1470,7 +1470,7 @@ public:
void initType(const TSourceLoc& l)
{
basicType = EbtVoid;
vectorSize = 1;
vectorSize = 1u;
matrixRows = 0;
matrixCols = 0;
arraySizes = nullptr;
@ -1501,19 +1501,22 @@ public:
{
matrixRows = 0;
matrixCols = 0;
vectorSize = s;
assert(s >= 0);
vectorSize = static_cast<uint32_t>(s) & 0b1111;
}
void setMatrix(int c, int r)
{
matrixRows = r;
matrixCols = c;
assert(r >= 0);
matrixRows = static_cast<uint32_t>(r) & 0b1111;
assert(c >= 0);
matrixCols = static_cast<uint32_t>(c) & 0b1111;
vectorSize = 0;
}
bool isScalar() const
{
return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
return matrixCols == 0u && vectorSize == 1u && arraySizes == nullptr && userDef == nullptr;
}
// GL_EXT_spirv_intrinsics
@ -1535,10 +1538,14 @@ public:
// for "empty" type (no args) or simple scalar/vector/matrix
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
assert(mc >= 0);
assert(mr >= 0);
sampler.clear();
qualifier.clear();
qualifier.storage = q;
@ -1547,10 +1554,14 @@ public:
// for explicit precision qualifier
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
assert(mc >= 0);
assert(mr >= 0);
sampler.clear();
qualifier.clear();
qualifier.storage = q;
@ -1561,7 +1572,7 @@ public:
// for turning a TPublicType into a TType, using a shallow copy
explicit TType(const TPublicType& p) :
basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(-1),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
spirvType(p.spirvType)
{
@ -1602,14 +1613,17 @@ public:
basicType = p.typeParameters->basicType;
if (p.typeParameters->arraySizes->getNumDims() == 4) {
coopmatKHRuse = p.typeParameters->arraySizes->getDimSize(3);
const int dimSize = p.typeParameters->arraySizes->getDimSize(3);
assert(dimSize >= 0);
coopmatKHRuse = static_cast<uint32_t>(dimSize) & 0b111;
coopmatKHRUseValid = true;
p.typeParameters->arraySizes->removeLastSize();
}
}
}
// for construction of sampler types
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
{
@ -1655,14 +1669,15 @@ public:
} else if (isCoopMat()) {
coopmatNV = false;
coopmatKHR = false;
coopmatKHRuse = -1;
coopmatKHRuse = 0;
coopmatKHRUseValid = false;
typeParameters = nullptr;
}
}
}
// for making structures, ...
TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1672,7 +1687,7 @@ public:
}
// For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1681,7 +1696,7 @@ public:
}
// for block reference (first parameter must be EbtReference)
explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1719,6 +1734,7 @@ public:
coopmatNV = copyOf.isCoopMatNV();
coopmatKHR = copyOf.isCoopMatKHR();
coopmatKHRuse = copyOf.coopmatKHRuse;
coopmatKHRUseValid = copyOf.coopmatKHRUseValid;
}
// Make complete copy of the whole type graph rooted at 'copyOf'.
@ -1748,7 +1764,7 @@ public:
void makeVector() { vector1 = true; }
virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; }
virtual void hideMember() { basicType = EbtVoid; vectorSize = 1u; }
virtual bool hiddenMember() const { return basicType == EbtVoid; }
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
@ -1788,9 +1804,9 @@ public:
virtual TQualifier& getQualifier() { return qualifier; }
virtual const TQualifier& getQualifier() const { return qualifier; }
virtual int getVectorSize() const { return vectorSize; } // returns 1 for either scalar or vector of size 1, valid for both
virtual int getMatrixCols() const { return matrixCols; }
virtual int getMatrixRows() const { return matrixRows; }
virtual int getVectorSize() const { return static_cast<int>(vectorSize); } // returns 1 for either scalar or vector of size 1, valid for both
virtual int getMatrixCols() const { return static_cast<int>(matrixCols); }
virtual int getMatrixRows() const { return static_cast<int>(matrixRows); }
virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); }
virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); }
virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); }
@ -1805,7 +1821,7 @@ public:
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
virtual bool isVector() const { return vectorSize > 1 || vector1; }
virtual bool isVector() const { return vectorSize > 1u || vector1; }
virtual bool isMatrix() const { return matrixCols ? true : false; }
virtual bool isArray() const { return arraySizes != nullptr; }
virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
@ -1855,7 +1871,7 @@ public:
bool isCoopMatKHR() const { return coopmatKHR; }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
int getCoopMatKHRuse() const { return coopmatKHRuse; }
int getCoopMatKHRuse() const { return static_cast<int>(coopmatKHRuse); }
// return true if this type contains any subtype which satisfies the given predicate.
template <typename P>
@ -2395,7 +2411,7 @@ public:
if (i != (int)typeParameters->arraySizes->getNumDims() - 1)
appendStr(", ");
}
if (coopmatKHRuse != -1) {
if (coopmatKHRUseValid) {
appendStr(", ");
appendInt(coopmatKHRuse);
}
@ -2464,11 +2480,14 @@ public:
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
void setBasicType(const TBasicType& t) { basicType = t; }
void setVectorSize(int s) { vectorSize = s; }
void setVectorSize(int s) {
assert(s >= 0);
vectorSize = static_cast<uint32_t>(s) & 0b1111;
}
int computeNumComponents() const
{
int components = 0;
uint32_t components = 0;
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
@ -2482,7 +2501,7 @@ public:
components *= arraySizes->getCumulativeSize();
}
return components;
return static_cast<int>(components);
}
// append this type's mangled name to the passed in 'name'
@ -2825,9 +2844,9 @@ protected:
void buildMangledName(TString&) const;
TBasicType basicType : 8;
int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
int matrixCols : 4;
int matrixRows : 4;
uint32_t vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
uint32_t matrixCols : 4;
uint32_t matrixRows : 4;
bool vector1 : 1; // Backward-compatible tracking of a 1-component vector distinguished from a scalar.
// GLSL 4.5 never has a 1-component vector; so this will always be false until such
// functionality is added.
@ -2835,7 +2854,8 @@ protected:
// from a scalar.
bool coopmatNV : 1;
bool coopmatKHR : 1;
int coopmatKHRuse : 4; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
uint32_t coopmatKHRuse : 3; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
bool coopmatKHRUseValid : 1; // True if coopmatKHRuse has been set
TQualifier qualifier;
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types

View File

@ -48,14 +48,9 @@
#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H
#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning(disable : 4464) // relative include path contains '..'
#pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
#endif
#include "../Include/Common.h"
#include "../Include/Types.h"
#include "../Include/ConstantUnion.h"
#include "Common.h"
#include "Types.h"
#include "ConstantUnion.h"
namespace glslang {

View File

@ -689,7 +689,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpConvInt64ToBool:
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
case EOpConvUint64ToBool:
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
newConstArray[i].setBConst(unionArray[i].getU64Const() != 0); break;
case EOpConvFloat16ToBool:
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;

View File

@ -52,6 +52,7 @@
//
#include "Initialize.h"
#include "span.h"
namespace glslang {
@ -139,20 +140,17 @@ struct Versioning {
EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECompatibilityProfile);
// Declare pointers to put into the table for versioning.
const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr },
{ EDesktopProfile, 0, 130, 0, nullptr },
{ EBadProfile } };
const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
const std::array Es300Desktop130Version = { Versioning{ EEsProfile, 0, 300, 0, nullptr },
Versioning{ EDesktopProfile, 0, 130, 0, nullptr },
};
const Versioning Es310Desktop400Version[] = { { EEsProfile, 0, 310, 0, nullptr },
{ EDesktopProfile, 0, 400, 0, nullptr },
{ EBadProfile } };
const Versioning* Es310Desktop400 = &Es310Desktop400Version[0];
const std::array Es310Desktop400Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr },
Versioning{ EDesktopProfile, 0, 400, 0, nullptr },
};
const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr },
{ EDesktopProfile, 0, 450, 0, nullptr },
{ EBadProfile } };
const Versioning* Es310Desktop450 = &Es310Desktop450Version[0];
const std::array Es310Desktop450Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr },
Versioning{ EDesktopProfile, 0, 450, 0, nullptr },
};
// The main descriptor of what a set of function prototypes can look like, and
// a pointer to extra versioning information, when needed.
@ -162,7 +160,7 @@ struct BuiltInFunction {
int numArguments; // number of arguments (overloads with varying arguments need different entries)
ArgType types; // ArgType mask
ArgClass classes; // the ways this particular function entry manifests
const Versioning* versioning; // nullptr means always a valid version
const span<const Versioning> versioning; // An empty span means always a valid version
};
// The tables can have the same built-in function name more than one time,
@ -174,151 +172,146 @@ struct BuiltInFunction {
//
// Table is terminated by an OpNull TOperator.
const BuiltInFunction BaseFunctions[] = {
const std::array BaseFunctions = {
// TOperator, name, arg-count, ArgType, ArgClass, versioning
// --------- ---- --------- ------- -------- ----------
{ EOpRadians, "radians", 1, TypeF, ClassRegular, nullptr },
{ EOpDegrees, "degrees", 1, TypeF, ClassRegular, nullptr },
{ EOpSin, "sin", 1, TypeF, ClassRegular, nullptr },
{ EOpCos, "cos", 1, TypeF, ClassRegular, nullptr },
{ EOpTan, "tan", 1, TypeF, ClassRegular, nullptr },
{ EOpAsin, "asin", 1, TypeF, ClassRegular, nullptr },
{ EOpAcos, "acos", 1, TypeF, ClassRegular, nullptr },
{ EOpAtan, "atan", 2, TypeF, ClassRegular, nullptr },
{ EOpAtan, "atan", 1, TypeF, ClassRegular, nullptr },
{ EOpPow, "pow", 2, TypeF, ClassRegular, nullptr },
{ EOpExp, "exp", 1, TypeF, ClassRegular, nullptr },
{ EOpLog, "log", 1, TypeF, ClassRegular, nullptr },
{ EOpExp2, "exp2", 1, TypeF, ClassRegular, nullptr },
{ EOpLog2, "log2", 1, TypeF, ClassRegular, nullptr },
{ EOpSqrt, "sqrt", 1, TypeF, ClassRegular, nullptr },
{ EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, nullptr },
{ EOpAbs, "abs", 1, TypeF, ClassRegular, nullptr },
{ EOpSign, "sign", 1, TypeF, ClassRegular, nullptr },
{ EOpFloor, "floor", 1, TypeF, ClassRegular, nullptr },
{ EOpCeil, "ceil", 1, TypeF, ClassRegular, nullptr },
{ EOpFract, "fract", 1, TypeF, ClassRegular, nullptr },
{ EOpMod, "mod", 2, TypeF, ClassLS, nullptr },
{ EOpMin, "min", 2, TypeF, ClassLS, nullptr },
{ EOpMax, "max", 2, TypeF, ClassLS, nullptr },
{ EOpClamp, "clamp", 3, TypeF, ClassLS2, nullptr },
{ EOpMix, "mix", 3, TypeF, ClassLS, nullptr },
{ EOpStep, "step", 2, TypeF, ClassFS, nullptr },
{ EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, nullptr },
{ EOpNormalize, "normalize", 1, TypeF, ClassRegular, nullptr },
{ EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, nullptr },
{ EOpReflect, "reflect", 2, TypeF, ClassRegular, nullptr },
{ EOpRefract, "refract", 3, TypeF, ClassXLS, nullptr },
{ EOpLength, "length", 1, TypeF, ClassRS, nullptr },
{ EOpDistance, "distance", 2, TypeF, ClassRS, nullptr },
{ EOpDot, "dot", 2, TypeF, ClassRS, nullptr },
{ EOpCross, "cross", 2, TypeF, ClassV3, nullptr },
{ EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, nullptr },
{ EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, nullptr },
{ EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, nullptr },
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, nullptr },
{ EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, nullptr },
{ EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, nullptr },
{ EOpAny, "any", 1, TypeB, ClassRSNS, nullptr },
{ EOpAll, "all", 1, TypeB, ClassRSNS, nullptr },
{ EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, nullptr },
{ EOpSinh, "sinh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpCosh, "cosh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpTanh, "tanh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAsinh, "asinh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAcosh, "acosh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAtanh, "atanh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAbs, "abs", 1, TypeI, ClassRegular, Es300Desktop130 },
{ EOpSign, "sign", 1, TypeI, ClassRegular, Es300Desktop130 },
{ EOpTrunc, "trunc", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpRound, "round", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpModf, "modf", 2, TypeF, ClassLO, Es300Desktop130 },
{ EOpMin, "min", 2, TypeIU, ClassLS, Es300Desktop130 },
{ EOpMax, "max", 2, TypeIU, ClassLS, Es300Desktop130 },
{ EOpClamp, "clamp", 3, TypeIU, ClassLS2, Es300Desktop130 },
{ EOpMix, "mix", 3, TypeF, ClassLB, Es300Desktop130 },
{ EOpIsInf, "isinf", 1, TypeF, ClassB, Es300Desktop130 },
{ EOpIsNan, "isnan", 1, TypeF, ClassB, Es300Desktop130 },
{ EOpLessThan, "lessThan", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop400 },
{ EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 },
{ EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 },
{ EOpNull }
BuiltInFunction{ EOpRadians, "radians", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpDegrees, "degrees", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSin, "sin", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpCos, "cos", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpTan, "tan", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAsin, "asin", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAcos, "acos", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAtan, "atan", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAtan, "atan", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpPow, "pow", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpExp, "exp", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpLog, "log", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpExp2, "exp2", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpLog2, "log2", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSqrt, "sqrt", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAbs, "abs", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSign, "sign", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFloor, "floor", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpCeil, "ceil", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFract, "fract", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpMod, "mod", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpMin, "min", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpMax, "max", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpClamp, "clamp", 3, TypeF, ClassLS2, {} },
BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLS, {} },
BuiltInFunction{ EOpStep, "step", 2, TypeF, ClassFS, {} },
BuiltInFunction{ EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, {} },
BuiltInFunction{ EOpNormalize, "normalize", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpReflect, "reflect", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpRefract, "refract", 3, TypeF, ClassXLS, {} },
BuiltInFunction{ EOpLength, "length", 1, TypeF, ClassRS, {} },
BuiltInFunction{ EOpDistance, "distance", 2, TypeF, ClassRS, {} },
BuiltInFunction{ EOpDot, "dot", 2, TypeF, ClassRS, {} },
BuiltInFunction{ EOpCross, "cross", 2, TypeF, ClassV3, {} },
BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, {} },
BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, {} },
BuiltInFunction{ EOpAny, "any", 1, TypeB, ClassRSNS, {} },
BuiltInFunction{ EOpAll, "all", 1, TypeB, ClassRSNS, {} },
BuiltInFunction{ EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, {} },
BuiltInFunction{ EOpSinh, "sinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpCosh, "cosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpTanh, "tanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAsinh, "asinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAcosh, "acosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAtanh, "atanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAbs, "abs", 1, TypeI, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpSign, "sign", 1, TypeI, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpTrunc, "trunc", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpRound, "round", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpModf, "modf", 2, TypeF, ClassLO, {Es300Desktop130Version} },
BuiltInFunction{ EOpMin, "min", 2, TypeIU, ClassLS, {Es300Desktop130Version} },
BuiltInFunction{ EOpMax, "max", 2, TypeIU, ClassLS, {Es300Desktop130Version} },
BuiltInFunction{ EOpClamp, "clamp", 3, TypeIU, ClassLS2, {Es300Desktop130Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLB, {Es300Desktop130Version} },
BuiltInFunction{ EOpIsInf, "isinf", 1, TypeF, ClassB, {Es300Desktop130Version} },
BuiltInFunction{ EOpIsNan, "isnan", 1, TypeF, ClassB, {Es300Desktop130Version} },
BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeB, ClassRegular, {Es310Desktop450Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeIU, ClassLB, {Es310Desktop450Version} },
};
const BuiltInFunction DerivativeFunctions[] = {
{ EOpDPdx, "dFdx", 1, TypeF, ClassRegular, nullptr },
{ EOpDPdy, "dFdy", 1, TypeF, ClassRegular, nullptr },
{ EOpFwidth, "fwidth", 1, TypeF, ClassRegular, nullptr },
{ EOpNull }
const std::array DerivativeFunctions = {
BuiltInFunction{ EOpDPdx, "dFdx", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpDPdy, "dFdy", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFwidth, "fwidth", 1, TypeF, ClassRegular, {} },
};
// For functions declared some other way, but still use the table to relate to operator.
struct CustomFunction {
TOperator op; // operator to map the name to
const char* name; // function name
const Versioning* versioning; // nullptr means always a valid version
const span<const Versioning> versioning; // An empty span means always a valid version
};
const CustomFunction CustomFunctions[] = {
{ EOpBarrier, "barrier", nullptr },
{ EOpMemoryBarrierShared, "memoryBarrierShared", nullptr },
{ EOpGroupMemoryBarrier, "groupMemoryBarrier", nullptr },
{ EOpMemoryBarrier, "memoryBarrier", nullptr },
{ EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr },
{ EOpBarrier, "barrier", {} },
{ EOpMemoryBarrierShared, "memoryBarrierShared", {} },
{ EOpGroupMemoryBarrier, "groupMemoryBarrier", {} },
{ EOpMemoryBarrier, "memoryBarrier", {} },
{ EOpMemoryBarrierBuffer, "memoryBarrierBuffer", {} },
{ EOpPackSnorm2x16, "packSnorm2x16", nullptr },
{ EOpUnpackSnorm2x16, "unpackSnorm2x16", nullptr },
{ EOpPackUnorm2x16, "packUnorm2x16", nullptr },
{ EOpUnpackUnorm2x16, "unpackUnorm2x16", nullptr },
{ EOpPackHalf2x16, "packHalf2x16", nullptr },
{ EOpUnpackHalf2x16, "unpackHalf2x16", nullptr },
{ EOpPackSnorm2x16, "packSnorm2x16", {} },
{ EOpUnpackSnorm2x16, "unpackSnorm2x16", {} },
{ EOpPackUnorm2x16, "packUnorm2x16", {} },
{ EOpUnpackUnorm2x16, "unpackUnorm2x16", {} },
{ EOpPackHalf2x16, "packHalf2x16", {} },
{ EOpUnpackHalf2x16, "unpackHalf2x16", {} },
{ EOpMul, "matrixCompMult", nullptr },
{ EOpOuterProduct, "outerProduct", nullptr },
{ EOpTranspose, "transpose", nullptr },
{ EOpDeterminant, "determinant", nullptr },
{ EOpMatrixInverse, "inverse", nullptr },
{ EOpFloatBitsToInt, "floatBitsToInt", nullptr },
{ EOpFloatBitsToUint, "floatBitsToUint", nullptr },
{ EOpIntBitsToFloat, "intBitsToFloat", nullptr },
{ EOpUintBitsToFloat, "uintBitsToFloat", nullptr },
{ EOpMul, "matrixCompMult", {} },
{ EOpOuterProduct, "outerProduct", {} },
{ EOpTranspose, "transpose", {} },
{ EOpDeterminant, "determinant", {} },
{ EOpMatrixInverse, "inverse", {} },
{ EOpFloatBitsToInt, "floatBitsToInt", {} },
{ EOpFloatBitsToUint, "floatBitsToUint", {} },
{ EOpIntBitsToFloat, "intBitsToFloat", {} },
{ EOpUintBitsToFloat, "uintBitsToFloat", {} },
{ EOpTextureQuerySize, "textureSize", nullptr },
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
{ EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
{ EOpTextureQuerySamples, "textureSamples", nullptr },
{ EOpTexture, "texture", nullptr },
{ EOpTextureProj, "textureProj", nullptr },
{ EOpTextureLod, "textureLod", nullptr },
{ EOpTextureOffset, "textureOffset", nullptr },
{ EOpTextureFetch, "texelFetch", nullptr },
{ EOpTextureFetchOffset, "texelFetchOffset", nullptr },
{ EOpTextureProjOffset, "textureProjOffset", nullptr },
{ EOpTextureLodOffset, "textureLodOffset", nullptr },
{ EOpTextureProjLod, "textureProjLod", nullptr },
{ EOpTextureProjLodOffset, "textureProjLodOffset", nullptr },
{ EOpTextureGrad, "textureGrad", nullptr },
{ EOpTextureGradOffset, "textureGradOffset", nullptr },
{ EOpTextureProjGrad, "textureProjGrad", nullptr },
{ EOpTextureProjGradOffset, "textureProjGradOffset", nullptr },
{ EOpNull }
{ EOpTextureQuerySize, "textureSize", {} },
{ EOpTextureQueryLod, "textureQueryLod", {} },
{ EOpTextureQueryLod, "textureQueryLOD", {} }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", {} },
{ EOpTextureQuerySamples, "textureSamples", {} },
{ EOpTexture, "texture", {} },
{ EOpTextureProj, "textureProj", {} },
{ EOpTextureLod, "textureLod", {} },
{ EOpTextureOffset, "textureOffset", {} },
{ EOpTextureFetch, "texelFetch", {} },
{ EOpTextureFetchOffset, "texelFetchOffset", {} },
{ EOpTextureProjOffset, "textureProjOffset", {} },
{ EOpTextureLodOffset, "textureLodOffset", {} },
{ EOpTextureProjLod, "textureProjLod", {} },
{ EOpTextureProjLodOffset, "textureProjLodOffset", {} },
{ EOpTextureGrad, "textureGrad", {} },
{ EOpTextureGradOffset, "textureGradOffset", {} },
{ EOpTextureProjGrad, "textureProjGrad", {} },
{ EOpTextureProjGradOffset, "textureProjGradOffset", {} },
};
// For the given table of functions, add all the indicated prototypes for each
@ -403,13 +396,13 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function)
bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */)
{
// nullptr means always valid
if (function.versioning == nullptr)
if (function.versioning.empty())
return true;
// check for what is said about our current profile
for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) {
if ((v->profiles & profile) != 0) {
if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version))
for (const auto& v : function.versioning) {
if ((v.profiles & profile) != 0) {
if (v.minCoreVersion <= version || (v.numExtensions > 0 && v.minExtendedVersion <= version))
return true;
}
}
@ -422,12 +415,11 @@ bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile
// called once per stage). This is a performance issue only, not a correctness
// concern. It is done for quality arising from simplicity, as there are subtleties
// to get correct if instead trying to do it surgically.
template<class FunctionT>
void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
template<class FunctionContainer>
void RelateTabledBuiltins(const FunctionContainer& functions, TSymbolTable& symbolTable)
{
while (functions->op != EOpNull) {
symbolTable.relateToOperator(functions->name, functions->op);
++functions;
for (const auto& fn : functions) {
symbolTable.relateToOperator(fn.name, fn.op);
}
}
@ -436,11 +428,10 @@ void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
// Add declarations for all tables of built-in functions.
void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion)
{
const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) {
while (function->op != EOpNull) {
if (ValidVersion(*function, version, profile, spvVersion))
AddTabledBuiltin(decls, *function);
++function;
const auto forEachFunction = [&](TString& decls, const span<const BuiltInFunction>& functions) {
for (const auto& fn : functions) {
if (ValidVersion(fn, version, profile, spvVersion))
AddTabledBuiltin(decls, fn);
}
};
@ -1726,6 +1717,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"vec4 shadow2DRect(sampler2DRectShadow, vec3);" // GL_ARB_texture_rectangle, caught by keyword check
"vec4 shadow2DRectProj(sampler2DRectShadow, vec4);" // GL_ARB_texture_rectangle, caught by keyword check
"vec4 texture1DArray(sampler1DArray, vec2);" // GL_EXT_texture_array
"vec4 texture2DArray(sampler2DArray, vec3);" // GL_EXT_texture_array
"vec4 shadow1DArray(sampler1DArrayShadow, vec3);" // GL_EXT_texture_array
"vec4 shadow2DArray(sampler2DArrayShadow, vec4);" // GL_EXT_texture_array
"vec4 texture1DArray(sampler1DArray, vec2, float);" // GL_EXT_texture_array
"vec4 texture2DArray(sampler2DArray, vec3, float);" // GL_EXT_texture_array
"vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array
"vec4 texture1DArrayLod(sampler1DArray, vec2, float);" // GL_EXT_texture_array
"vec4 texture2DArrayLod(sampler2DArray, vec3, float);" // GL_EXT_texture_array
"vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array
"\n");
}
}
@ -5246,7 +5247,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangVertex].append(
"int gl_VertexID;" // needs qualifier fixed later
);
if (version >= 140 && spvVersion.vulkan == 0)
if (spvVersion.vulkan == 0)
stageBuiltins[EShLangVertex].append(
"int gl_InstanceID;" // needs qualifier fixed later
);
@ -5301,6 +5302,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangVertex].append(
"highp vec4 gl_Position;" // needs qualifier fixed later
"mediump float gl_PointSize;" // needs qualifier fixed later
"highp int gl_InstanceID;" // needs qualifier fixed later
);
} else {
if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed)
@ -7851,6 +7853,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (spvVersion.vulkan == 0) {
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
if (version < 140)
symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_EXT_draw_instanced);
}
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
@ -8002,6 +8006,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
}
// E_GL_EXT_texture_array
if (profile != EEsProfile && spvVersion.spv == 0) {
symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture1DArrayLod", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture2DArrayLod", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow1DArrayLod", 1, &E_GL_EXT_texture_array);
}
// Fall through
case EShLangTessControl:
@ -9967,6 +9983,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM);
symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM);
}
if (profile != EEsProfile && spvVersion.spv == 0) {
symbolTable.relateToOperator("texture1DArray", EOpTexture);
symbolTable.relateToOperator("texture2DArray", EOpTexture);
symbolTable.relateToOperator("shadow1DArray", EOpTexture);
symbolTable.relateToOperator("shadow2DArray", EOpTexture);
symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod);
symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod);
symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod);
}
}
switch(language) {

View File

@ -2317,6 +2317,40 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
return aggNode;
}
TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right)
{
if (left == nullptr && right == nullptr)
return nullptr;
TIntermAggregate* aggNode = nullptr;
if (left != nullptr)
aggNode = left->getAsAggregate();
if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
aggNode = new TIntermAggregate;
if (left != nullptr)
aggNode->getSequence().push_back(left);
}
TIntermAggregate* rhsagg = right->getAsAggregate();
if (rhsagg == nullptr || rhsagg->getOp() != EOpNull)
aggNode->getSequence().push_back(right);
else
aggNode->getSequence().insert(aggNode->getSequence().end(),
rhsagg->getSequence().begin(),
rhsagg->getSequence().end());
return aggNode;
}
TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
{
TIntermAggregate* aggNode = mergeAggregate(left, right);
if (aggNode)
aggNode->setLoc(loc);
return aggNode;
}
//
// Turn an existing node into an aggregate.
//
@ -2821,10 +2855,9 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag
//}
if (language == EShLangVertex) {
// the names won't be found in the symbol table unless the versions are right,
// so version logic does not need to be repeated here
addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
if ((version < 140 && requestedExtensions.find(E_GL_EXT_draw_instanced) != requestedExtensions.end()) || version >= 140)
addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
}
// Add a child to the root node for the linker objects

View File

@ -722,6 +722,24 @@ void TParseContextBase::finish()
if (parsingBuiltins)
return;
for (const TString& relaxedSymbol : relaxedSymbols)
{
TSymbol* symbol = symbolTable.find(relaxedSymbol);
TType& type = symbol->getWritableType();
for (const TTypeLoc& typeLoc : *type.getStruct())
{
if (typeLoc.type->isOpaque())
{
typeLoc.type->getSampler() = TSampler{};
typeLoc.type->setBasicType(EbtInt);
TString fieldName("/*");
fieldName.append(typeLoc.type->getFieldName());
fieldName.append("*/");
typeLoc.type->setFieldName(fieldName);
}
}
}
// Transfer the linkage symbols to AST nodes, preserving order.
TIntermAggregate* linkage = new TIntermAggregate;
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)

View File

@ -993,17 +993,25 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
break;
}
}
if (fieldFound) {
if (base->getType().getQualifier().isFrontEndConstant())
result = intermediate.foldDereference(base, member, loc);
else {
blockMemberExtensionCheck(loc, base, member, field);
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[member].type);
if ((*fields)[member].type->getQualifier().isIo())
intermediate.addIoAccessed(field);
if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed)
result = vkRelaxedRemapDotDereference(loc, *base, *(*fields)[member].type, field);
if (result == base)
{
if (base->getType().getQualifier().isFrontEndConstant())
result = intermediate.foldDereference(base, member, loc);
else {
blockMemberExtensionCheck(loc, base, member, field);
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[member].type);
if ((*fields)[member].type->getQualifier().isIo())
intermediate.addIoAccessed(field);
}
}
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
} else {
auto baseSymbol = base;
@ -1655,7 +1663,9 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
}
} else {
if (value->getType().isTexture() || value->getType().isImage()) {
if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
if (spvVersion.spv != 0)
error(loc, "sampler or image cannot be used as return type when generating SPIR-V", "return", "");
else if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
error(loc, "sampler or image can be used as return type only when the extension GL_ARB_bindless_texture enabled", "return", "");
}
branch = intermediate.addBranch(EOpReturn, value, loc);
@ -7357,12 +7367,14 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub
}
}
bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&,
bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType,
TArraySizes*, TIntermTyped* initializer, TType& type)
{
vkRelaxedRemapUniformMembers(loc, publicType, type, identifier);
if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() ||
type.getQualifier().storage != EvqUniform ||
!(type.containsNonOpaque()|| type.getBasicType() == EbtAtomicUint)) {
!(type.containsNonOpaque() || type.getBasicType() == EbtAtomicUint || (type.containsSampler() && type.isStruct()))) {
return false;
}
@ -7436,6 +7448,251 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString
return true;
}
template <typename Function>
static void ForEachOpaque(const TType& type, const TString& path, Function callback)
{
auto recursion = [&callback](const TType& type, const TString& path, bool skipArray, auto& recursion) -> void {
if (!skipArray && type.isArray())
{
std::vector<int> indices(type.getArraySizes()->getNumDims());
for (int flatIndex = 0;
flatIndex < type.getArraySizes()->getCumulativeSize();
++flatIndex)
{
TString subscriptPath = path;
for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
{
int index = indices[dimIndex];
subscriptPath.append("[");
subscriptPath.append(String(index));
subscriptPath.append("]");
}
recursion(type, subscriptPath, true, recursion);
for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
{
++indices[dimIndex];
if (indices[dimIndex] < type.getArraySizes()->getDimSize(dimIndex))
break;
else
indices[dimIndex] = 0;
}
}
}
else if (type.isStruct() && type.containsOpaque())
{
const TTypeList& types = *type.getStruct();
for (const TTypeLoc& typeLoc : types)
{
TString nextPath = path;
nextPath.append(".");
nextPath.append(typeLoc.type->getFieldName());
recursion(*(typeLoc.type), nextPath, false, recursion);
}
}
else if (type.isOpaque())
{
callback(type, path);
}
};
recursion(type, path, false, recursion);
}
void TParseContext::vkRelaxedRemapUniformMembers(const TSourceLoc& loc, const TPublicType& publicType, const TType& type,
const TString& identifier)
{
if (!type.isStruct() || !type.containsOpaque())
return;
ForEachOpaque(type, identifier,
[&publicType, &loc, this](const TType& type, const TString& path) {
TArraySizes arraySizes = {};
if (type.getArraySizes()) arraySizes = *type.getArraySizes();
TTypeParameters typeParameters = {};
if (type.getTypeParameters()) typeParameters = *type.getTypeParameters();
TPublicType memberType{};
memberType.basicType = type.getBasicType();
memberType.sampler = type.getSampler();
memberType.qualifier = type.getQualifier();
memberType.vectorSize = type.getVectorSize();
memberType.matrixCols = type.getMatrixCols();
memberType.matrixRows = type.getMatrixRows();
memberType.coopmatNV = type.isCoopMatNV();
memberType.coopmatKHR = type.isCoopMatKHR();
memberType.arraySizes = nullptr;
memberType.userDef = nullptr;
memberType.loc = loc;
memberType.typeParameters = (type.getTypeParameters() ? &typeParameters : nullptr);
memberType.spirvType = nullptr;
memberType.qualifier.storage = publicType.qualifier.storage;
memberType.shaderQualifiers = publicType.shaderQualifiers;
TString& structMemberName = *NewPoolTString(path.c_str()); // A copy is required due to declareVariable() signature.
declareVariable(loc, structMemberName, memberType, nullptr, nullptr);
});
}
void TParseContext::vkRelaxedRemapFunctionParameter(TFunction* function, TParameter& param, std::vector<int>* newParams)
{
function->addParameter(param);
if (!param.type->isStruct() || !param.type->containsOpaque())
return;
ForEachOpaque(*param.type, (param.name ? *param.name : param.type->getFieldName()),
[function, param, newParams](const TType& type, const TString& path) {
TString* memberName = NewPoolTString(path.c_str());
TType* memberType = new TType();
memberType->shallowCopy(type);
memberType->getQualifier().storage = param.type->getQualifier().storage;
memberType->clearArraySizes();
TParameter memberParam = {};
memberParam.name = memberName;
memberParam.type = memberType;
memberParam.defaultValue = nullptr;
function->addParameter(memberParam);
if (newParams)
newParams->push_back(function->getParamCount()-1);
});
}
//
// Generates a valid GLSL dereferencing string for the input TIntermNode
//
struct AccessChainTraverser : public TIntermTraverser {
AccessChainTraverser() : TIntermTraverser(false, false, true)
{}
TString path = "";
bool visitBinary(TVisit, TIntermBinary* binary) override {
if (binary->getOp() == EOpIndexDirectStruct)
{
const TTypeList& members = *binary->getLeft()->getType().getStruct();
const TTypeLoc& member =
members[binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()];
TString memberName = member.type->getFieldName();
if (path != "")
path.append(".");
path.append(memberName);
}
if (binary->getOp() == EOpIndexDirect)
{
const TConstUnionArray& indices = binary->getRight()->getAsConstantUnion()->getConstArray();
for (int index = 0; index < indices.size(); ++index)
{
path.append("[");
path.append(String(indices[index].getIConst()));
path.append("]");
}
}
return true;
}
void visitSymbol(TIntermSymbol* symbol) override {
if (!IsAnonymous(symbol->getName()))
path.append(symbol->getName());
}
};
TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc, TFunction* function, TIntermTyped* intermTyped)
{
AccessChainTraverser accessChainTraverser{};
intermTyped->traverse(&accessChainTraverser);
TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType };
param.type->shallowCopy(intermTyped->getType());
std::vector<int> newParams = {};
vkRelaxedRemapFunctionParameter(function, param, &newParams);
if (intermTyped->getType().isOpaque())
{
TIntermNode* remappedArgument = intermTyped;
{
TIntermSymbol* intermSymbol = nullptr;
TSymbol* symbol = symbolTable.find(*param.name);
if (symbol && symbol->getAsVariable())
intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
else
{
TVariable* variable = new TVariable(param.name, *param.type);
intermSymbol = intermediate.addSymbol(*variable, loc);
}
remappedArgument = intermSymbol;
}
return remappedArgument;
}
else if (!(intermTyped->isStruct() && intermTyped->getType().containsOpaque()))
return intermTyped;
else
{
TIntermNode* remappedArgument = intermTyped;
{
TSymbol* symbol = symbolTable.find(*param.name);
if (symbol && symbol->getAsVariable())
remappedArgument = intermediate.addSymbol(*symbol->getAsVariable(), loc);
}
if (!newParams.empty())
remappedArgument = intermediate.makeAggregate(remappedArgument, loc);
for (int paramIndex : newParams)
{
TParameter& newParam = function->operator[](paramIndex);
TIntermSymbol* intermSymbol = nullptr;
TSymbol* symbol = symbolTable.find(*newParam.name);
if (symbol && symbol->getAsVariable())
intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
else
{
TVariable* variable = new TVariable(newParam.name, *newParam.type);
intermSymbol = intermediate.addSymbol(*variable, loc);
}
remappedArgument = intermediate.growAggregate(remappedArgument, intermSymbol);
}
return remappedArgument;
}
}
TIntermTyped* TParseContext::vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped& base, const TType& member,
const TString& identifier)
{
if (!member.isOpaque())
return &base;
AccessChainTraverser traverser{};
base.traverse(&traverser);
if (!traverser.path.empty())
traverser.path.append(".");
traverser.path.append(identifier);
const TSymbol* symbol = symbolTable.find(traverser.path);
if (!symbol)
return &base;
TIntermTyped* result = intermediate.addSymbol(*symbol->getAsVariable());
result->setType(symbol->getType());
return result;
}
//
// Do everything necessary to handle a variable (non-block) declaration.
// Either redeclaring a variable, or making a new one, updating the symbol

View File

@ -180,6 +180,7 @@ public:
// Basic parsing state, easily accessible to the grammar
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
TVector<TString> relaxedSymbols;
int statementNestingLevel; // 0 if outside all flow control or compound statements
int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // 0 if outside structures
@ -367,6 +368,10 @@ public:
TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
// returns true if the variable was remapped to something else
bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
void vkRelaxedRemapUniformMembers(const TSourceLoc&, const TPublicType&, const TType&, const TString&);
void vkRelaxedRemapFunctionParameter(TFunction*, TParameter&, std::vector<int>* newParams = nullptr);
TIntermNode* vkRelaxedRemapFunctionArgument(const TSourceLoc&, TFunction*, TIntermTyped*);
TIntermTyped* vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped&, const TType&, const TString&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand);

View File

@ -1496,6 +1496,12 @@ int TScanContext::tokenizeIdentifier()
case USAMPLERCUBE:
case USAMPLER2DARRAY:
afterType = true;
if (keyword == SAMPLER2DARRAY || keyword == SAMPLER2DARRAYSHADOW) {
if (!parseContext.isEsProfile() &&
(parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
return keyword;
}
}
return nonreservedKeyword(300, 130);
case SAMPLER3D:
@ -1539,6 +1545,12 @@ int TScanContext::tokenizeIdentifier()
case USAMPLER1D:
case USAMPLER1DARRAY:
afterType = true;
if (keyword == SAMPLER1DARRAYSHADOW) {
if (!parseContext.isEsProfile() &&
(parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
return keyword;
}
}
return es30ReservedFromGLSL(130);
case ISAMPLER2DRECT:
case USAMPLER2DRECT:
@ -1608,7 +1620,9 @@ int TScanContext::tokenizeIdentifier()
if (parseContext.isEsProfile() && parseContext.version == 300)
reservedWord();
else if ((parseContext.isEsProfile() && parseContext.version < 300) ||
(!parseContext.isEsProfile() && parseContext.version < 130))
((!parseContext.isEsProfile() && parseContext.version < 130) &&
!parseContext.symbolTable.atBuiltInLevel() &&
!parseContext.extensionTurnedOn(E_GL_EXT_texture_array)))
return identifierOrType();
return keyword;

View File

@ -58,7 +58,6 @@
#endif
#include "../Include/ShHandle.h"
#include "../../OGLCompilersDLL/InitializeDll.h"
#include "preprocessor/PpContext.h"
@ -1311,9 +1310,6 @@ bool CompileDeferred(
//
int ShInitialize()
{
if (! InitProcess())
return 0;
const std::lock_guard<std::mutex> lock(init_lock);
++NumberOfClients;
@ -1335,9 +1331,6 @@ int ShInitialize()
ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/)
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, 0));
return reinterpret_cast<void*>(base);
@ -1345,9 +1338,6 @@ ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unus
ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/)
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, 0));
return reinterpret_cast<void*>(base);
@ -1355,9 +1345,6 @@ ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions un
ShHandle ShConstructUniformMap()
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
return reinterpret_cast<void*>(base);
@ -1871,8 +1858,6 @@ void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlatt
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages messages, Includer& includer)
{
if (! InitThread())
return false;
SetThreadPoolAllocator(pool);
if (! preamble)
@ -1897,8 +1882,6 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
std::string* output_string,
Includer& includer)
{
if (! InitThread())
return false;
SetThreadPoolAllocator(pool);
if (! preamble)

View File

@ -359,6 +359,8 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
extensionBehavior[E_GL_EXT_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_array] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@ -487,7 +489,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_vertex_attrib_64bit 1\n"
"#define GL_ARB_draw_instanced 1\n"
"#define GL_ARB_fragment_coord_conventions 1\n"
"#define GL_ARB_bindless_texture 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
@ -580,8 +582,13 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_atomic_float2 1\n"
"#define GL_EXT_fragment_shader_barycentric 1\n"
"#define GL_EXT_texture_array 1\n"
;
if (spvVersion.spv == 0) {
preamble += "#define GL_ARB_bindless_texture 1\n";
}
if (version >= 150) {
// define GL_core_profile and GL_compatibility_profile
preamble += "#define GL_core_profile 1\n";

View File

@ -215,6 +215,8 @@ const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intr
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap";
const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced";
const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array";
// Arrays of extensions for the above viewportEXTs duplications

View File

@ -110,13 +110,6 @@ using namespace glslang;
%{
/* windows only pragma */
#ifdef _MSC_VER
#pragma warning(disable : 4065)
#pragma warning(disable : 4127)
#pragma warning(disable : 4244)
#endif
#define parseContext (*pParseContext)
#define yyerror(context, msg) context->parserError(msg)
@ -492,18 +485,41 @@ function_call_header_no_parameters
function_call_header_with_parameters
: function_call_header assignment_expression {
TParameter param = { 0, new TType };
param.type->shallowCopy($2->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = $2;
if (parseContext.spvVersion.vulkan > 0
&& parseContext.spvVersion.vulkanRelaxed
&& $2->getType().containsOpaque())
{
$$.intermNode = parseContext.vkRelaxedRemapFunctionArgument($$.loc, $1.function, $2);
$$.function = $1.function;
}
else
{
TParameter param = { 0, new TType };
param.type->shallowCopy($2->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = $2;
}
}
| function_call_header_with_parameters COMMA assignment_expression {
TParameter param = { 0, new TType };
param.type->shallowCopy($3->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
if (parseContext.spvVersion.vulkan > 0
&& parseContext.spvVersion.vulkanRelaxed
&& $3->getType().containsOpaque())
{
TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument($2.loc, $1.function, $3);
$$.intermNode = parseContext.intermediate.mergeAggregate($1.intermNode, remappedNode, $2.loc);
$$.function = $1.function;
}
else
{
TParameter param = { 0, new TType };
param.type->shallowCopy($3->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
}
}
;
@ -980,7 +996,12 @@ function_header_with_parameters
// Add the parameter
$$ = $1;
if ($2.param.type->getBasicType() != EbtVoid)
$1->addParameter($2.param);
{
if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
$1->addParameter($2.param);
else
parseContext.vkRelaxedRemapFunctionParameter($1, $2.param);
}
else
delete $2.param.type;
}
@ -998,7 +1019,10 @@ function_header_with_parameters
} else {
// Add the parameter
$$ = $1;
$1->addParameter($3.param);
if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
$1->addParameter($3.param);
else
parseContext.vkRelaxedRemapFunctionParameter($1, $3.param);
}
}
;
@ -3549,11 +3573,17 @@ precision_qualifier
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($5, *$2.string);
parseContext.structArrayCheck($2.loc, *structure);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct");
else if (parseContext.spvVersion.vulkanRelaxed
&& structure->containsOpaque())
parseContext.relaxedSymbols.push_back(structure->getTypeName());
$$.init($1.loc);
$$.basicType = EbtStruct;
$$.userDef = structure;

File diff suppressed because it is too large Load Diff

View File

@ -528,6 +528,8 @@ public:
TOperator mapTypeToConstructorOp(const TType&) const;
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* makeAggregate(TIntermNode* node);
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
TIntermAggregate* makeAggregate(const TSourceLoc&);

View File

@ -86,11 +86,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../ParseHelper.h"
#include "PpTokens.h"
/* windows only pragma */
#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif
namespace glslang {
class TPpToken {
@ -220,6 +215,7 @@ public:
virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
virtual bool isMacroInput() { return false; }
virtual bool isStringInput() { return false; }
// Will be called when we start reading tokens from this instance
virtual void notifyActivated() {}
@ -360,7 +356,8 @@ protected:
// Scanner data:
int previous_token;
TParseContextBase& parseContext;
std::vector<int> lastLineTokens;
std::vector<TSourceLoc> lastLineTokenLocs;
// Get the next token from *stack* of input sources, popping input sources
// that are out of tokens, down until an input source is found that has a token.
// Return EndOfInput when there are no more tokens to be found by doing this.
@ -374,7 +371,31 @@ protected:
break;
popInput();
}
if (!inputStack.empty() && inputStack.back()->isStringInput()) {
if (token == '\n') {
bool seenNumSign = false;
for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
int curPos = i;
int curToken = lastLineTokens[i++];
if (curToken == '#' && lastLineTokens[i] == '#') {
curToken = PpAtomPaste;
i++;
}
if (curToken == '#') {
if (seenNumSign) {
parseContext.ppError(lastLineTokenLocs[curPos], "(#) can be preceded in its line only by spaces or horizontal tabs", "#", "");
} else {
seenNumSign = true;
}
}
}
lastLineTokens.clear();
lastLineTokenLocs.clear();
} else {
lastLineTokens.push_back(token);
lastLineTokenLocs.push_back(ppToken->loc);
}
}
return token;
}
int getChar() { return inputStack.back()->getch(); }
@ -527,7 +548,7 @@ protected:
public:
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
virtual int scan(TPpToken*) override;
bool isStringInput() override { return true; }
// Scanner used to get source stream characters.
// - Escaped newlines are handled here, invisibly to the caller.
// - All forms of newline are handled, and turned into just a '\n'.

View File

@ -0,0 +1,92 @@
#pragma once
//
// Copyright (C) 2023 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Partial implementation of std::span for C++11
// Replace with std::span if repo standard is bumped to C++20
//
// This code was copied from https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/layers/containers/custom_containers.h
template <typename T>
class span {
public:
using pointer = T *;
using const_pointer = T const *;
using iterator = pointer;
using const_iterator = const_pointer;
span() = default;
span(pointer start, size_t n) : data_(start), count_(n) {}
template <typename Iterator>
span(Iterator start, Iterator end) : data_(&(*start)), count_(end - start) {}
template <typename Container>
span(Container &c) : data_(c.data()), count_(c.size()) {}
iterator begin() { return data_; }
const_iterator begin() const { return data_; }
iterator end() { return data_ + count_; }
const_iterator end() const { return data_ + count_; }
T &operator[](int i) { return data_[i]; }
const T &operator[](int i) const { return data_[i]; }
T &front() { return *data_; }
const T &front() const { return *data_; }
T &back() { return *(data_ + (count_ - 1)); }
const T &back() const { return *(data_ + (count_ - 1)); }
size_t size() const { return count_; }
bool empty() const { return count_ == 0; }
pointer data() { return data_; }
const_pointer data() const { return data_; }
private:
pointer data_ = {};
size_t count_ = 0;
};
//
// Allow type inference that using the constructor doesn't allow in C++11
template <typename T>
span<T> make_span(T *begin, size_t count) {
return span<T>(begin, count);
}
template <typename T>
span<T> make_span(T *begin, T *end) {
return make_span<T>(begin, end);
}

View File

@ -42,28 +42,14 @@ const glslang_resource_t* glslang_default_resource(void)
return reinterpret_cast<const glslang_resource_t*>(GetDefaultResources());
}
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
const char* glslang_default_resource_string()
{
std::string cpp_str = GetDefaultTBuiltInResourceString();
char* c_str = (char*)malloc(cpp_str.length() + 1);
strcpy(c_str, cpp_str.c_str());
strncpy(c_str, cpp_str.c_str(), cpp_str.length() + 1);
return c_str;
}
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
void glslang_decode_resource_limits(glslang_resource_t* resources, char* config)
{
DecodeResourceLimits(reinterpret_cast<TBuiltInResource*>(resources), config);