Upgrade glslang to 11.10.0

This commit is contained in:
Magnus Norddahl 2022-06-12 07:59:07 +02:00 committed by Christoph Oelckers
parent 32d059e432
commit 5cc21c5a4a
53 changed files with 5696 additions and 4693 deletions

View file

@ -263,6 +263,7 @@ enum TBuiltInVariable {
EbvObjectRayDirection,
EbvRayTmin,
EbvRayTmax,
EbvCullMask,
EbvHitT,
EbvHitKind,
EbvObjectToWorld,
@ -274,6 +275,8 @@ enum TBuiltInVariable {
// barycentrics
EbvBaryCoordNV,
EbvBaryCoordNoPerspNV,
EbvBaryCoordEXT,
EbvBaryCoordNoPerspEXT,
// mesh shaders
EbvTaskCountNV,
EbvPrimitiveCountNV,
@ -478,8 +481,10 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvWorldToObject: return "WorldToObjectNV";
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
case EbvBaryCoordNV: return "BaryCoordNV";
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case EbvBaryCoordEXT:
case EbvBaryCoordNV: return "BaryCoordKHR";
case EbvBaryCoordNoPerspEXT:
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspKHR";
case EbvTaskCountNV: return "TaskCountNV";
case EbvPrimitiveCountNV: return "PrimitiveCountNV";

View file

@ -39,6 +39,11 @@
#include <algorithm>
#include <cassert>
#ifdef _MSC_VER
#include <cfloat>
#else
#include <cmath>
#endif
#include <cstdio>
#include <cstdlib>
#include <list>
@ -61,7 +66,7 @@ std::string to_string(const T& val) {
}
#endif
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
#include <basetsd.h>
#ifndef snprintf
#define snprintf sprintf_s
@ -213,7 +218,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
//
// Create a TString object from an integer.
//
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
#if defined _MSC_VER || MINGW_HAS_SECURE_API
inline const TString String(const int i, const int base = 10)
{
char text[16]; // 32 bit ints are at most 10 digits in base 10
@ -302,6 +307,34 @@ template <class T> int IntLog2(T n)
return result;
}
inline bool IsInfinity(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return true;
default:
return false;
}
#else
return std::isinf(x);
#endif
}
inline bool IsNan(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return true;
default:
return false;
}
#else
return std::isnan(x);
#endif
}
} // end namespace glslang
#endif // _COMMON_INCLUDED_

View file

@ -306,6 +306,8 @@ public:
TPoolAllocator& getAllocator() const { return allocator; }
pool_allocator select_on_container_copy_construction() const { return pool_allocator{}; }
protected:
pool_allocator& operator=(const pool_allocator&) { return *this; }
TPoolAllocator& allocator;

View file

@ -65,7 +65,7 @@ struct TSpirvExecutionMode {
// spirv_execution_mode
TMap<int, TVector<const TIntermConstantUnion*>> modes;
// spirv_execution_mode_id
TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
TMap<int, TVector<const TIntermTyped*> > modeIds;
};
// SPIR-V decorations
@ -75,7 +75,7 @@ struct TSpirvDecorate {
// spirv_decorate
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
// spirv_decorate_id
TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
TMap<int, TVector<const TIntermTyped*>> decorateIds;
// spirv_decorate_string
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
};
@ -98,20 +98,12 @@ struct TSpirvInstruction {
struct TSpirvTypeParameter {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; }
bool operator==(const TSpirvTypeParameter& rhs) const
{
return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
}
bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; }
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
bool isConstant;
union {
const TIntermConstantUnion* constant;
const TType* type;
};
const TIntermConstantUnion* constant;
};
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;

View file

@ -552,6 +552,7 @@ public:
perViewNV = false;
perTaskNV = false;
#endif
pervertexEXT = false;
}
void clearMemory()
@ -604,7 +605,8 @@ public:
bool isNoContraction() const { return false; }
void setNoContraction() { }
bool isPervertexNV() const { return false; }
void setNullInit() { }
bool isPervertexEXT() const { return pervertexEXT; }
void setNullInit() {}
bool isNullInit() const { return false; }
void setSpirvByReference() { }
bool isSpirvByReference() { return false; }
@ -615,6 +617,7 @@ public:
bool nopersp : 1;
bool explicitInterp : 1;
bool pervertexNV : 1;
bool pervertexEXT : 1;
bool perPrimitiveNV : 1;
bool perViewNV : 1;
bool perTaskNV : 1;
@ -663,12 +666,13 @@ public:
}
bool isAuxiliary() const
{
return centroid || patch || sample || pervertexNV;
return centroid || patch || sample || pervertexNV || pervertexEXT;
}
bool isPatch() const { return patch; }
bool isNoContraction() const { return noContraction; }
void setNoContraction() { noContraction = true; }
bool isPervertexNV() const { return pervertexNV; }
bool isPervertexEXT() const { return pervertexEXT; }
void setNullInit() { nullInit = true; }
bool isNullInit() const { return nullInit; }
void setSpirvByReference() { spirvByReference = true; }
@ -741,6 +745,16 @@ public:
}
}
bool isUniform() const
{
switch (storage) {
case EvqUniform:
return true;
default:
return false;
}
}
bool isIo() const
{
switch (storage) {
@ -846,7 +860,7 @@ public:
case EShLangTessEvaluation:
return ! patch && isPipeInput();
case EShLangFragment:
return pervertexNV && isPipeInput();
return (pervertexNV || pervertexEXT) && isPipeInput();
case EShLangMeshNV:
return ! perTaskNV && isPipeOutput();
@ -1855,10 +1869,12 @@ public:
bool isAtomic() const { return false; }
bool isCoopMat() const { return false; }
bool isReference() const { return false; }
bool isSpirvType() const { return false; }
#else
bool isAtomic() const { return basicType == EbtAtomicUint; }
bool isCoopMat() const { return coopmat; }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
#endif
// return true if this type contains any subtype which satisfies the given predicate.
@ -2130,7 +2146,8 @@ public:
const char* getPrecisionQualifierString() const { return ""; }
TString getBasicTypeString() const { return ""; }
#else
TString getCompleteString() const
TString getCompleteString(bool syntactic = false, bool getQualifiers = true, bool getPrecision = true,
bool getType = true, TString name = "", TString structName = "") const
{
TString typeString;
@ -2138,232 +2155,337 @@ public:
const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
if (qualifier.hasSprivDecorate())
if (getQualifiers) {
if (qualifier.hasSprivDecorate())
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
if (qualifier.hasLayout()) {
if (qualifier.hasLayout()) {
// To reduce noise, skip this if the only layout is an xfb_buffer
// with no triggering xfb_offset.
TQualifier noXfbBuffer = qualifier;
noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
if (noXfbBuffer.hasLayout()) {
appendStr("layout(");
if (qualifier.hasAnyLocation()) {
appendStr(" location=");
appendUint(qualifier.layoutLocation);
if (qualifier.hasComponent()) {
appendStr(" component=");
appendUint(qualifier.layoutComponent);
}
if (qualifier.hasIndex()) {
appendStr(" index=");
appendUint(qualifier.layoutIndex);
}
appendStr("layout(");
if (qualifier.hasAnyLocation()) {
appendStr(" location=");
appendUint(qualifier.layoutLocation);
if (qualifier.hasComponent()) {
appendStr(" component=");
appendUint(qualifier.layoutComponent);
}
if (qualifier.hasSet()) {
appendStr(" set=");
appendUint(qualifier.layoutSet);
}
if (qualifier.hasBinding()) {
appendStr(" binding=");
appendUint(qualifier.layoutBinding);
}
if (qualifier.hasStream()) {
appendStr(" stream=");
appendUint(qualifier.layoutStream);
}
if (qualifier.hasMatrix()) {
appendStr(" ");
appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
}
if (qualifier.hasPacking()) {
appendStr(" ");
appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking));
}
if (qualifier.hasOffset()) {
appendStr(" offset=");
appendInt(qualifier.layoutOffset);
}
if (qualifier.hasAlign()) {
appendStr(" align=");
appendInt(qualifier.layoutAlign);
}
if (qualifier.hasFormat()) {
appendStr(" ");
appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat));
}
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) {
appendStr(" xfb_buffer=");
appendUint(qualifier.layoutXfbBuffer);
}
if (qualifier.hasXfbOffset()) {
appendStr(" xfb_offset=");
appendUint(qualifier.layoutXfbOffset);
}
if (qualifier.hasXfbStride()) {
appendStr(" xfb_stride=");
appendUint(qualifier.layoutXfbStride);
}
if (qualifier.hasAttachment()) {
appendStr(" input_attachment_index=");
appendUint(qualifier.layoutAttachment);
}
if (qualifier.hasSpecConstantId()) {
appendStr(" constant_id=");
appendUint(qualifier.layoutSpecConstantId);
}
if (qualifier.layoutPushConstant)
appendStr(" push_constant");
if (qualifier.layoutBufferReference)
appendStr(" buffer_reference");
if (qualifier.hasBufferReferenceAlign()) {
appendStr(" buffer_reference_align=");
appendUint(1u << qualifier.layoutBufferReferenceAlign);
if (qualifier.hasIndex()) {
appendStr(" index=");
appendUint(qualifier.layoutIndex);
}
}
if (qualifier.hasSet()) {
appendStr(" set=");
appendUint(qualifier.layoutSet);
}
if (qualifier.hasBinding()) {
appendStr(" binding=");
appendUint(qualifier.layoutBinding);
}
if (qualifier.hasStream()) {
appendStr(" stream=");
appendUint(qualifier.layoutStream);
}
if (qualifier.hasMatrix()) {
appendStr(" ");
appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
}
if (qualifier.hasPacking()) {
appendStr(" ");
appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking));
}
if (qualifier.hasOffset()) {
appendStr(" offset=");
appendInt(qualifier.layoutOffset);
}
if (qualifier.hasAlign()) {
appendStr(" align=");
appendInt(qualifier.layoutAlign);
}
if (qualifier.hasFormat()) {
appendStr(" ");
appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat));
}
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) {
appendStr(" xfb_buffer=");
appendUint(qualifier.layoutXfbBuffer);
}
if (qualifier.hasXfbOffset()) {
appendStr(" xfb_offset=");
appendUint(qualifier.layoutXfbOffset);
}
if (qualifier.hasXfbStride()) {
appendStr(" xfb_stride=");
appendUint(qualifier.layoutXfbStride);
}
if (qualifier.hasAttachment()) {
appendStr(" input_attachment_index=");
appendUint(qualifier.layoutAttachment);
}
if (qualifier.hasSpecConstantId()) {
appendStr(" constant_id=");
appendUint(qualifier.layoutSpecConstantId);
}
if (qualifier.layoutPushConstant)
appendStr(" push_constant");
if (qualifier.layoutBufferReference)
appendStr(" buffer_reference");
if (qualifier.hasBufferReferenceAlign()) {
appendStr(" buffer_reference_align=");
appendUint(1u << qualifier.layoutBufferReferenceAlign);
}
if (qualifier.layoutPassthrough)
appendStr(" passthrough");
if (qualifier.layoutViewportRelative)
appendStr(" layoutViewportRelative");
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
appendStr(" layoutSecondaryViewportRelativeOffset=");
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
}
if (qualifier.layoutShaderRecord)
appendStr(" shaderRecordNV");
if (qualifier.layoutPassthrough)
appendStr(" passthrough");
if (qualifier.layoutViewportRelative)
appendStr(" layoutViewportRelative");
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
appendStr(" layoutSecondaryViewportRelativeOffset=");
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
}
if (qualifier.layoutShaderRecord)
appendStr(" shaderRecordNV");
appendStr(")");
appendStr(")");
}
}
}
if (qualifier.invariant)
if (qualifier.invariant)
appendStr(" invariant");
if (qualifier.noContraction)
if (qualifier.noContraction)
appendStr(" noContraction");
if (qualifier.centroid)
if (qualifier.centroid)
appendStr(" centroid");
if (qualifier.smooth)
if (qualifier.smooth)
appendStr(" smooth");
if (qualifier.flat)
if (qualifier.flat)
appendStr(" flat");
if (qualifier.nopersp)
if (qualifier.nopersp)
appendStr(" noperspective");
if (qualifier.explicitInterp)
if (qualifier.explicitInterp)
appendStr(" __explicitInterpAMD");
if (qualifier.pervertexNV)
if (qualifier.pervertexNV)
appendStr(" pervertexNV");
if (qualifier.perPrimitiveNV)
if (qualifier.pervertexEXT)
appendStr(" pervertexEXT");
if (qualifier.perPrimitiveNV)
appendStr(" perprimitiveNV");
if (qualifier.perViewNV)
if (qualifier.perViewNV)
appendStr(" perviewNV");
if (qualifier.perTaskNV)
if (qualifier.perTaskNV)
appendStr(" taskNV");
if (qualifier.patch)
if (qualifier.patch)
appendStr(" patch");
if (qualifier.sample)
if (qualifier.sample)
appendStr(" sample");
if (qualifier.coherent)
if (qualifier.coherent)
appendStr(" coherent");
if (qualifier.devicecoherent)
if (qualifier.devicecoherent)
appendStr(" devicecoherent");
if (qualifier.queuefamilycoherent)
if (qualifier.queuefamilycoherent)
appendStr(" queuefamilycoherent");
if (qualifier.workgroupcoherent)
if (qualifier.workgroupcoherent)
appendStr(" workgroupcoherent");
if (qualifier.subgroupcoherent)
if (qualifier.subgroupcoherent)
appendStr(" subgroupcoherent");
if (qualifier.shadercallcoherent)
if (qualifier.shadercallcoherent)
appendStr(" shadercallcoherent");
if (qualifier.nonprivate)
if (qualifier.nonprivate)
appendStr(" nonprivate");
if (qualifier.volatil)
if (qualifier.volatil)
appendStr(" volatile");
if (qualifier.restrict)
if (qualifier.restrict)
appendStr(" restrict");
if (qualifier.readonly)
if (qualifier.readonly)
appendStr(" readonly");
if (qualifier.writeonly)
if (qualifier.writeonly)
appendStr(" writeonly");
if (qualifier.specConstant)
if (qualifier.specConstant)
appendStr(" specialization-constant");
if (qualifier.nonUniform)
if (qualifier.nonUniform)
appendStr(" nonuniform");
if (qualifier.isNullInit())
if (qualifier.isNullInit())
appendStr(" null-init");
if (qualifier.isSpirvByReference())
if (qualifier.isSpirvByReference())
appendStr(" spirv_by_reference");
if (qualifier.isSpirvLiteral())
if (qualifier.isSpirvLiteral())
appendStr(" spirv_literal");
appendStr(" ");
appendStr(getStorageQualifierString());
if (isArray()) {
for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
appendStr(" ");
appendStr(getStorageQualifierString());
}
if (getType) {
if (syntactic) {
if (getPrecision && qualifier.precision != EpqNone) {
appendStr(" ");
appendStr(getPrecisionQualifierString());
}
if (isVector() || isMatrix()) {
appendStr(" ");
switch (basicType) {
case EbtDouble:
appendStr("d");
break;
case EbtInt:
appendStr("i");
break;
case EbtUint:
appendStr("u");
break;
case EbtBool:
appendStr("b");
break;
case EbtFloat:
default:
break;
}
if (isVector()) {
appendStr("vec");
appendInt(vectorSize);
} else {
appendStr("mat");
appendInt(matrixCols);
appendStr("x");
appendInt(matrixRows);
}
} else if (isStruct() && structure) {
appendStr(" ");
appendStr(structName.c_str());
appendStr("{");
bool hasHiddenMember = true;
for (size_t i = 0; i < structure->size(); ++i) {
if (!(*structure)[i].type->hiddenMember()) {
if (!hasHiddenMember)
appendStr(", ");
typeString.append((*structure)[i].type->getCompleteString(syntactic, getQualifiers, getPrecision, getType, (*structure)[i].type->getFieldName()));
hasHiddenMember = false;
}
}
appendStr("}");
} else {
appendStr(" ");
switch (basicType) {
case EbtDouble:
appendStr("double");
break;
case EbtInt:
appendStr("int");
break;
case EbtUint:
appendStr("uint");
break;
case EbtBool:
appendStr("bool");
break;
case EbtFloat:
appendStr("float");
break;
default:
appendStr("unexpected");
break;
}
}
if (name.length() > 0) {
appendStr(" ");
appendStr(name.c_str());
}
if (isArray()) {
for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
int size = arraySizes->getDimSize(i);
if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
appendStr(" runtime-sized array of");
appendStr("[]");
else {
if (size == UnsizedArraySize) {
appendStr(" unsized");
if (i == 0) {
appendStr(" ");
appendInt(arraySizes->getImplicitSize());
}
} else {
appendStr(" ");
appendInt(arraySizes->getDimSize(i));
}
appendStr("-element array of");
if (size == UnsizedArraySize) {
appendStr("[");
if (i == 0)
appendInt(arraySizes->getImplicitSize());
appendStr("]");
}
else {
appendStr("[");
appendInt(arraySizes->getDimSize(i));
appendStr("]");
}
}
}
}
}
if (isParameterized()) {
appendStr("<");
for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) {
}
else {
if (isArray()) {
for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
int size = arraySizes->getDimSize(i);
if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
appendStr(" runtime-sized array of");
else {
if (size == UnsizedArraySize) {
appendStr(" unsized");
if (i == 0) {
appendStr(" ");
appendInt(arraySizes->getImplicitSize());
}
}
else {
appendStr(" ");
appendInt(arraySizes->getDimSize(i));
}
appendStr("-element array of");
}
}
}
if (isParameterized()) {
appendStr("<");
for (int i = 0; i < (int)typeParameters->getNumDims(); ++i) {
appendInt(typeParameters->getDimSize(i));
if (i != (int)typeParameters->getNumDims() - 1)
appendStr(", ");
}
appendStr(">");
}
if (getPrecision && qualifier.precision != EpqNone) {
appendStr(" ");
appendStr(getPrecisionQualifierString());
}
if (isMatrix()) {
appendStr(" ");
appendInt(matrixCols);
appendStr("X");
appendInt(matrixRows);
appendStr(" matrix of");
}
else if (isVector()) {
appendStr(" ");
appendInt(vectorSize);
appendStr("-component vector of");
}
appendStr(" ");
typeString.append(getBasicTypeString());
if (qualifier.builtIn != EbvNone) {
appendStr(" ");
appendStr(getBuiltInVariableString());
}
// Add struct/block members
if (isStruct() && structure) {
appendStr("{");
bool hasHiddenMember = true;
for (size_t i = 0; i < structure->size(); ++i) {
if (!(*structure)[i].type->hiddenMember()) {
if (!hasHiddenMember)
appendStr(", ");
}
appendStr(">");
}
if (qualifier.precision != EpqNone) {
appendStr(" ");
appendStr(getPrecisionQualifierString());
}
if (isMatrix()) {
appendStr(" ");
appendInt(matrixCols);
appendStr("X");
appendInt(matrixRows);
appendStr(" matrix of");
} else if (isVector()) {
appendStr(" ");
appendInt(vectorSize);
appendStr("-component vector of");
}
appendStr(" ");
typeString.append(getBasicTypeString());
if (qualifier.builtIn != EbvNone) {
appendStr(" ");
appendStr(getBuiltInVariableString());
}
// Add struct/block members
if (isStruct() && structure) {
appendStr("{");
bool hasHiddenMember = true;
for (size_t i = 0; i < structure->size(); ++i) {
if (! (*structure)[i].type->hiddenMember()) {
if (!hasHiddenMember)
appendStr(", ");
typeString.append((*structure)[i].type->getCompleteString());
typeString.append(" ");
typeString.append((*structure)[i].type->getFieldName());
hasHiddenMember = false;
typeString.append((*structure)[i].type->getCompleteString());
typeString.append(" ");
typeString.append((*structure)[i].type->getFieldName());
hasHiddenMember = false;
}
}
appendStr("}");
}
appendStr("}");
}
}
return typeString;
@ -2432,13 +2554,27 @@ public:
// type definitions, and member names to be considered the same type.
// This rule applies recursively for nested or embedded types."
//
bool sameStructType(const TType& right) const
// If type mismatch in structure, return member indices through lpidx and rpidx.
// If matching members for either block are exhausted, return -1 for exhausted
// block and the index of the unmatched member. Otherwise return {-1,-1}.
//
bool sameStructType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const
{
// Initialize error to general type mismatch.
if (lpidx != nullptr) {
*lpidx = -1;
*rpidx = -1;
}
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
// TODO: Why return true when neither types are structures?
if ((!isStruct() && !right.isStruct()) ||
(isStruct() && right.isStruct() && structure == right.structure))
return true;
if (!isStruct() || !right.isStruct())
return false;
// Structure names have to match
if (*typeName != *right.typeName)
return false;
@ -2448,17 +2584,30 @@ public:
bool isGLPerVertex = *typeName == "gl_PerVertex";
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
if (!isStruct() || !right.isStruct() ||
(structure->size() != right.structure->size() && !isGLPerVertex))
if (lpidx == nullptr &&
(structure->size() != right.structure->size() && !isGLPerVertex)) {
return false;
}
// Compare the names and types of all the members, which have to match
for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) {
if (lpidx != nullptr) {
*lpidx = static_cast<int>(li);
*rpidx = static_cast<int>(ri);
}
if (li < structure->size() && ri < right.structure->size()) {
if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) {
if (*(*structure)[li].type != *(*right.structure)[ri].type)
return false;
} else {
// Skip hidden members
if ((*structure)[li].type->hiddenMember()) {
ri--;
continue;
} else if ((*right.structure)[ri].type->hiddenMember()) {
li--;
continue;
}
// If one of the members is something that's inconsistently declared, skip over it
// for now.
if (isGLPerVertex) {
@ -2475,11 +2624,19 @@ public:
}
// If we get here, then there should only be inconsistently declared members left
} else if (li < structure->size()) {
if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) {
if (lpidx != nullptr) {
*rpidx = -1;
}
return false;
}
} else {
if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) {
if (lpidx != nullptr) {
*lpidx = -1;
}
return false;
}
}
}
@ -2503,10 +2660,15 @@ public:
return *referentType == *right.referentType;
}
// See if two types match, in all aspects except arrayness
bool sameElementType(const TType& right) const
// See if two types match, in all aspects except arrayness
// If mismatch in structure members, return member indices in lpidx and rpidx.
bool sameElementType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const
{
return basicType == right.basicType && sameElementShape(right);
if (lpidx != nullptr) {
*lpidx = -1;
*rpidx = -1;
}
return basicType == right.basicType && sameElementShape(right, lpidx, rpidx);
}
// See if two type's arrayness match
@ -2540,15 +2702,20 @@ public:
#endif
// See if two type's elements match in all ways except basic type
bool sameElementShape(const TType& right) const
// If mismatch in structure members, return member indices in lpidx and rpidx.
bool sameElementShape(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const
{
return sampler == right.sampler &&
if (lpidx != nullptr) {
*lpidx = -1;
*rpidx = -1;
}
return ((basicType != EbtSampler && right.basicType != EbtSampler) || sampler == right.sampler) &&
vectorSize == right.vectorSize &&
matrixCols == right.matrixCols &&
matrixRows == right.matrixRows &&
vector1 == right.vector1 &&
isCoopMat() == right.isCoopMat() &&
sameStructType(right) &&
sameStructType(right, lpidx, rpidx) &&
sameReferenceType(right);
}

View file

@ -35,7 +35,7 @@
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 11
#define GLSLANG_VERSION_MINOR 6
#define GLSLANG_VERSION_MINOR 10
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""

View file

@ -1155,7 +1155,7 @@ public:
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
bool isAtomic() const { return type.isAtomic(); }
bool isReference() const { return type.isReference(); }
TString getCompleteString() const { return type.getCompleteString(); }
TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
protected:
TIntermTyped& operator=(const TIntermTyped&);
@ -1643,6 +1643,7 @@ public:
~TIntermAggregate() { delete pragmaTable; }
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual const TIntermAggregate* getAsAggregate() const { return this; }
virtual void updatePrecision();
virtual void setOperator(TOperator o) { op = o; }
virtual TIntermSequence& getSequence() { return sequence; }
virtual const TIntermSequence& getSequence() const { return sequence; }

View file

@ -1,3 +0,0 @@
// This header is generated by the make-revision script.
#define GLSLANG_PATCH_LEVEL 3559

View file

@ -1,13 +0,0 @@
// The file revision.h should be updated to the latest version, somehow, on
// check-in, if glslang has changed.
//
// revision.template is the source for revision.h when using SubWCRev as the
// method of updating revision.h. You don't have to do it this way, the
// requirement is only that revision.h gets updated.
//
// revision.h is under source control so that not all consumers of glslang
// source have to figure out how to create revision.h just to get a build
// going. However, if it is not updated, it can be a version behind.
#define GLSLANG_REVISION "$WCREV$"
#define GLSLANG_DATE "$WCDATE$"

View file

@ -42,43 +42,10 @@
#include <cstdlib>
#include <climits>
#ifdef _MSC_VER
#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
#endif
namespace {
using namespace glslang;
typedef union {
double d;
int i[2];
} DoubleIntUnion;
// Some helper functions
bool isNan(double x)
{
DoubleIntUnion u;
// tough to find a platform independent library function, do it directly
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
}
bool isInf(double x)
{
DoubleIntUnion u;
// tough to find a platform independent library function, do it directly
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
(bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
}
const double pi = 3.1415926535897932384626433832795;
} // end anonymous namespace
@ -535,7 +502,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
// Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
unionArray[i].getIConst() == 0x80000000
static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
? -0x7FFFFFFF - 1
: -unionArray[i].getIConst());
break;
@ -667,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpIsNan:
{
newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
break;
}
case EOpIsInf:
{
newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
break;
}

View file

@ -3,7 +3,7 @@
// Copyright (C) 2012-2016 LunarG, Inc.
// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
// Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@ -316,6 +316,7 @@ const CustomFunction CustomFunctions[] = {
{ EOpTextureQuerySize, "textureSize", nullptr },
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
{ EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
{ EOpTextureQuerySamples, "textureSamples", nullptr },
{ EOpTexture, "texture", nullptr },
@ -4159,106 +4160,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"u16vec4 unpack16(uint64_t);"
"i32vec2 unpack32(int64_t);"
"u32vec2 unpack32(uint64_t);"
"float64_t radians(float64_t);"
"f64vec2 radians(f64vec2);"
"f64vec3 radians(f64vec3);"
"f64vec4 radians(f64vec4);"
"float64_t degrees(float64_t);"
"f64vec2 degrees(f64vec2);"
"f64vec3 degrees(f64vec3);"
"f64vec4 degrees(f64vec4);"
"float64_t sin(float64_t);"
"f64vec2 sin(f64vec2);"
"f64vec3 sin(f64vec3);"
"f64vec4 sin(f64vec4);"
"float64_t cos(float64_t);"
"f64vec2 cos(f64vec2);"
"f64vec3 cos(f64vec3);"
"f64vec4 cos(f64vec4);"
"float64_t tan(float64_t);"
"f64vec2 tan(f64vec2);"
"f64vec3 tan(f64vec3);"
"f64vec4 tan(f64vec4);"
"float64_t asin(float64_t);"
"f64vec2 asin(f64vec2);"
"f64vec3 asin(f64vec3);"
"f64vec4 asin(f64vec4);"
"float64_t acos(float64_t);"
"f64vec2 acos(f64vec2);"
"f64vec3 acos(f64vec3);"
"f64vec4 acos(f64vec4);"
"float64_t atan(float64_t, float64_t);"
"f64vec2 atan(f64vec2, f64vec2);"
"f64vec3 atan(f64vec3, f64vec3);"
"f64vec4 atan(f64vec4, f64vec4);"
"float64_t atan(float64_t);"
"f64vec2 atan(f64vec2);"
"f64vec3 atan(f64vec3);"
"f64vec4 atan(f64vec4);"
"float64_t sinh(float64_t);"
"f64vec2 sinh(f64vec2);"
"f64vec3 sinh(f64vec3);"
"f64vec4 sinh(f64vec4);"
"float64_t cosh(float64_t);"
"f64vec2 cosh(f64vec2);"
"f64vec3 cosh(f64vec3);"
"f64vec4 cosh(f64vec4);"
"float64_t tanh(float64_t);"
"f64vec2 tanh(f64vec2);"
"f64vec3 tanh(f64vec3);"
"f64vec4 tanh(f64vec4);"
"float64_t asinh(float64_t);"
"f64vec2 asinh(f64vec2);"
"f64vec3 asinh(f64vec3);"
"f64vec4 asinh(f64vec4);"
"float64_t acosh(float64_t);"
"f64vec2 acosh(f64vec2);"
"f64vec3 acosh(f64vec3);"
"f64vec4 acosh(f64vec4);"
"float64_t atanh(float64_t);"
"f64vec2 atanh(f64vec2);"
"f64vec3 atanh(f64vec3);"
"f64vec4 atanh(f64vec4);"
"float64_t pow(float64_t, float64_t);"
"f64vec2 pow(f64vec2, f64vec2);"
"f64vec3 pow(f64vec3, f64vec3);"
"f64vec4 pow(f64vec4, f64vec4);"
"float64_t exp(float64_t);"
"f64vec2 exp(f64vec2);"
"f64vec3 exp(f64vec3);"
"f64vec4 exp(f64vec4);"
"float64_t log(float64_t);"
"f64vec2 log(f64vec2);"
"f64vec3 log(f64vec3);"
"f64vec4 log(f64vec4);"
"float64_t exp2(float64_t);"
"f64vec2 exp2(f64vec2);"
"f64vec3 exp2(f64vec3);"
"f64vec4 exp2(f64vec4);"
"float64_t log2(float64_t);"
"f64vec2 log2(f64vec2);"
"f64vec3 log2(f64vec3);"
"f64vec4 log2(f64vec4);"
"\n");
}
@ -4369,7 +4270,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
//
//============================================================================
if (profile != EEsProfile && version >= 400) {
if (profile != EEsProfile && (version >= 400 || version == 150)) {
stageBuiltins[EShLangGeometry].append(
"void EmitStreamVertex(int);"
"void EndStreamPrimitive(int);"
@ -4653,7 +4554,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// GL_ARB_shader_clock & GL_EXT_shader_realtime_clock
// GL_ARB_shader_clock& GL_EXT_shader_realtime_clock
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"uvec2 clock2x32ARB();"
@ -5174,9 +5075,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
);
}
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangVertex].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangVertex].append(
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5312,9 +5217,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in int gl_InvocationID;"
);
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangGeometry].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangGeometry].append(
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5390,7 +5299,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
if (version >= 450)
stageBuiltins[EShLangTessControl].append(
"float gl_CullDistance[];"
);
if (version >= 430)
stageBuiltins[EShLangTessControl].append(
"int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangTessControl].append(
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5493,9 +5408,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"out int gl_Layer;"
"\n");
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangTessEvaluation].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangTessEvaluation].append(
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5652,6 +5571,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"flat in int gl_InvocationsPerPixelNV;"
"in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric
"in vec3 gl_BaryCoordNoPerspNV;"
"in vec3 gl_BaryCoordEXT;" // GL_EXT_fragment_shader_barycentric
"in vec3 gl_BaryCoordNoPerspEXT;"
);
if (version >= 450)
@ -5716,7 +5637,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangFragment].append(
"in vec3 gl_BaryCoordNV;"
"in vec3 gl_BaryCoordNoPerspNV;"
);
"in vec3 gl_BaryCoordEXT;"
"in vec3 gl_BaryCoordNoPerspEXT;"
);
if (version >= 310)
stageBuiltins[EShLangFragment].append(
"flat in highp int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate
@ -5938,6 +5861,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"in uint gl_CullMaskEXT;"
"\n";
const char *hitDecls =
"in uvec3 gl_LaunchIDNV;"
@ -5974,6 +5898,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"in uint gl_CullMaskEXT;"
"\n";
const char *missDecls =
"in uvec3 gl_LaunchIDNV;"
@ -5993,6 +5918,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"in uint gl_CullMaskEXT;"
"\n";
const char *callableDecls =
@ -6329,38 +6255,44 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
//
// textureQueryLod(), fragment stage only
// Also enabled with extension GL_ARB_texture_query_lod
// Extension GL_ARB_texture_query_lod says that textureQueryLOD() also exist at extension.
if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect &&
! sampler.isMultiSample() && ! sampler.isBuffer()) {
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
if (f16TexAddr && sampler.type != EbtFloat16)
continue;
stageBuiltins[EShLangFragment].append("vec2 textureQueryLod(");
stageBuiltins[EShLangFragment].append(typeName);
if (dimMap[sampler.dim] == 1)
if (f16TexAddr)
stageBuiltins[EShLangFragment].append(", float16_t");
else
stageBuiltins[EShLangFragment].append(", float");
else {
if (f16TexAddr)
stageBuiltins[EShLangFragment].append(", f16vec");
else
stageBuiltins[EShLangFragment].append(", vec");
stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
}
stageBuiltins[EShLangFragment].append(");\n");
}
stageBuiltins[EShLangCompute].append("vec2 textureQueryLod(");
stageBuiltins[EShLangCompute].append(typeName);
if (dimMap[sampler.dim] == 1)
stageBuiltins[EShLangCompute].append(", float");
else {
stageBuiltins[EShLangCompute].append(", vec");
stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
const TString funcName[2] = {"vec2 textureQueryLod(", "vec2 textureQueryLOD("};
for (int i = 0; i < 2; ++i){
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
if (f16TexAddr && sampler.type != EbtFloat16)
continue;
stageBuiltins[EShLangFragment].append(funcName[i]);
stageBuiltins[EShLangFragment].append(typeName);
if (dimMap[sampler.dim] == 1)
if (f16TexAddr)
stageBuiltins[EShLangFragment].append(", float16_t");
else
stageBuiltins[EShLangFragment].append(", float");
else {
if (f16TexAddr)
stageBuiltins[EShLangFragment].append(", f16vec");
else
stageBuiltins[EShLangFragment].append(", vec");
stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
}
stageBuiltins[EShLangFragment].append(");\n");
}
stageBuiltins[EShLangCompute].append(funcName[i]);
stageBuiltins[EShLangCompute].append(typeName);
if (dimMap[sampler.dim] == 1)
stageBuiltins[EShLangCompute].append(", float");
else {
stageBuiltins[EShLangCompute].append(", vec");
stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
}
stageBuiltins[EShLangCompute].append(");\n");
}
stageBuiltins[EShLangCompute].append(");\n");
}
//
@ -7701,6 +7633,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
symQualifier.builtIn = builtIn;
}
static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
{
symbolTable.retargetSymbol(from, to);
}
//
// For built-in variables inside a named block.
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
@ -7768,8 +7705,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
// treat these built-ins as aliases of VertexIndex and InstanceIndex
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
}
if (profile != EEsProfile) {
@ -8140,7 +8077,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
if (profile != EEsProfile && version < 400) {
symbolTable.setFunctionExtensions("textureQueryLod", 1, &E_GL_ARB_texture_query_lod);
symbolTable.setFunctionExtensions("textureQueryLOD", 1, &E_GL_ARB_texture_query_lod);
}
if (profile != EEsProfile && version >= 460) {
@ -8388,6 +8325,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_BaryCoordNoPerspNV", 1, &E_GL_NV_fragment_shader_barycentric);
BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable);
BuiltInVariable("gl_BaryCoordNoPerspNV", EbvBaryCoordNoPerspNV, symbolTable);
symbolTable.setVariableExtensions("gl_BaryCoordEXT", 1, &E_GL_EXT_fragment_shader_barycentric);
symbolTable.setVariableExtensions("gl_BaryCoordNoPerspEXT", 1, &E_GL_EXT_fragment_shader_barycentric);
BuiltInVariable("gl_BaryCoordEXT", EbvBaryCoordEXT, symbolTable);
BuiltInVariable("gl_BaryCoordNoPerspEXT", EbvBaryCoordNoPerspEXT, symbolTable);
}
if ((profile != EEsProfile && version >= 450) ||
@ -8403,7 +8344,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock);
symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
if (profile == EEsProfile && version < 320) {
@ -8423,10 +8364,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
if (profile != EEsProfile && version < 330 ) {
symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding);
symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding);
symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
const char* bitsConvertExt[2] = {E_GL_ARB_shader_bit_encoding, E_GL_ARB_gpu_shader5};
symbolTable.setFunctionExtensions("floatBitsToInt", 2, bitsConvertExt);
symbolTable.setFunctionExtensions("floatBitsToUint", 2, bitsConvertExt);
symbolTable.setFunctionExtensions("intBitsToFloat", 2, bitsConvertExt);
symbolTable.setFunctionExtensions("uintBitsToFloat", 2, bitsConvertExt);
}
if (profile != EEsProfile && version < 430 ) {
@ -8812,6 +8754,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_RayTminEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setVariableExtensions("gl_RayTmaxEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_CullMaskEXT", 1, &E_GL_EXT_ray_cull_mask);
symbolTable.setVariableExtensions("gl_HitTNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_ray_tracing);
@ -8861,6 +8804,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_RayTminEXT", EbvRayTmin, symbolTable);
BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable);
BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable);
BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable);
BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable);
BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable);
BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable);

View file

@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
// TODO: but, did this bypass constant folding?
//
switch (op) {
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructInt:
case EOpConstructUint:
case EOpConstructInt64:
case EOpConstructUint64:
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16:
return child;
default: break; // some compilers want this
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructInt:
case EOpConstructUint:
case EOpConstructInt64:
case EOpConstructUint64:
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16: {
TIntermUnary* unary_node = child->getAsUnaryNode();
if (unary_node != nullptr)
unary_node->updatePrecision();
return child;
}
default: break; // some compilers want this
}
//
@ -2762,7 +2766,7 @@ void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision)
return;
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
exp->getBasicType() == EbtFloat) {
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
exp->propagatePrecision(parentPrecision);
}
@ -3280,7 +3284,7 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
void TIntermUnary::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
getBasicType() == EbtFloat) {
if (operand->getQualifier().precision > getQualifier().precision)
getQualifier().precision = operand->getQualifier().precision;
}
@ -3776,12 +3780,34 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
return false;
}
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
void TIntermAggregate::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat) {
TPrecisionQualifier maxPrecision = EpqNone;
TIntermSequence operands = getSequence();
for (unsigned int i = 0; i < operands.size(); ++i) {
TIntermTyped* typedNode = operands[i]->getAsTyped();
assert(typedNode);
maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
}
getQualifier().precision = maxPrecision;
for (unsigned int i = 0; i < operands.size(); ++i) {
TIntermTyped* typedNode = operands[i]->getAsTyped();
assert(typedNode);
typedNode->propagatePrecision(maxPrecision);
}
}
}
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
void TIntermBinary::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
getBasicType() == EbtFloat) {
if (op == EOpRightShift || op == EOpLeftShift) {
// For shifts get precision from left side only and thus no need to propagate
getQualifier().precision = left->getQualifier().precision;
@ -3876,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
case EbtInt8: PROMOTE(setI8Const, signed char, Get); break; \
case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
case EbtInt: PROMOTE(setIConst, int, Get); break; \
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \

View file

@ -74,6 +74,9 @@ void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason
{
if (messages & EShMsgOnlyPreprocessor)
return;
// If enhanced msg readability, only print one error
if (messages & EShMsgEnhanced && numErrors > 0)
return;
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
@ -622,6 +625,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
// Check for declarations of this default uniform that already exist due to other compilation units.
TSymbol* symbol = symbolTable.find(memberName);
if (symbol) {
if (memberType != symbol->getType()) {
TString err;
err += "\"" + memberType.getCompleteString() + "\"";
err += " versus ";
err += "\"" + symbol->getType().getCompleteString() + "\"";
error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
}
return;
}
// Add the requested member as a member to the global block.
TType* type = new TType;
type->shallowCopy(memberType);

View file

@ -716,7 +716,7 @@ bool TParseContext::isIoResizeArray(const TType& type) const
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
! type.getQualifier().patch) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
type.getQualifier().pervertexNV) ||
(type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}
@ -856,7 +856,7 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS
error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
else if (language == EShLangFragment) {
if (type.getOuterArraySize() > requiredSize)
error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str());
error(loc, " cannot be greater than 3 for pervertexEXT", feature, name.c_str());
}
else if (language == EShLangMeshNV)
error(loc, "inconsistent output array size of", feature, name.c_str());
@ -902,8 +902,10 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char*
result = intermediate.addBinaryMath(op, left, right, loc);
}
if (result == nullptr)
binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
if (result == nullptr) {
bool enhanced = intermediate.getEnhancedMsgs();
binaryOpError(loc, str, left->getCompleteString(enhanced), right->getCompleteString(enhanced));
}
return result;
}
@ -926,8 +928,10 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
if (result)
return result;
else
unaryOpError(loc, str, childNode->getCompleteString());
else {
bool enhanced = intermediate.getEnhancedMsgs();
unaryOpError(loc, str, childNode->getCompleteString(enhanced));
}
return childNode;
}
@ -953,8 +957,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
requireProfile(loc, ~EEsProfile, feature);
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
} else if (!base->getType().isCoopMat()) {
error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
bool enhanced = intermediate.getEnhancedMsgs();
error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString(enhanced).c_str());
return base;
}
@ -1005,10 +1009,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
intermediate.addIoAccessed(field);
}
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
} else
error(loc, "no such field in structure", field.c_str(), "");
} else {
auto baseSymbol = base;
while (baseSymbol->getAsSymbolNode() == nullptr)
baseSymbol = baseSymbol->getAsBinaryNode()->getLeft();
TString structName;
structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append( "\'");
error(loc, "no such field in structure", field.c_str(), structName.c_str());
}
} else
error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
// Propagate noContraction up the dereference chain
if (base->getQualifier().isNoContraction())
@ -1314,14 +1324,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
//
result = addConstructor(loc, arguments, type);
if (result == nullptr)
error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
error(loc, "cannot construct with these arguments", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str(), "");
}
} else {
//
// Find it in the symbol table.
//
const TFunction* fnCandidate;
bool builtIn;
bool builtIn {false};
fnCandidate = findFunction(loc, *function, builtIn);
if (fnCandidate) {
// This is a declared function that might map to
@ -1494,7 +1504,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
else
error(arguments->getLoc(), " wrong operand type", "Internal Error",
"built in unary operator function. Type: %s",
static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
static_cast<TIntermTyped*>(arguments)->getCompleteString(intermediate.getEnhancedMsgs()).c_str());
} else if (result->getAsOperator())
builtInOpCheck(loc, function, *result->getAsOperator());
@ -2317,7 +2327,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
error(loc, "argument must be compile-time constant", "payload number", "a");
else {
unsigned int location = (*argp)[10]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
if (intermediate.checkLocationRT(0, location) < 0)
if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(0, location) < 0)
error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location);
}
break;
@ -2330,7 +2340,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
error(loc, "argument must be compile-time constant", "callable data number", "");
else {
unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
if (intermediate.checkLocationRT(1, location) < 0)
if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(1, location) < 0)
error(loc, "with layout(location =", "no callableDataEXT/callableDataInEXT declared", "%d)", location);
}
break;
@ -2495,6 +2505,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
case EOpEmitStreamVertex:
case EOpEndStreamPrimitive:
if (version == 150)
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
intermediate.setMultiStream();
break;
@ -2597,23 +2609,24 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
// Check that if extended types are being used that the correct extensions are enabled.
if (arg0 != nullptr) {
const TType& type = arg0->getType();
bool enhanced = intermediate.getEnhancedMsgs();
switch (type.getBasicType()) {
default:
break;
case EbtInt8:
case EbtUint8:
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str());
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString(enhanced).c_str());
break;
case EbtInt16:
case EbtUint16:
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str());
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString(enhanced).c_str());
break;
case EbtInt64:
case EbtUint64:
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str());
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString(enhanced).c_str());
break;
case EbtFloat16:
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str());
requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString(enhanced).c_str());
break;
}
}
@ -2786,7 +2799,10 @@ TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPu
TOperator op = intermediate.mapTypeToConstructorOp(type);
if (op == EOpNull) {
error(loc, "cannot construct this type", type.getBasicString(), "");
if (intermediate.getEnhancedMsgs() && type.getBasicType() == EbtSampler)
error(loc, "function not supported in this version; use texture() instead", "texture*D*", "");
else
error(loc, "cannot construct this type", type.getBasicString(), "");
op = EOpConstructFloat;
TType errorType(EbtFloat);
type.shallowCopy(errorType);
@ -3029,11 +3045,14 @@ void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
//
// Both test, and if necessary spit out an error, to see if the node is really
// an integer.
// a 32-bit integer or can implicitly convert to one.
//
void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
{
if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
auto from_type = node->getBasicType();
if ((from_type == EbtInt || from_type == EbtUint ||
intermediate.canImplicitlyPromote(from_type, EbtInt, EOpNull) ||
intermediate.canImplicitlyPromote(from_type, EbtUint, EOpNull)) && node->isScalar())
return;
error(node->getLoc(), "scalar integer expression required", token, "");
@ -3193,6 +3212,12 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
break;
}
TString constructorString;
if (intermediate.getEnhancedMsgs())
constructorString.append(type.getCompleteString(true, false, false, true)).append(" constructor");
else
constructorString.append("constructor");
// See if it's a matrix
bool constructingMatrix = false;
switch (op) {
@ -3250,7 +3275,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
if (function[arg].type->isArray()) {
if (function[arg].type->isUnsizedArray()) {
// Can't construct from an unsized array.
error(loc, "array argument must be sized", "constructor", "");
error(loc, "array argument must be sized", constructorString.c_str(), "");
return true;
}
arrayArg = true;
@ -3280,13 +3305,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
intArgument = true;
if (type.isStruct()) {
if (function[arg].type->contains16BitFloat()) {
requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
requireFloat16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type");
}
if (function[arg].type->contains16BitInt()) {
requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
requireInt16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type");
}
if (function[arg].type->contains8BitInt()) {
requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type");
requireInt8Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 8-bit type");
}
}
}
@ -3300,9 +3325,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructF16Vec3:
case EOpConstructF16Vec4:
if (type.isArray())
requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported");
requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types");
break;
case EOpConstructUint16:
case EOpConstructU16Vec2:
@ -3313,9 +3338,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructI16Vec3:
case EOpConstructI16Vec4:
if (type.isArray())
requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported");
requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types");
break;
case EOpConstructUint8:
case EOpConstructU8Vec2:
@ -3326,9 +3351,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructI8Vec3:
case EOpConstructI8Vec4:
if (type.isArray())
requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported");
requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types");
requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit vectors only take vector types");
break;
default:
break;
@ -3410,7 +3435,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
if (type.isArray()) {
if (function.getParamCount() == 0) {
error(loc, "array constructor must have at least one argument", "constructor", "");
error(loc, "array constructor must have at least one argument", constructorString.c_str(), "");
return true;
}
@ -3418,7 +3443,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// auto adapt the constructor type to the number of arguments
type.changeOuterArraySize(function.getParamCount());
} else if (type.getOuterArraySize() != function.getParamCount()) {
error(loc, "array constructor needs one argument per array element", "constructor", "");
error(loc, "array constructor needs one argument per array element", constructorString.c_str(), "");
return true;
}
@ -3431,7 +3456,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// At least the dimensionalities have to match.
if (! function[0].type->isArray() ||
arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
error(loc, "array constructor argument not correct type to construct array element", constructorString.c_str(), "");
return true;
}
@ -3448,7 +3473,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
}
if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
error(loc, "constructing non-array constituent from array argument", "constructor", "");
error(loc, "constructing non-array constituent from array argument", constructorString.c_str(), "");
return true;
}
@ -3458,51 +3483,51 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// "If a matrix argument is given to a matrix constructor,
// it is a compile-time error to have any other arguments."
if (function.getParamCount() != 1)
error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
error(loc, "matrix constructed from matrix can only have one argument", constructorString.c_str(), "");
return false;
}
if (overFull) {
error(loc, "too many arguments", "constructor", "");
error(loc, "too many arguments", constructorString.c_str(), "");
return true;
}
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
error(loc, "Number of constructor parameters does not match the number of structure fields", constructorString.c_str(), "");
return true;
}
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
(op == EOpConstructStruct && size < type.computeNumComponents())) {
error(loc, "not enough data provided for construction", "constructor", "");
error(loc, "not enough data provided for construction", constructorString.c_str(), "");
return true;
}
if (type.isCoopMat() && function.getParamCount() != 1) {
error(loc, "wrong number of arguments", "constructor", "");
error(loc, "wrong number of arguments", constructorString.c_str(), "");
return true;
}
if (type.isCoopMat() &&
!(function[0].type->isScalar() || function[0].type->isCoopMat())) {
error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", "");
error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", constructorString.c_str(), "");
return true;
}
TIntermTyped* typed = node->getAsTyped();
if (typed == nullptr) {
error(loc, "constructor argument does not have a type", "constructor", "");
error(loc, "constructor argument does not have a type", constructorString.c_str(), "");
return true;
}
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
error(loc, "cannot convert a sampler", "constructor", "");
error(loc, "cannot convert a sampler", constructorString.c_str(), "");
return true;
}
if (op != EOpConstructStruct && typed->isAtomic()) {
error(loc, "cannot convert an atomic_uint", "constructor", "");
error(loc, "cannot convert an atomic_uint", constructorString.c_str(), "");
return true;
}
if (typed->getBasicType() == EbtVoid) {
error(loc, "cannot convert a void", "constructor", "");
error(loc, "cannot convert a void", constructorString.c_str(), "");
return true;
}
@ -3781,7 +3806,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble)
profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) {
if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV() && !qualifier.isPervertexEXT()) {
if (isTypeInt(publicType.basicType) ||
publicType.basicType == EbtDouble ||
(publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt)
@ -4586,7 +4611,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (ssoPre150 ||
(identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) ||
(identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) ||
(identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 140) || esRedecls)) ||
identifier == "gl_ClipDistance" ||
identifier == "gl_CullDistance" ||
identifier == "gl_ShadingRateEXT" ||
@ -4655,7 +4680,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
symbolQualifier.storage != qualifier.storage)
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
} else if (identifier == "gl_FragCoord") {
if (intermediate.inIoAccessed("gl_FragCoord"))
if (!intermediate.getTexCoordRedeclared() && intermediate.inIoAccessed("gl_FragCoord"))
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
qualifier.isMemory() || qualifier.isAuxiliary())
@ -4665,6 +4690,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
intermediate.setTexCoordRedeclared();
if (publicType.pixelCenterInteger)
intermediate.setPixelCenterInteger();
if (publicType.originUpperLeft)
@ -5496,12 +5524,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
if (language == EShLangFragment) {
if (id == "origin_upper_left") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "origin_upper_left");
if (profile == ENoProfile) {
profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "origin_upper_left");
}
publicType.shaderQualifiers.originUpperLeft = true;
return;
}
if (id == "pixel_center_integer") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "pixel_center_integer");
if (profile == ENoProfile) {
profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "pixel_center_integer");
}
publicType.shaderQualifiers.pixelCenterInteger = true;
return;
}
@ -6034,6 +6069,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
dst.layoutShaderRecord = true;
if (src.pervertexNV)
dst.pervertexNV = true;
if (src.pervertexEXT)
dst.pervertexEXT = true;
#endif
}
}
@ -6207,11 +6244,13 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
#ifndef GLSLANG_WEB
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
int repeated = intermediate.addXfbBufferOffset(type);
if (repeated >= 0)
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
if (type.isUnsizedArray())
if (type.isUnsizedArray()) {
error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
} else {
int repeated = intermediate.addXfbBufferOffset(type);
if (repeated >= 0)
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
}
// "The offset must be a multiple of the size of the first component of the first
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
@ -6331,8 +6370,12 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
}
if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "push_constant", "");
if (qualifier.isPushConstant()) {
if (type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "push_constant", "");
if (type.isArray())
error(loc, "Push constants blocks can't be an array", "push_constant", "");
}
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "buffer_reference", "");
@ -6493,6 +6536,8 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
error(loc, "can only be used with a uniform", "push_constant", "");
if (qualifier.hasSet())
error(loc, "cannot be used with push_constant", "set", "");
if (qualifier.hasBinding())
error(loc, "cannot be used with push_constant", "binding", "");
}
if (qualifier.hasBufferReference()) {
if (qualifier.storage != EvqBuffer)
@ -6647,8 +6692,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
: findFunctionExact(loc, call, builtIn));
else if (version < 120)
function = findFunctionExact(loc, call, builtIn);
else if (version < 400)
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
else if (version < 400) {
bool needfindFunction400 = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) || extensionTurnedOn(E_GL_ARB_gpu_shader5);
function = needfindFunction400 ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
}
else if (explicitTypesEnabled)
function = findFunctionExplicitTypes(loc, call, builtIn);
else
@ -7419,14 +7466,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
// Uniforms require a compile-time constant initializer
if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
error(loc, "uniform initializers must be constant", "=", "'%s'",
variable->getType().getCompleteString().c_str());
variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
variable->getWritableType().getQualifier().makeTemporary();
return nullptr;
}
// Global consts require a constant initializer (specialization constant is okay)
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
error(loc, "global const initializers must be constant", "=", "'%s'",
variable->getType().getCompleteString().c_str());
variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
variable->getWritableType().getQualifier().makeTemporary();
return nullptr;
}
@ -7489,7 +7536,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
if (! initNode)
assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
assignError(loc, "=", intermSymbol->getCompleteString(intermediate.getEnhancedMsgs()), initializer->getCompleteString(intermediate.getEnhancedMsgs()));
return initNode;
}
@ -7560,7 +7607,7 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
}
} else if (type.isMatrix()) {
if (type.getMatrixCols() != (int)initList->getSequence().size()) {
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
TType vectorType(type, 0); // dereferenced type
@ -7571,20 +7618,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
}
} else if (type.isVector()) {
if (type.getVectorSize() != (int)initList->getSequence().size()) {
error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
TBasicType destType = type.getBasicType();
for (int i = 0; i < type.getVectorSize(); ++i) {
TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType();
if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) {
error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str());
error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
}
} else {
error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
@ -7691,7 +7738,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
return nullptr;
}
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
TIntermAggregate *agg_node = ret_node->getAsAggregate();
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
agg_node->updatePrecision();
return ret_node;
}
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
@ -8086,8 +8139,9 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType&
{
TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
if (! converted || converted->getType() != type) {
bool enhanced = intermediate.getEnhancedMsgs();
error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
node->getAsTyped()->getType().getCompleteString(enhanced).c_str(), type.getCompleteString(enhanced).c_str());
return nullptr;
}
@ -9237,11 +9291,14 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
// "it is an error to have no statement between a label and the end of the switch statement."
// The specifications were updated to remove this (being ill-defined what a "statement" was),
// so, this became a warning. However, 3.0 tests still check for the error.
if (isEsProfile() && version <= 300 && ! relaxedErrors())
if (isEsProfile() && (version <= 300 || version >= 320) && ! relaxedErrors())
error(loc, "last case/default label not followed by statements", "switch", "");
else if (!isEsProfile() && (version <= 430 || version >= 460))
error(loc, "last case/default label not followed by statements", "switch", "");
else
warn(loc, "last case/default label not followed by statements", "switch", "");
// emulate a break for error recovery
lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
lastStatements->setOperator(EOpSequence);

View file

@ -241,7 +241,7 @@ protected:
// override this to set the language-specific name
virtual const char* getAtomicCounterBlockName() const { return ""; }
virtual void setAtomicCounterBlockDefaults(TType&) const {}
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
virtual void setInvariant(const TSourceLoc&, const char*) {}
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
bool isAtomicCounterBlock(const TSymbol& symbol) {
const TVariable* var = symbol.getAsVariable();
@ -472,7 +472,7 @@ public:
// Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
// GL_EXT_spirv_intrinsics
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
@ -480,7 +480,6 @@ public:
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
TSpirvTypeParameters* spirvTypeParams2);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);

View file

@ -739,6 +739,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS;
(*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD;
(*KeywordMap)["pervertexNV"] = PERVERTEXNV;
(*KeywordMap)["pervertexEXT"] = PERVERTEXEXT;
(*KeywordMap)["precise"] = PRECISE;
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
@ -1719,6 +1720,12 @@ int TScanContext::tokenizeIdentifier()
return keyword;
return identifierOrType();
case PERVERTEXEXT:
if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
parseContext.extensionTurnedOn(E_GL_EXT_fragment_shader_barycentric))
return keyword;
return identifierOrType();
case PRECISE:
if ((parseContext.isEsProfile() &&
(parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||

View file

@ -813,6 +813,7 @@ bool ProcessDeferred(
// set version/profile to defaultVersion/defaultProfile regardless of the #version
// directive in the source code
bool forceDefaultVersionAndProfile,
int overrideVersion, // overrides version specified by #verison or default version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate, // returned tree, etc.
@ -900,6 +901,9 @@ bool ProcessDeferred(
version = defaultVersion;
profile = defaultProfile;
}
if (source == EShSourceGlsl && overrideVersion != 0) {
version = overrideVersion;
}
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
@ -1275,6 +1279,7 @@ bool PreprocessDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile,
bool forceDefaultVersionAndProfile,
int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TShader::Includer& includer,
@ -1285,7 +1290,7 @@ bool PreprocessDeferred(
DoPreprocessing parser(outputString);
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile,
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser,
false, includer, "", environment);
}
@ -1314,6 +1319,7 @@ bool CompileDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile,
bool forceDefaultVersionAndProfile,
int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate,// returned tree, etc.
@ -1324,7 +1330,7 @@ bool CompileDeferred(
DoFullParse parser;
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile,
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser,
true, includer, sourceEntryPointName, environment);
}
@ -1343,7 +1349,6 @@ int ShInitialize()
glslang::GetGlobalLock();
++NumberOfClients;
glslang::ReleaseGlobalLock();
if (PerProcessGPA == nullptr)
PerProcessGPA = new TPoolAllocator();
@ -1353,6 +1358,7 @@ int ShInitialize()
glslang::HlslScanContext::fillInKeywordMap();
#endif
glslang::ReleaseGlobalLock();
return 1;
}
@ -1415,9 +1421,10 @@ int ShFinalize()
--NumberOfClients;
assert(NumberOfClients >= 0);
bool finalize = NumberOfClients == 0;
glslang::ReleaseGlobalLock();
if (! finalize)
if (! finalize) {
glslang::ReleaseGlobalLock();
return 1;
}
for (int version = 0; version < VersionCount; ++version) {
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
@ -1455,6 +1462,7 @@ int ShFinalize()
glslang::HlslScanContext::deleteKeywordMap();
#endif
glslang::ReleaseGlobalLock();
return 1;
}
@ -1496,7 +1504,7 @@ int ShCompile(
TIntermediate intermediate(compiler->getLanguage());
TShader::ForbidIncluder includer;
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
"", optLevel, resources, defaultVersion, ENoProfile, false,
"", optLevel, resources, defaultVersion, ENoProfile, false, 0,
forwardCompatible, messages, intermediate, includer);
//
@ -1757,7 +1765,7 @@ public:
};
TShader::TShader(EShLanguage s)
: stage(s), lengths(nullptr), stringNames(nullptr), preamble("")
: stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0)
{
pool = new TPoolAllocator;
infoSink = new TInfoSink;
@ -1826,7 +1834,14 @@ void TShader::setUniqueId(unsigned long long id)
intermediate->setUniqueId(id);
}
void TShader::setOverrideVersion(int version)
{
overrideVersion = version;
}
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); }
void TShader::setEnhancedMsgs() { intermediate->setEnhancedMsgs(); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
#ifndef GLSLANG_WEB
@ -1906,7 +1921,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
preamble, EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile,
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
&environment);
}
@ -1933,7 +1948,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile,
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, message, includer, *intermediate, output_string,
&environment);
}
@ -2046,6 +2061,8 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
firstIntermediate->getVersion(),
firstIntermediate->getProfile());
intermediate[stage]->setLimits(firstIntermediate->getLimits());
if (firstIntermediate->getEnhancedMsgs())
intermediate[stage]->setEnhancedMsgs();
// The new TIntermediate must use the same origin as the original TIntermediates.
// Otherwise linking will fail due to different coordinate systems.

View file

@ -130,11 +130,11 @@ void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermA
spirvExecutionMode = new TSpirvExecutionMode;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
TVector<const TIntermTyped*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
auto extraOperand = arg->getAsTyped();
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
extraOperands.push_back(extraOperand);
}
spirvExecutionMode->modeIds[executionMode] = extraOperands;
@ -165,10 +165,10 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args
spirvDecorate = new TSpirvDecorate;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
TVector<const TIntermTyped*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
auto extraOperand = arg->getAsTyped();
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
extraOperands.push_back(extraOperand);
}
spirvDecorate->decorateIds[decoration] = extraOperands;
@ -201,25 +201,27 @@ TString TQualifier::getSpirvDecorateQualifierString() const
const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
const auto appendDecorate = [&](const TIntermConstantUnion* constant) {
const auto appendDecorate = [&](const TIntermTyped* constant) {
auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray()
: constant->getAsSymbolNode()->getConstArray();
if (constant->getBasicType() == EbtFloat) {
float value = static_cast<float>(constant->getConstArray()[0].getDConst());
float value = static_cast<float>(constArray[0].getDConst());
appendFloat(value);
}
else if (constant->getBasicType() == EbtInt) {
int value = constant->getConstArray()[0].getIConst();
int value = constArray[0].getIConst();
appendInt(value);
}
else if (constant->getBasicType() == EbtUint) {
unsigned value = constant->getConstArray()[0].getUConst();
unsigned value = constArray[0].getUConst();
appendUint(value);
}
else if (constant->getBasicType() == EbtBool) {
bool value = constant->getConstArray()[0].getBConst();
bool value = constArray[0].getBConst();
appendBool(value);
}
else if (constant->getBasicType() == EbtString) {
const TString* value = constant->getConstArray()[0].getSConst();
const TString* value = constArray[0].getSConst();
appendStr(value->c_str());
}
else
@ -290,13 +292,6 @@ TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& l
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type)
{
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type)));
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
{
// Merge SPIR-V type parameters of the second one to the first one

View file

@ -279,8 +279,14 @@ TFunction::~TFunction()
//
TSymbolTableLevel::~TSymbolTableLevel()
{
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
delete (*it).second;
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
const TString& name = it->first;
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
if (retargetIter == retargetedSymbols.end())
delete (*it).second;
}
delete [] defaultPrecision;
}
@ -418,6 +424,10 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
symTableLevel->anonId = anonId;
symTableLevel->thisLevel = thisLevel;
symTableLevel->retargetedSymbols.clear();
for (auto &s : retargetedSymbols) {
symTableLevel->retargetedSymbols.push_back({s.first, s.second});
}
std::vector<bool> containerCopied(anonId, false);
tLevel::const_iterator iter;
for (iter = level.begin(); iter != level.end(); ++iter) {
@ -433,8 +443,21 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
symTableLevel->insert(*container, false);
containerCopied[anon->getAnonId()] = true;
}
} else
} else {
const TString& name = iter->first;
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
if (retargetIter != retargetedSymbols.end())
continue;
symTableLevel->insert(*iter->second->clone(), false);
}
}
// Now point retargeted symbols to the newly created versions of them
for (auto &s : retargetedSymbols) {
TSymbol* sym = symTableLevel->find(s.second);
if (!sym)
continue;
symTableLevel->insert(s.first, sym);
}
return symTableLevel;

View file

@ -84,7 +84,7 @@ typedef TVector<const char*> TExtensionList;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(0), writable(true) { }
virtual TSymbol* clone() const = 0;
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
@ -413,13 +413,20 @@ public:
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
~TSymbolTableLevel();
bool insert(TSymbol& symbol, bool separateNameSpaces)
bool insert(const TString& name, TSymbol* symbol) {
return level.insert(tLevelPair(name, symbol)).second;
}
bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
{
//
// returning true means symbol was added to the table with no semantic errors
//
const TString& name = symbol.getName();
if (name == "") {
if (forcedKeyName.length()) {
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
}
else if (name == "") {
symbol.getAsVariable()->setAnonId(anonId++);
// An empty name means an anonymous container, exposing its members to the external scope.
// Give it a name and insert its members in the symbol table, pointing to the container.
@ -471,6 +478,16 @@ public:
return true;
}
void retargetSymbol(const TString& from, const TString& to) {
tLevel::const_iterator fromIt = level.find(from);
tLevel::const_iterator toIt = level.find(to);
if (fromIt == level.end() || toIt == level.end())
return;
delete fromIt->second;
level[from] = toIt->second;
retargetedSymbols.push_back({from, to});
}
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
@ -583,6 +600,8 @@ protected:
tLevel level; // named mappings
TPrecisionQualifier *defaultPrecision;
// pair<FromName, ToName>
TVector<std::pair<TString, TString>> retargetedSymbols;
int anonId;
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
// that are supposed to see anonymous access to member variables.
@ -788,6 +807,12 @@ public:
return symbol;
}
void retargetSymbol(const TString& from, const TString& to) {
int level = currentLevel();
table[level]->retargetSymbol(from, to);
}
// Find of a symbol that returns how many layers deep of nested
// structures-with-member-functions ('this' scopes) deep the symbol was
// found in.

View file

@ -225,6 +225,9 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
@ -256,6 +259,8 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
extensionBehavior[E_GL_EXT_fragment_shader_barycentric] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
@ -331,6 +336,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable;
extensionBehavior[E_GL_EXT_ray_query] = EBhDisable;
extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable;
extensionBehavior[E_GL_EXT_ray_cull_mask] = EBhDisable;
extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable;
extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable;
@ -465,6 +471,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_shader_storage_buffer_object 1\n"
"#define GL_ARB_texture_query_lod 1\n"
"#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_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"
@ -482,6 +490,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_debug_printf 1\n"
"#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 1\n"
"#define GL_EXT_shader_integer_mix 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
@ -499,6 +508,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_ray_tracing 1\n"
"#define GL_EXT_ray_query 1\n"
"#define GL_EXT_ray_flags_primitive_culling 1\n"
"#define GL_EXT_ray_cull_mask 1\n"
"#define GL_EXT_spirv_intrinsics 1\n"
"#define GL_AMD_shader_ballot 1\n"
@ -546,6 +556,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_atomic_float 1\n"
"#define GL_EXT_shader_atomic_float2 1\n"
"#define GL_EXT_fragment_shader_barycentric 1\n"
;
if (version >= 150) {

View file

@ -161,6 +161,8 @@ const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
@ -199,6 +201,7 @@ const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_prin
const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing";
const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query";
const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling";
const char* const E_GL_EXT_ray_cull_mask = "GL_EXT_ray_cull_mask";
const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended";
const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
@ -207,6 +210,7 @@ const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initi
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
// Arrays of extensions for the above viewportEXTs duplications

View file

@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
//
// Function attributes
//
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
{
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
if (it->size() > 0) {

View file

@ -315,7 +315,7 @@ GLSLANG_WEB_EXCLUDE_ON
%token <lex> PATCH SAMPLE NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> PRECISE
GLSLANG_WEB_EXCLUDE_OFF
@ -798,7 +798,7 @@ conditional_expression
parseContext.rValueErrorCheck($5.loc, ":", $6);
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
if ($$ == 0) {
parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString());
parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $6;
}
}
@ -815,7 +815,7 @@ assignment_expression
parseContext.rValueErrorCheck($2.loc, "assign", $3);
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
if ($$ == 0) {
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $1;
}
}
@ -877,7 +877,7 @@ expression
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
if ($$ == 0) {
parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());
parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $3;
}
}
@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@ -1290,6 +1290,14 @@ GLSLANG_WEB_EXCLUDE_ON
$$.init($1.loc);
$$.qualifier.pervertexNV = true;
}
| PERVERTEXEXT {
parseContext.globalCheck($1.loc, "pervertexEXT");
parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
$$.init($1.loc);
$$.qualifier.pervertexEXT = true;
}
| PERPRIMITIVENV {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "perprimitiveNV");
@ -3926,6 +3934,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@ -3937,6 +3946,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
@ -4365,9 +4375,6 @@ spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
}
| type_specifier {
$$ = parseContext.makeSpirvTypeParameters($1);
}
spirv_instruction_qualifier
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {

View file

@ -315,7 +315,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> PATCH SAMPLE NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> PRECISE
@ -798,7 +798,7 @@ conditional_expression
parseContext.rValueErrorCheck($5.loc, ":", $6);
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
if ($$ == 0) {
parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString());
parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $6;
}
}
@ -815,7 +815,7 @@ assignment_expression
parseContext.rValueErrorCheck($2.loc, "assign", $3);
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
if ($$ == 0) {
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $1;
}
}
@ -877,7 +877,7 @@ expression
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
if ($$ == 0) {
parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());
parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $3;
}
}
@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@ -1290,6 +1290,14 @@ interpolation_qualifier
$$.init($1.loc);
$$.qualifier.pervertexNV = true;
}
| PERVERTEXEXT {
parseContext.globalCheck($1.loc, "pervertexEXT");
parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric");
$$.init($1.loc);
$$.qualifier.pervertexEXT = true;
}
| PERPRIMITIVENV {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "perprimitiveNV");
@ -3926,6 +3934,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@ -3937,6 +3946,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
@ -4365,9 +4375,6 @@ spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
}
| type_specifier {
$$ = parseContext.makeSpirvTypeParameters($1);
}
spirv_instruction_qualifier
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {

File diff suppressed because it is too large Load diff

View file

@ -501,11 +501,12 @@ extern int yydebug;
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
PERVERTEXNV = 705, /* PERVERTEXNV */
PERPRIMITIVENV = 706, /* PERPRIMITIVENV */
PERVIEWNV = 707, /* PERVIEWNV */
PERTASKNV = 708, /* PERTASKNV */
PRECISE = 709 /* PRECISE */
PERVERTEXEXT = 705, /* PERVERTEXEXT */
PERVERTEXNV = 706, /* PERVERTEXNV */
PERPRIMITIVENV = 707, /* PERPRIMITIVENV */
PERVIEWNV = 708, /* PERVIEWNV */
PERTASKNV = 709, /* PERTASKNV */
PRECISE = 710 /* PRECISE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
@ -553,7 +554,7 @@ union YYSTYPE
glslang::TArraySizes* typeParameters;
} interm;
#line 557 "MachineIndependent/glslang_tab.cpp.h"
#line 558 "MachineIndependent/glslang_tab.cpp.h"
};
typedef union YYSTYPE YYSTYPE;

View file

@ -48,37 +48,6 @@
#endif
#include <cstdint>
namespace {
bool IsInfinity(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return true;
default:
return false;
}
#else
return std::isinf(x);
#endif
}
bool IsNan(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return true;
default:
return false;
}
#else
return std::isnan(x);
#endif
}
}
namespace glslang {

View file

@ -79,7 +79,7 @@ public:
target = &inputList;
else if (base->getQualifier().storage == EvqVaryingOut)
target = &outputList;
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant() && !base->getQualifier().isShaderRecord())
target = &uniformList;
// If a global is being visited, then we should also traverse it incase it's evaluation
// ends up visiting inputs we want to tag as live
@ -203,11 +203,7 @@ struct TResolverUniformAdaptor {
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
TVarEntryInfo& ent = entKey.second;
ent.newLocation = -1;
ent.newComponent = -1;
ent.newBinding = -1;
ent.newSet = -1;
ent.newIndex = -1;
ent.clearNewAssignments();
const bool isValid = resolver.validateBinding(stage, ent);
if (isValid) {
resolver.resolveSet(ent.stage, ent);
@ -281,11 +277,7 @@ struct TResolverInOutAdaptor {
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
{
TVarEntryInfo& ent = entKey.second;
ent.newLocation = -1;
ent.newComponent = -1;
ent.newBinding = -1;
ent.newSet = -1;
ent.newIndex = -1;
ent.clearNewAssignments();
const bool isValid = resolver.validateInOut(ent.stage, ent);
if (isValid) {
resolver.resolveInOutLocation(stage, ent);
@ -514,6 +506,24 @@ struct TSymbolValidater
return;
}
else {
// Deal with input/output pairs where one is a block member but the other is loose,
// e.g. with ARB_separate_shader_objects
if (type1.getBasicType() == EbtBlock &&
type1.isStruct() && !type2.isStruct()) {
// Iterate through block members tracking layout
glslang::TString name;
type1.getStruct()->begin()->type->appendMangledName(name);
if (name == mangleName2
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
}
if (type2.getBasicType() == EbtBlock &&
type2.isStruct() && !type1.isStruct()) {
// Iterate through block members tracking layout
glslang::TString name;
type2.getStruct()->begin()->type->appendMangledName(name);
if (name == mangleName1
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
}
TString err = "Invalid In/Out variable type : " + entKey.first;
infoSink.info.message(EPrefixInternalError, err.c_str());
hadError = true;
@ -748,7 +758,7 @@ private:
};
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
: intermediate(intermediate)
: referenceIntermediate(intermediate)
, nextUniformLocation(intermediate.getUniformLocationBase())
, nextInputLocation(0)
, nextOutputLocation(0)
@ -760,17 +770,17 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
: selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
: selectBaseBinding(referenceIntermediate.getShiftBinding(res), referenceIntermediate.getShiftBindingForSet(res, set));
}
const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
: intermediate.getResourceSetBinding();
: referenceIntermediate.getResourceSetBinding();
}
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return referenceIntermediate.getAutoMapBindings(); }
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return referenceIntermediate.getAutoMapLocations(); }
TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
@ -827,7 +837,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
type.isAtomic() || type.isSpirvType() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -839,7 +849,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
return ent.newLocation = -1;
}
}
int location = intermediate.getUniformLocationOverride(name);
int location = referenceIntermediate.getUniformLocationOverride(name);
if (location != -1) {
return ent.newLocation = location;
}
@ -855,8 +865,8 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
return ent.newLocation = -1;
}
// no locations added if already present, or a built-in variable
if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
@ -942,8 +952,8 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
if (type.getQualifier().hasLocation()) {
return ent.newLocation = type.getQualifier().layoutLocation;
}
// no locations added if already present, or a built-in variable
if (type.isBuiltIn()) {
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -1024,7 +1034,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
} else {
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
type.isAtomic() || type.isSpirvType() ||
(type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -1037,7 +1048,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
}
}
int location = intermediate.getUniformLocationOverride(name.c_str());
int location = referenceIntermediate.getUniformLocationOverride(name.c_str());
if (location != -1) {
return ent.newLocation = location;
}
@ -1086,7 +1097,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
const TType& type = ent.symbol->getType();
const TString& name = ent.symbol->getAccessName();
// On OpenGL arrays of opaque types take a separate binding for each element
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
TResourceType resource = getResourceType(type);
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
if (resource == EResUbo && type.getBasicType() != EbtBlock) {
@ -1095,7 +1106,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
// There is no 'set' qualifier in OpenGL shading language, each resource has its own
// binding name space, so remap the 'set' to resource type which make each resource
// binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet;
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : ent.newSet;
int resourceKey = set;
if (resource < EResCount) {
if (type.getQualifier().hasBinding()) {
@ -1223,7 +1234,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
const TType& type = ent.symbol->getType();
const TString& name = ent.symbol->getAccessName();
TResourceType resource = getResourceType(type);
int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
int resourceKey = set;
if (type.getQualifier().hasBinding()) {
@ -1233,7 +1244,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
if (iter == varSlotMap.end()) {
// Reserve the slots for the ubo, ssbo and opaques who has explicit binding
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
varSlotMap[name] = binding;
reserveSlot(resourceKey, binding, numBindings);
} else {
@ -1288,7 +1299,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
const TType& type = ent.symbol->getType();
const int set = getLayoutSet(type);
// On OpenGL arrays of opaque types take a seperate binding for each element
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
TResourceType resource = getResourceType(type);
if (resource < EResCount) {
if (type.getQualifier().hasBinding()) {
@ -1633,6 +1644,45 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
});
resolver->endResolve(EShLangCount);
if (autoPushConstantBlockName.length()) {
bool upgraded = false;
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (intermediates[stage] != nullptr) {
TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
if (at == pUniformVarMap[stage]->end())
continue;
TQualifier& qualifier = at->second.symbol->getQualifier();
if (!qualifier.isUniform())
continue;
TType& t = at->second.symbol->getWritableType();
int size, stride;
TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
qualifier.layoutMatrix == ElmRowMajor);
if (size <= int(autoPushConstantMaxSize)) {
qualifier.setBlockStorage(EbsPushConstant);
qualifier.layoutPacking = autoPushConstantBlockPacking;
// Push constants don't have set/binding etc. decorations, remove those.
qualifier.layoutSet = TQualifier::layoutSetEnd;
at->second.clearNewAssignments();
upgraded = true;
}
}
}
// If it's been upgraded to push_constant, then remove it from the uniformVector
// so it doesn't get a set/binding assigned to it.
if (upgraded) {
while (1) {
auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
[this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
if (at != uniformVector.end())
uniformVector.erase(at);
else
break;
}
}
}
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (intermediates[stage] != nullptr) {
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to

View file

@ -61,6 +61,15 @@ struct TVarEntryInfo {
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
@ -165,7 +174,7 @@ public:
protected:
TDefaultIoResolverBase(TDefaultIoResolverBase&);
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
const TIntermediate& intermediate;
const TIntermediate& referenceIntermediate;
int nextUniformLocation;
int nextInputLocation;
int nextOutputLocation;
@ -291,7 +300,7 @@ public:
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
};
// I/O mapper for OpenGL
// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
@ -301,6 +310,8 @@ public:
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
@ -320,6 +331,13 @@ public:
intermediates[stage] = nullptr;
}
}
// If set, the uniform block with the given name will be changed to be backed by
// push_constant if it's size is <= maxSize
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
autoPushConstantBlockName = name;
autoPushConstantMaxSize = maxSize;
autoPushConstantBlockPacking = packing;
}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
@ -329,6 +347,11 @@ public:
bool hadError = false;
EProfile profile;
int version;
private:
TString autoPushConstantBlockName;
unsigned int autoPushConstantMaxSize;
TLayoutPacking autoPushConstantBlockPacking;
};
} // end namespace glslang

View file

@ -55,22 +55,28 @@ namespace glslang {
//
// Link-time error emitter.
//
void TIntermediate::error(TInfoSink& infoSink, const char* message)
void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixError);
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
#endif
++numErrors;
}
// Link-time warning.
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixWarning);
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
#endif
}
@ -312,6 +318,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(autoMapBindings);
MERGE_TRUE(autoMapLocations);
MERGE_TRUE(invertY);
MERGE_TRUE(dxPositionW);
MERGE_TRUE(flattenUniformArrays);
MERGE_TRUE(useUnknownFormat);
MERGE_TRUE(hlslOffsets);
@ -579,9 +586,6 @@ void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate&
}
void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
if (block->getType() == unitBlock->getType()) {
return;
}
if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
block->getType().getBasicType() != unitBlock->getType().getBasicType() ||
@ -628,44 +632,42 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
}
}
TType unitType;
unitType.shallowCopy(unitBlock->getType());
// update symbol node in unit tree,
// and other nodes that may reference it
class TMergeBlockTraverser : public TIntermTraverser {
public:
TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType,
glslang::TIntermediate& unit,
const std::map<unsigned int, unsigned int>& memberIdxUpdates) :
newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
{ }
virtual ~TMergeBlockTraverser() { }
TMergeBlockTraverser(const TIntermSymbol* newSym)
: newSymbol(newSym), unitType(nullptr), unit(nullptr), memberIndexUpdates(nullptr)
{
}
TMergeBlockTraverser(const TIntermSymbol* newSym, const glslang::TType* unitType, glslang::TIntermediate* unit,
const std::map<unsigned int, unsigned int>* memberIdxUpdates)
: TIntermTraverser(false, true), newSymbol(newSym), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
{
}
virtual ~TMergeBlockTraverser() {}
const glslang::TType& newType; // type with modifications
const glslang::TType& unitType; // copy of original type
glslang::TIntermediate& unit; // intermediate that is being updated
const std::map<unsigned int, unsigned int>& memberIndexUpdates;
const TIntermSymbol* newSymbol;
const glslang::TType* unitType; // copy of original type
glslang::TIntermediate* unit; // intermediate that is being updated
const std::map<unsigned int, unsigned int>* memberIndexUpdates;
virtual void visitSymbol(TIntermSymbol* symbol)
{
glslang::TType& symType = symbol->getWritableType();
if (symType == unitType) {
// each symbol node has a local copy of the unitType
// if merging involves changing properties that aren't shared objects
// they should be updated in all instances
// e.g. the struct list is a ptr to an object, so it can be updated
// once, outside the traverser
//*symType.getWritableStruct() = *newType.getStruct();
if (newSymbol->getAccessName() == symbol->getAccessName() &&
newSymbol->getQualifier().getBlockStorage() == symbol->getQualifier().getBlockStorage()) {
// Each symbol node may have a local copy of the block structure.
// Update those structures to match the new one post-merge
*(symbol->getWritableType().getWritableStruct()) = *(newSymbol->getType().getStruct());
}
}
virtual bool visitBinary(TVisit, glslang::TIntermBinary* node)
{
if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) {
if (!unit || !unitType || !memberIndexUpdates || memberIndexUpdates->empty())
return true;
if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == *unitType) {
// this is a dereference to a member of the block since the
// member list changed, need to update this to point to the
// right index
@ -673,8 +675,8 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
unsigned int newIdx = memberIndexUpdates.at(memberIdx);
TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc());
unsigned int newIdx = memberIndexUpdates->at(memberIdx);
TIntermTyped* newConstNode = unit->addConstantUnion(newIdx, node->getRight()->getLoc());
node->setRight(newConstNode);
delete constNode;
@ -683,10 +685,20 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
}
return true;
}
} finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates);
};
// update the tree to use the new type
unit->getTreeRoot()->traverse(&finalLinkTraverser);
// 'this' may have symbols that are using the old block structure, so traverse the tree to update those
// in 'visitSymbol'
TMergeBlockTraverser finalLinkTraverser(block);
getTreeRoot()->traverse(&finalLinkTraverser);
// The 'unit' intermediate needs the block structures update, but also structure entry indices
// may have changed from the old block to the new one that it was merged into, so update those
// in 'visitBinary'
TType unitType;
unitType.shallowCopy(unitBlock->getType());
TMergeBlockTraverser unitFinalLinkTraverser(block, &unitType, unit, &memberIndexUpdates);
unit->getTreeRoot()->traverse(&unitFinalLinkTraverser);
// update the member list
(*unitMemberList) = (*memberList);
@ -759,7 +771,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()
&& !((*unitSymbol->getType().getStruct())[i].type->getQualifier().hasLocation()
|| unitSymbol->getType().getQualifier().hasLocation())
) {
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
}
@ -815,6 +830,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
bool crossStage = getStage() != unitStage;
bool writeTypeComparison = false;
bool errorReported = false;
bool printQualifiers = false;
bool printPrecision = false;
bool printType = false;
// Types have to match
{
@ -846,11 +865,48 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
}
if (!symbol.getType().sameElementType(unitSymbol.getType()) ||
!symbol.getType().sameTypeParameters(unitSymbol.getType()) ||
!arraysMatch ) {
int lpidx = -1;
int rpidx = -1;
if (!symbol.getType().sameElementType(unitSymbol.getType(), &lpidx, &rpidx)) {
if (lpidx >= 0 && rpidx >= 0) {
error(infoSink, "Member names and types must match:", unitStage);
infoSink.info << " Block: " << symbol.getType().getTypeName() << "\n";
infoSink.info << " " << StageName(getStage()) << " stage: \""
<< (*symbol.getType().getStruct())[lpidx].type->getCompleteString(true, false, false, true,
(*symbol.getType().getStruct())[lpidx].type->getFieldName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \""
<< (*unitSymbol.getType().getStruct())[rpidx].type->getCompleteString(true, false, false, true,
(*unitSymbol.getType().getStruct())[rpidx].type->getFieldName()) << "\"\n";
errorReported = true;
} else if (lpidx >= 0 && rpidx == -1) {
TString errmsg = StageName(getStage());
errmsg.append(" block member has no corresponding member in ").append(StageName(unitStage)).append(" block:");
error(infoSink, errmsg.c_str(), unitStage);
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
<< (*symbol.getType().getStruct())[lpidx].type->getFieldName() << "\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: n/a \n";
errorReported = true;
} else if (lpidx == -1 && rpidx >= 0) {
TString errmsg = StageName(unitStage);
errmsg.append(" block member has no corresponding member in ").append(StageName(getStage())).append(" block:");
error(infoSink, errmsg.c_str(), unitStage);
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
<< (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName() << "\n";
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n";
errorReported = true;
} else {
error(infoSink, "Types must match:", unitStage);
writeTypeComparison = true;
printType = true;
}
} else if (!arraysMatch) {
error(infoSink, "Array sizes must be compatible:", unitStage);
writeTypeComparison = true;
error(infoSink, "Types must match:");
printType = true;
} else if (!symbol.getType().sameTypeParameters(unitSymbol.getType())) {
error(infoSink, "Type parameters must match:", unitStage);
writeTypeComparison = true;
printType = true;
}
}
@ -858,17 +914,51 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
symbol.getType().sameStructType(unitSymbol.getType())) {
for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
qualifier.layoutOffset != unitQualifier.layoutOffset ||
qualifier.layoutAlign != unitQualifier.layoutAlign ||
qualifier.layoutLocation != unitQualifier.layoutLocation ||
qualifier.layoutComponent != unitQualifier.layoutComponent) {
error(infoSink, "Interface block member layout qualifiers must match:");
writeTypeComparison = true;
unsigned int li = 0;
unsigned int ri = 0;
while (li < symbol.getType().getStruct()->size() && ri < unitSymbol.getType().getStruct()->size()) {
if ((*symbol.getType().getStruct())[li].type->hiddenMember()) {
++li;
continue;
}
if ((*unitSymbol.getType().getStruct())[ri].type->hiddenMember()) {
++ri;
continue;
}
const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier();
const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier();
bool layoutQualifierError = false;
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix) {
error(infoSink, "Interface block member layout matrix qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (qualifier.layoutOffset != unitQualifier.layoutOffset) {
error(infoSink, "Interface block member layout offset qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (qualifier.layoutAlign != unitQualifier.layoutAlign) {
error(infoSink, "Interface block member layout align qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (qualifier.layoutLocation != unitQualifier.layoutLocation) {
error(infoSink, "Interface block member layout location qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (qualifier.layoutComponent != unitQualifier.layoutComponent) {
error(infoSink, "Interface block member layout component qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (layoutQualifierError) {
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
<< (*symbol.getType().getStruct())[li].type->getFieldName() << " \""
<< (*symbol.getType().getStruct())[li].type->getCompleteString(true, true, false, false) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
<< (*unitSymbol.getType().getStruct())[ri].type->getFieldName() << " \""
<< (*unitSymbol.getType().getStruct())[ri].type->getCompleteString(true, true, false, false) << "\"\n";
errorReported = true;
}
++li;
++ri;
}
}
@ -879,8 +969,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// Qualifiers have to (almost) match
// Storage...
if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
error(infoSink, "Storage qualifiers must match:");
error(infoSink, "Storage qualifiers must match:", unitStage);
writeTypeComparison = true;
printQualifiers = true;
}
// Uniform and buffer blocks must either both have an instance name, or
@ -888,33 +979,36 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getQualifier().isUniformOrBuffer() &&
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) {
error(infoSink, "Matched Uniform or Storage blocks must all be anonymous,"
" or all be named:");
" or all be named:", unitStage);
writeTypeComparison = true;
}
if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage &&
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) ||
(!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) {
warn(infoSink, "Matched shader interfaces are using different instance names.");
warn(infoSink, "Matched shader interfaces are using different instance names.", unitStage);
writeTypeComparison = true;
}
// Precision...
if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
error(infoSink, "Precision qualifiers must match:");
error(infoSink, "Precision qualifiers must match:", unitStage);
writeTypeComparison = true;
printPrecision = true;
}
// Invariance...
if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
error(infoSink, "Presence of invariant qualifier must match:");
error(infoSink, "Presence of invariant qualifier must match:", unitStage);
writeTypeComparison = true;
printQualifiers = true;
}
// Precise...
if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) {
error(infoSink, "Presence of precise qualifier must match:");
error(infoSink, "Presence of precise qualifier must match:", unitStage);
writeTypeComparison = true;
printPrecision = true;
}
// Auxiliary and interpolation...
@ -928,57 +1022,137 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) {
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:", unitStage);
writeTypeComparison = true;
printQualifiers = true;
}
// Memory...
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent ||
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
error(infoSink, "Memory qualifiers must match:");
writeTypeComparison = true;
bool memoryQualifierError = false;
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent) {
error(infoSink, "Memory coherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent) {
error(infoSink, "Memory devicecoherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent) {
error(infoSink, "Memory queuefamilycoherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent) {
error(infoSink, "Memory workgroupcoherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent) {
error(infoSink, "Memory subgroupcoherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().shadercallcoherent != unitSymbol.getQualifier().shadercallcoherent) {
error(infoSink, "Memory shadercallcoherent qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate) {
error(infoSink, "Memory nonprivate qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil) {
error(infoSink, "Memory volatil qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict) {
error(infoSink, "Memory restrict qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly) {
error(infoSink, "Memory readonly qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
error(infoSink, "Memory writeonly qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (memoryQualifierError) {
writeTypeComparison = true;
printQualifiers = true;
}
// Layouts...
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
// requires separate user-supplied offset from actual computed offset, but
// current implementation only has one offset.
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex ||
symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding ||
(symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
error(infoSink, "Layout qualification must match:");
bool layoutQualifierError = false;
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix) {
error(infoSink, "Layout matrix qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking) {
error(infoSink, "Layout packing qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) {
error(infoSink, "Layout location qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent) {
error(infoSink, "Layout component qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex) {
error(infoSink, "Layout index qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) {
error(infoSink, "Layout binding qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset)) {
error(infoSink, "Layout offset qualifier must match:", unitStage);
layoutQualifierError = true;
}
if (layoutQualifierError) {
writeTypeComparison = true;
printQualifiers = true;
}
// Initializers have to match, if both are present, and if we don't already know the types don't match
if (! writeTypeComparison) {
if (! writeTypeComparison && ! errorReported) {
if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) {
if (symbol.getConstArray() != unitSymbol.getConstArray()) {
error(infoSink, "Initializers must match:");
error(infoSink, "Initializers must match:", unitStage);
infoSink.info << " " << symbol.getName() << "\n";
}
}
}
if (writeTypeComparison) {
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus ";
if (symbol.getName() != unitSymbol.getName())
infoSink.info << unitSymbol.getName() << ": ";
infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n";
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
symbol.getType().getStruct() && unitSymbol.getType().getStruct()) {
if (printType) {
infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision,
printType, symbol.getName(), symbol.getType().getTypeName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision,
printType, unitSymbol.getName(), unitSymbol.getType().getTypeName()) << "\"\n";
} else {
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName()
<< ": \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << " Instance: " << unitSymbol.getName()
<< ": \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
}
} else {
if (printType) {
infoSink.info << " " << StageName(getStage()) << " stage: \""
<< symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, symbol.getName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \""
<< unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, unitSymbol.getName()) << "\"\n";
} else {
infoSink.info << " " << StageName(getStage()) << " stage: " << symbol.getName() << " \""
<< symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: " << unitSymbol.getName() << " \""
<< unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
}
}
}
#endif
}
@ -1786,7 +1960,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
return size;
}
int numComponents;
int numComponents {0};
if (type.isScalar())
numComponents = 1;
else if (type.isVector())
@ -1934,7 +2108,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
}
// rule 9
if (type.getBasicType() == EbtStruct) {
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
const TTypeList& memberList = *type.getStruct();
size = 0;
@ -2159,10 +2333,11 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
return type.isArray() &&
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
(language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
! type.getQualifier().patch) ||
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
type.getQualifier().pervertexNV) ||
(type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}

View file

@ -290,6 +290,8 @@ public:
resources(TBuiltInResource{}),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invertY(false),
dxPositionW(false),
enhancedMsgs(false),
useStorageBuffer(false),
invariantAll(false),
nanMinMaxClamp(false),
@ -307,7 +309,7 @@ public:
useVulkanMemoryModel(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
postDepthCoverage(false), depthLayout(EldNone),
hlslFunctionality1(false),
@ -397,6 +399,9 @@ public:
case EShTargetSpv_1_5:
processes.addProcess("target-env spirv1.5");
break;
case EShTargetSpv_1_6:
processes.addProcess("target-env spirv1.6");
break;
default:
processes.addProcess("target-env spirvUnknown");
break;
@ -415,6 +420,9 @@ public:
case EShTargetVulkan_1_2:
processes.addProcess("target-env vulkan1.2");
break;
case EShTargetVulkan_1_3:
processes.addProcess("target-env vulkan1.3");
break;
default:
processes.addProcess("target-env vulkanUnknown");
break;
@ -460,6 +468,20 @@ public:
}
bool getInvertY() const { return invertY; }
void setDxPositionW(bool dxPosW)
{
dxPositionW = dxPosW;
if (dxPositionW)
processes.addProcess("dx-position-w");
}
bool getDxPositionW() const { return dxPositionW; }
void setEnhancedMsgs()
{
enhancedMsgs = true;
}
bool getEnhancedMsgs() const { return enhancedMsgs && source == EShSourceGlsl; }
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
@ -812,6 +834,8 @@ public:
bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void setTexCoordRedeclared() { texCoordBuiltinRedeclared = true; }
bool getTexCoordRedeclared() const { return texCoordBuiltinRedeclared; }
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
unsigned int getBlendEquations() const { return blendEquations; }
bool setXfbBufferStride(int buffer, unsigned stride)
@ -1016,8 +1040,8 @@ public:
protected:
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*);
void warn(TInfoSink& infoSink, const char*);
void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&);
@ -1070,6 +1094,8 @@ protected:
int numPushConstants;
bool recursive;
bool invertY;
bool dxPositionW;
bool enhancedMsgs;
bool useStorageBuffer;
bool invariantAll;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
@ -1098,6 +1124,7 @@ protected:
TLayoutGeometry outputPrimitive;
bool pixelCenterInteger;
bool originUpperLeft;
bool texCoordBuiltinRedeclared;
TVertexSpacing vertexSpacing;
TVertexOrder vertexOrder;
TInterlockOrdering interlockOrdering;
@ -1158,6 +1185,7 @@ protected:
// for callableData/callableDataIn
// set of names of statically read/written I/O that might need extra checking
std::set<TString> ioAccessed;
// source code of shader, useful as part of debug information
std::string sourceFile;
std::string sourceText;

View file

@ -56,4 +56,4 @@ if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent EXPORT OSDependentTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
endif(ENABLE_GLSLANG_INSTALL)
endif()

View file

@ -172,7 +172,7 @@ namespace {
pthread_mutex_t gMutex;
}
void InitGlobalLock()
static void InitMutex(void)
{
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
@ -180,6 +180,12 @@ void InitGlobalLock()
pthread_mutex_init(&gMutex, &mutexattr);
}
void InitGlobalLock()
{
static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, InitMutex);
}
void GetGlobalLock()
{
pthread_mutex_lock(&gMutex);

View file

@ -55,7 +55,7 @@ if(ENABLE_GLSLANG_JS)
if(ENABLE_EMSCRIPTEN_SINGLE_FILE)
target_link_libraries(glslang.js "-s SINGLE_FILE=1")
endif(ENABLE_EMSCRIPTEN_SINGLE_FILE)
endif()
if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE)
target_link_libraries(glslang.js "-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0")
@ -67,5 +67,5 @@ if(ENABLE_GLSLANG_JS)
add_custom_command(TARGET glslang.js POST_BUILD
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js)
endif()
endif(EMSCRIPTEN)
endif(ENABLE_GLSLANG_JS)
endif()
endif()

View file

@ -45,10 +45,10 @@ endif()
if(WIN32)
source_group("Source" FILES ${SOURCES})
endif(WIN32)
endif()
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent EXPORT OSDependentTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
endif(ENABLE_GLSLANG_INSTALL)
endif()

View file

@ -150,8 +150,8 @@ typedef enum {
typedef enum {
EShClientNone, // use when there is no client, e.g. for validation
EShClientVulkan,
EShClientOpenGL,
EShClientVulkan, // as GLSL dialect, specifies KHR_vulkan_glsl extension
EShClientOpenGL, // as GLSL dialect, specifies ARB_gl_spirv extension
LAST_ELEMENT_MARKER(EShClientCount),
} EShClient;
@ -166,8 +166,9 @@ typedef enum {
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
EShTargetVulkan_1_3 = (1 << 22) | (3 << 12), // Vulkan 1.3
EShTargetOpenGL_450 = 450, // OpenGL
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 5),
} EShTargetClientVersion;
typedef EShTargetClientVersion EshTargetClientVersion;
@ -179,7 +180,8 @@ typedef enum {
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
EShTargetSpv_1_6 = (1 << 16) | (6 << 8), // SPIR-V 1.6
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7),
} EShTargetLanguageVersion;
struct TInputLanguage {
@ -262,6 +264,7 @@ enum EShMessages : unsigned {
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
EShMsgEnhanced = (1 << 15), // enhanced message readability
LAST_ELEMENT_MARKER(EShMsgCount),
};
@ -468,6 +471,7 @@ public:
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
GLSLANG_EXPORT void setOverrideVersion(int version);
// IO resolver binding data: see comments in ShaderLang.cpp
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
@ -485,6 +489,8 @@ public:
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
GLSLANG_EXPORT void setUniformLocationBase(int base);
GLSLANG_EXPORT void setInvertY(bool invert);
GLSLANG_EXPORT void setDxPositionW(bool dxPosW);
GLSLANG_EXPORT void setEnhancedMsgs();
#ifdef ENABLE_HLSL
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
@ -512,6 +518,9 @@ public:
// use EShClientNone and version of 0, e.g. for validation mode.
// Note 'version' does not describe the target environment,
// just the version of the source dialect to compile under.
// For example, to choose the Vulkan dialect of GLSL defined by
// version 100 of the KHR_vulkan_glsl extension: lang = EShSourceGlsl,
// dialect = EShClientVulkan, and version = 100.
//
// See the definitions of TEnvironment, EShSource, EShLanguage,
// and EShClient for choices and more detail.
@ -703,6 +712,9 @@ protected:
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
std::string sourceEntryPointName;
// overrides #version in shader source or default version if #version isn't present
int overrideVersion;
TEnvironment environment;
friend class TProgram;

View file

@ -29,7 +29,7 @@
#define GLSLextKHR_H
static const int GLSLextKHRVersion = 100;
static const int GLSLextKHRRevision = 2;
static const int GLSLextKHRRevision = 3;
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
@ -52,5 +52,6 @@ static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragm
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
#endif // #ifndef GLSLextKHR_H

View file

@ -260,6 +260,7 @@ protected:
std::unordered_map<std::string, spv::Id> extBuiltinMap;
std::unordered_map<long long, spv::Id> symbolValues;
std::unordered_map<uint32_t, spv::Id> builtInVariableIds;
std::unordered_set<long long> rValueParameters; // set of formal function parameters passed as rValues,
// rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap;
@ -1007,6 +1008,8 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInRayTminKHR;
case glslang::EbvRayTmax:
return spv::BuiltInRayTmaxKHR;
case glslang::EbvCullMask:
return spv::BuiltInCullMaskKHR;
case glslang::EbvInstanceCustomIndex:
return spv::BuiltInInstanceCustomIndexKHR;
case glslang::EbvHitT:
@ -1048,6 +1051,15 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
return spv::BuiltInBaryCoordNoPerspNV;
case glslang::EbvBaryCoordEXT:
builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric);
builder.addCapability(spv::CapabilityFragmentBarycentricKHR);
return spv::BuiltInBaryCoordKHR;
case glslang::EbvBaryCoordNoPerspEXT:
builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric);
builder.addCapability(spv::CapabilityFragmentBarycentricKHR);
return spv::BuiltInBaryCoordNoPerspKHR;
// mesh shaders
case glslang::EbvTaskCountNV:
return spv::BuiltInTaskCountNV;
@ -1256,8 +1268,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
if (type.getBasicType() == glslang::EbtRayQuery)
return spv::StorageClassPrivate;
#ifndef GLSLANG_WEB
if (type.getQualifier().isSpirvByReference())
return spv::StorageClassFunction;
if (type.getQualifier().isSpirvByReference()) {
if (type.getQualifier().isParamInput() || type.getQualifier().isParamOutput())
return spv::StorageClassFunction;
}
#endif
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
@ -1662,9 +1676,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
case EShLangCompute:
builder.addCapability(spv::CapabilityShader);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
std::vector<spv::Id> dimConstId;
for (int dim = 0; dim < 3; ++dim) {
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
if (specConst) {
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
glslangIntermediate->getLocalSizeSpecId(dim));
}
}
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
} else {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
}
if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) {
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV);
@ -1762,15 +1789,35 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addCapability(spv::CapabilityRayTracingNV);
builder.addExtension("SPV_NV_ray_tracing");
}
if (glslangIntermediate->getStage() != EShLangRayGen && glslangIntermediate->getStage() != EShLangCallable)
{
if (extensions.find("GL_EXT_ray_cull_mask") != extensions.end()) {
builder.addCapability(spv::CapabilityRayCullMaskKHR);
builder.addExtension("SPV_KHR_ray_cull_mask");
}
}
break;
}
case EShLangTaskNV:
case EShLangMeshNV:
builder.addCapability(spv::CapabilityMeshShadingNV);
builder.addExtension(spv::E_SPV_NV_mesh_shader);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
std::vector<spv::Id> dimConstId;
for (int dim = 0; dim < 3; ++dim) {
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
if (specConst) {
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
glslangIntermediate->getLocalSizeSpecId(dim));
}
}
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
} else {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
}
if (glslangIntermediate->getStage() == EShLangMeshNV) {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
glslangIntermediate->getVertices());
@ -1830,10 +1877,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
std::vector<spv::Id> operandIds;
assert(!modeId.second.empty());
for (auto extraOperand : modeId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
if (extraOperand->getType().getQualifier().isSpecConstant())
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
else
operandIds.push_back(createSpvConstant(*extraOperand));
}
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
}
@ -2746,6 +2793,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
} else {
handleFunctionEntry(node);
}
if (options.generateDebugInfo) {
const auto& loc = node->getLoc();
currentFunction->setDebugLineInfo(builder.getSourceFile(), loc.line, loc.column);
}
} else {
if (inEntryPoint)
entryPointTerminated = true;
@ -3384,7 +3435,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
const auto& spirvInst = node->getSpirvInstruction();
if (spirvInst.set == "") {
std::vector<spv::IdImmediate> idImmOps;
for (int i = 0; i < glslangOperands.size(); ++i) {
for (unsigned int i = 0; i < glslangOperands.size(); ++i) {
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Translate the constant to a literal value
std::vector<unsigned> literals;
@ -3777,7 +3828,16 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
switch (node->getFlowOp()) {
case glslang::EOpKill:
builder.makeStatementTerminator(spv::OpKill, "post-discard");
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
builder.addCapability(spv::CapabilityDemoteToHelperInvocation);
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
} else {
builder.makeStatementTerminator(spv::OpTerminateInvocation, "post-terminate-invocation");
}
} else {
builder.makeStatementTerminator(spv::OpKill, "post-discard");
}
break;
case glslang::EOpTerminateInvocation:
builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
@ -3940,12 +4000,14 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
return builder.makeFloatType(16);
case glslang::EbtInt64: return builder.makeIntType(64);
case glslang::EbtInt64:
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
case glslang::EbtUint64: return builder.makeUintType(64);
builder.addCapability(spv::CapabilityInt64ImageEXT);
return builder.makeIntType(64);
case glslang::EbtUint64:
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
builder.addCapability(spv::CapabilityInt64ImageEXT);
return builder.makeUintType(64);
#endif
default:
assert(0);
@ -4146,68 +4208,55 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
const auto& spirvType = type.getSpirvType();
const auto& spirvInst = spirvType.spirvInst;
std::vector<spv::Id> operands;
std::vector<spv::IdImmediate> operands;
for (const auto& typeParam : spirvType.typeParams) {
if (typeParam.isConstant) {
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
operands.push_back(literal);
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
operands.push_back(literal);
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
operands.push_back({false, literal});
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
operands.push_back({false, literal});
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
operands.push_back({false, literal});
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
operands.push_back({false, literal});
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
operands.push_back({false, literal});
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} else
assert(0); // Unexpected type
} else {
int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(
typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
operands.push_back(constant);
}
} else {
// Type specifier
spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
operands.push_back(typeId);
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
operands.push_back({false, literal});
}
} else
assert(0); // Unexpected type
} else
operands.push_back({true, createSpvConstant(*typeParam.constant)});
}
if (spirvInst.set == "")
spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
else {
spvType = builder.createBuiltinCall(
spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
}
assert(spirvInst.set == ""); // Currently, couldn't be extended instructions.
spvType = builder.makeGenericType(static_cast<spv::Op>(spirvInst.id), operands);
break;
}
#endif
@ -7506,6 +7555,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
break;
case glslang::EOpReadFirstInvocation:
opCode = spv::OpSubgroupFirstInvocationKHR;
if (builder.isVectorType(typeId))
return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
break;
case glslang::EOpBallot:
{
@ -7630,7 +7681,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
op == spv::OpSubgroupReadInvocationKHR ||
op == spv::OpSubgroupReadInvocationKHR || op == spv::OpSubgroupFirstInvocationKHR ||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
op == spv::OpGroupSMinNonUniformAMD ||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
@ -7659,6 +7710,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
spvGroupOperands.push_back(scalar);
spv::IdImmediate operand = { true, operands[1] };
spvGroupOperands.push_back(operand);
} else if (op == spv::OpSubgroupFirstInvocationKHR) {
spvGroupOperands.push_back(scalar);
} else if (op == spv::OpGroupBroadcast) {
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
spvGroupOperands.push_back(scope);
@ -8698,7 +8751,32 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
// it was not found, create it
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType());
// There are pairs of symbols that map to the same SPIR-V built-in:
// gl_ObjectToWorldEXT and gl_ObjectToWorld3x4EXT, and gl_WorldToObjectEXT
// and gl_WorldToObject3x4EXT. SPIR-V forbids having two OpVariables
// with the same BuiltIn in the same storage class, so we must re-use one.
const bool mayNeedToReuseBuiltIn =
builtIn == spv::BuiltInObjectToWorldKHR ||
builtIn == spv::BuiltInWorldToObjectKHR;
if (mayNeedToReuseBuiltIn) {
auto iter = builtInVariableIds.find(uint32_t(builtIn));
if (builtInVariableIds.end() != iter) {
id = iter->second;
symbolValues[symbol->getId()] = id;
if (forcedType.second != spv::NoType)
forceType[id] = forcedType.second;
return id;
}
}
id = createSpvVariable(symbol, forcedType.first);
if (mayNeedToReuseBuiltIn) {
builtInVariableIds.insert({uint32_t(builtIn), id});
}
symbolValues[symbol->getId()] = id;
if (forcedType.second != spv::NoType)
forceType[id] = forcedType.second;
@ -8721,8 +8799,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
}
if (symbol->getQualifier().hasLocation())
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
if (symbol->getQualifier().hasLocation()) {
if (!(glslangIntermediate->isRayTracingStage() && glslangIntermediate->IsRequestedExtension(glslang::E_GL_EXT_ray_tracing)
&& (builder.getStorageClass(id) == spv::StorageClassRayPayloadKHR ||
builder.getStorageClass(id) == spv::StorageClassIncomingRayPayloadKHR ||
builder.getStorageClass(id) == spv::StorageClassCallableDataKHR ||
builder.getStorageClass(id) == spv::StorageClassIncomingCallableDataKHR))) {
// Location values are used to link TraceRayKHR and ExecuteCallableKHR to corresponding variables
// but are not valid in SPIRV since they are supported only for Input/Output Storage classes.
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
}
}
builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
builder.addCapability(spv::CapabilityGeometryStreams);
@ -8756,7 +8844,16 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
// add built-in variable decoration
if (builtIn != spv::BuiltInMax) {
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
// WorkgroupSize deprecated in spirv1.6
if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_6 ||
builtIn != spv::BuiltInWorkgroupSize)
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
}
// Add volatile decoration to HelperInvocation for spirv1.6 and beyond
if (builtIn == spv::BuiltInHelperInvocation &&
glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
builder.addDecoration(id, spv::DecorationVolatile);
}
#ifndef GLSLANG_WEB
@ -8808,6 +8905,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
}
if (symbol->getQualifier().pervertexEXT) {
builder.addDecoration(id, spv::DecorationPerVertexKHR);
builder.addCapability(spv::CapabilityFragmentBarycentricKHR);
builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric);
}
if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
@ -8841,12 +8944,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
std::vector<spv::Id> operandIds;
assert(!decorateId.second.empty());
for (auto extraOperand : decorateId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
if (extraOperand->getQualifier().isSpecConstant())
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
else
operandIds.push_back(createSpvConstant(*extraOperand));
}
builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
}
// Add spirv_decorate_string
@ -9029,15 +9132,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
break;
#ifndef GLSLANG_WEB
case glslang::EbtInt8:
builder.addCapability(spv::CapabilityInt8);
spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
break;
case glslang::EbtUint8:
builder.addCapability(spv::CapabilityInt8);
spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
break;
case glslang::EbtInt16:
builder.addCapability(spv::CapabilityInt16);
spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
break;
case glslang::EbtUint16:
builder.addCapability(spv::CapabilityInt16);
spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
break;
case glslang::EbtInt64:
@ -9050,6 +9157,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
break;
case glslang::EbtFloat16:
builder.addCapability(spv::CapabilityFloat16);
spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
break;
#endif
@ -9078,15 +9186,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
break;
#ifndef GLSLANG_WEB
case glslang::EbtInt8:
builder.addCapability(spv::CapabilityInt8);
scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
break;
case glslang::EbtUint8:
builder.addCapability(spv::CapabilityInt8);
scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
break;
case glslang::EbtInt16:
builder.addCapability(spv::CapabilityInt16);
scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
break;
case glslang::EbtUint16:
builder.addCapability(spv::CapabilityInt16);
scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
break;
case glslang::EbtInt64:
@ -9099,6 +9211,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
break;
case glslang::EbtFloat16:
builder.addCapability(spv::CapabilityFloat16);
scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
break;
case glslang::EbtReference:

View file

@ -40,7 +40,7 @@
#endif
#include "SpvTools.h"
#include "../glslang/Include/intermediate.h"
#include "glslang/Include/intermediate.h"
#include <string>
#include <vector>

View file

@ -160,15 +160,29 @@ namespace spv {
}
// Is this an opcode we should remove when using --strip?
bool spirvbin_t::isStripOp(spv::Op opCode) const
bool spirvbin_t::isStripOp(spv::Op opCode, unsigned start) const
{
switch (opCode) {
case spv::OpSource:
case spv::OpSourceExtension:
case spv::OpName:
case spv::OpMemberName:
case spv::OpLine: return true;
default: return false;
case spv::OpLine :
{
const std::string name = literalString(start + 2);
std::vector<std::string>::const_iterator it;
for (it = stripWhiteList.begin(); it < stripWhiteList.end(); it++)
{
if (name.find(*it) != std::string::npos) {
return false;
}
}
return true;
}
default :
return false;
}
}
@ -297,15 +311,21 @@ namespace spv {
std::string spirvbin_t::literalString(unsigned word) const
{
std::string literal;
const spirword_t * pos = spv.data() + word;
literal.reserve(16);
const char* bytes = reinterpret_cast<const char*>(spv.data() + word);
while (bytes && *bytes)
literal += *bytes++;
return literal;
do {
spirword_t word = *pos;
for (int i = 0; i < 4; i++) {
char c = word & 0xff;
if (c == '\0')
return literal;
literal += c;
word >>= 8;
}
pos++;
} while (true);
}
void spirvbin_t::applyMap()
@ -366,7 +386,7 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
// remember opcodes we want to strip later
if (isStripOp(opCode))
if (isStripOp(opCode, start))
stripInst(start);
return true;
},
@ -1488,13 +1508,24 @@ namespace spv {
}
// remap from a memory image
void spirvbin_t::remap(std::vector<std::uint32_t>& in_spv, std::uint32_t opts)
void spirvbin_t::remap(std::vector<std::uint32_t>& in_spv, const std::vector<std::string>& whiteListStrings,
std::uint32_t opts)
{
stripWhiteList = whiteListStrings;
spv.swap(in_spv);
remap(opts);
spv.swap(in_spv);
}
// remap from a memory image - legacy interface without white list
void spirvbin_t::remap(std::vector<std::uint32_t>& in_spv, std::uint32_t opts)
{
stripWhiteList.clear();
spv.swap(in_spv);
remap(opts);
spv.swap(in_spv);
}
} // namespace SPV
#endif // defined (use_cpp11)

View file

@ -118,6 +118,10 @@ public:
virtual ~spirvbin_t() { }
// remap on an existing binary in memory
void remap(std::vector<std::uint32_t>& spv, const std::vector<std::string>& whiteListStrings,
std::uint32_t opts = DO_EVERYTHING);
// remap on an existing binary in memory - legacy interface without white list
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
// Type for error/log handler functions
@ -180,6 +184,8 @@ private:
unsigned typeSizeInWords(spv::Id id) const;
unsigned idTypeSizeInWords(spv::Id id) const;
bool isStripOp(spv::Op opCode, unsigned start) const;
spv::Id& asId(unsigned word) { return spv[word]; }
const spv::Id& asId(unsigned word) const { return spv[word]; }
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
@ -249,6 +255,8 @@ private:
std::vector<spirword_t> spv; // SPIR words
std::vector<std::string> stripWhiteList;
namemap_t nameMap; // ID names from OpName
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use

View file

@ -427,6 +427,37 @@ Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols)
return type->getResultId();
}
Id Builder::makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands)
{
// try to find it
Instruction* type;
for (int t = 0; t < (int)groupedTypes[opcode].size(); ++t) {
type = groupedTypes[opcode][t];
if (static_cast<size_t>(type->getNumOperands()) != operands.size())
continue; // Number mismatch, find next
bool match = true;
for (int op = 0; match && op < (int)operands.size(); ++op) {
match = (operands[op].isId ? type->getIdOperand(op) : type->getImmediateOperand(op)) == operands[op].word;
}
if (match)
return type->getResultId();
}
// not found, make it
type = new Instruction(getUniqueId(), NoType, opcode);
for (size_t op = 0; op < operands.size(); ++op) {
if (operands[op].isId)
type->addIdOperand(operands[op].word);
else
type->addImmediateOperand(operands[op].word);
}
groupedTypes[opcode].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
return type->getResultId();
}
// TODO: performance: track arrays per stride
// If a stride is supplied (non-zero) make an array.

View file

@ -99,6 +99,10 @@ public:
stringIds[file_c_str] = strId;
return strId;
}
spv::Id getSourceFile() const
{
return sourceFileStringId;
}
void setSourceFile(const std::string& file)
{
sourceFileStringId = getStringId(file);
@ -181,6 +185,7 @@ public:
Id makeSamplerType();
Id makeSampledImageType(Id imageType);
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
Id makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands);
// accelerationStructureNV type
Id makeAccelerationStructureType();

View file

@ -44,10 +44,8 @@
#include <algorithm>
#include "SpvBuilder.h"
#include "spirv.hpp"
#include "GlslangToSpv.h"
#include "SpvBuilder.h"
namespace spv {
#include "GLSL.std.450.h"
#include "GLSL.ext.KHR.h"
@ -113,8 +111,6 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
}
}
break;
case OpAccessChain:
case OpPtrAccessChain:
case OpCopyObject:
break;
case OpFConvert:
@ -161,26 +157,43 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
switch (inst.getImmediateOperand(1)) {
case GLSLstd450Frexp:
case GLSLstd450FrexpStruct:
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeInt, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
break;
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeFloat, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
break;
default:
break;
}
break;
case OpAccessChain:
case OpPtrAccessChain:
if (isPointerType(typeId))
break;
if (basicTypeOp == OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
else if (width == 8)
addCapability(CapabilityInt8);
}
default:
if (basicTypeOp == OpTypeFloat && width == 16)
addCapability(CapabilityFloat16);
if (basicTypeOp == OpTypeInt && width == 16)
addCapability(CapabilityInt16);
if (basicTypeOp == OpTypeInt && width == 8)
addCapability(CapabilityInt8);
if (basicTypeOp == OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
else if (width == 8)
addCapability(CapabilityInt8);
else if (width == 64)
addCapability(CapabilityInt64);
} else if (basicTypeOp == OpTypeFloat) {
if (width == 16)
addCapability(CapabilityFloat16);
else if (width == 64)
addCapability(CapabilityFloat64);
}
break;
}
}

View file

@ -68,6 +68,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
}
case glslang::EShTargetVulkan_1_2:
return spv_target_env::SPV_ENV_VULKAN_1_2;
case glslang::EShTargetVulkan_1_3:
return spv_target_env::SPV_ENV_VULKAN_1_3;
default:
break;
}
@ -210,6 +212,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
if (options->optimizeSize) {
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass());
}
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());

View file

@ -47,7 +47,7 @@
#include "spirv-tools/libspirv.h"
#endif
#include "../glslang/MachineIndependent/localintermediate.h"
#include "glslang/MachineIndependent/localintermediate.h"
#include "Logger.h"
namespace glslang {

View file

@ -43,6 +43,7 @@
#include <stack>
#include <sstream>
#include <cstring>
#include <utility>
#include "disassemble.h"
#include "doc.h"
@ -100,6 +101,7 @@ protected:
void outputMask(OperandClass operandClass, unsigned mask);
void disassembleImmediates(int numOperands);
void disassembleIds(int numOperands);
std::pair<int, std::string> decodeString();
int disassembleString();
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
@ -290,31 +292,44 @@ void SpirvStream::disassembleIds(int numOperands)
}
}
// return the number of operands consumed by the string
int SpirvStream::disassembleString()
// decode string from words at current position (non-consuming)
std::pair<int, std::string> SpirvStream::decodeString()
{
int startWord = word;
out << " \"";
const char* wordString;
std::string res;
int wordPos = word;
char c;
bool done = false;
do {
unsigned int content = stream[word];
wordString = (const char*)&content;
unsigned int content = stream[wordPos];
for (int charCount = 0; charCount < 4; ++charCount) {
if (*wordString == 0) {
c = content & 0xff;
content >>= 8;
if (c == '\0') {
done = true;
break;
}
out << *(wordString++);
res += c;
}
++word;
} while (! done);
++wordPos;
} while(! done);
return std::make_pair(wordPos - word, res);
}
// return the number of operands consumed by the string
int SpirvStream::disassembleString()
{
out << " \"";
std::pair<int, std::string> decoderes = decodeString();
out << decoderes.second;
out << "\"";
return word - startWord;
word += decoderes.first;
return decoderes.first;
}
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
@ -331,7 +346,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
nextNestedControl = 0;
}
} else if (opCode == OpExtInstImport) {
idDescriptor[resultId] = (const char*)(&stream[word]);
idDescriptor[resultId] = decodeString().second;
}
else {
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
@ -428,7 +443,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
--numOperands;
// Get names for printing "(XXX)" for readability, *after* this id
if (opCode == OpName)
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
idDescriptor[stream[word - 1]] = decodeString().second;
break;
case OperandVariableIds:
disassembleIds(numOperands);

View file

@ -305,7 +305,8 @@ const char* DecorationString(int decoration)
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
case DecorationPerViewNV: return "PerViewNV";
case DecorationPerTaskNV: return "PerTaskNV";
case DecorationPerVertexNV: return "PerVertexNV";
case DecorationPerVertexKHR: return "PerVertexKHR";
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
@ -392,6 +393,7 @@ const char* BuiltInString(int builtIn)
case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
case BuiltInRayTminKHR: return "RayTminKHR";
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
case BuiltInCullMaskKHR: return "CullMaskKHR";
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
@ -406,8 +408,8 @@ const char* BuiltInString(int builtIn)
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case BuiltInBaryCoordKHR: return "BaryCoordKHR";
case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR";
case BuiltInFragSizeEXT: return "FragSizeEXT";
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
@ -900,6 +902,12 @@ const char* CapabilityString(int info)
case CapabilityDeviceGroup: return "DeviceGroup";
case CapabilityMultiView: return "MultiView";
case CapabilityDenormPreserve: return "DenormPreserve";
case CapabilityDenormFlushToZero: return "DenormFlushToZero";
case CapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve";
case CapabilityRoundingModeRTE: return "RoundingModeRTE";
case CapabilityRoundingModeRTZ: return "RoundingModeRTZ";
case CapabilityStencilExportEXT: return "StencilExportEXT";
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
@ -919,12 +927,13 @@ const char* CapabilityString(int info)
case CapabilityRayTracingNV: return "RayTracingNV";
case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
case CapabilityRayTracingKHR: return "RayTracingKHR";
case CapabilityRayCullMaskKHR: return "RayCullMaskKHR";
case CapabilityRayQueryKHR: return "RayQueryKHR";
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR";
case CapabilityMeshShadingNV: return "MeshShadingNV";
case CapabilityImageFootprintNV: return "ImageFootprintNV";
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT

View file

@ -49,12 +49,12 @@ namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10500
#define SPV_REVISION 4
#define SPV_VERSION 0x10600
#define SPV_REVISION 1
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010500;
static const unsigned int Revision = 4;
static const unsigned int Version = 0x00010600;
static const unsigned int Revision = 1;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@ -65,6 +65,7 @@ enum SourceLanguage {
SourceLanguageOpenCL_C = 3,
SourceLanguageOpenCL_CPP = 4,
SourceLanguageHLSL = 5,
SourceLanguageCPP_for_OpenCL = 6,
SourceLanguageMax = 0x7fffffff,
};
@ -352,6 +353,8 @@ enum ImageOperandsShift {
ImageOperandsVolatileTexelKHRShift = 11,
ImageOperandsSignExtendShift = 12,
ImageOperandsZeroExtendShift = 13,
ImageOperandsNontemporalShift = 14,
ImageOperandsOffsetsShift = 16,
ImageOperandsMax = 0x7fffffff,
};
@ -375,6 +378,8 @@ enum ImageOperandsMask {
ImageOperandsVolatileTexelKHRMask = 0x00000800,
ImageOperandsSignExtendMask = 0x00001000,
ImageOperandsZeroExtendMask = 0x00002000,
ImageOperandsNontemporalMask = 0x00004000,
ImageOperandsOffsetsMask = 0x00010000,
};
enum FPFastMathModeShift {
@ -491,6 +496,7 @@ enum Decoration {
DecorationPerPrimitiveNV = 5271,
DecorationPerViewNV = 5272,
DecorationPerTaskNV = 5273,
DecorationPerVertexKHR = 5285,
DecorationPerVertexNV = 5285,
DecorationNonUniform = 5300,
DecorationNonUniformEXT = 5300,
@ -498,6 +504,10 @@ enum Decoration {
DecorationRestrictPointerEXT = 5355,
DecorationAliasedPointer = 5356,
DecorationAliasedPointerEXT = 5356,
DecorationBindlessSamplerNV = 5398,
DecorationBindlessImageNV = 5399,
DecorationBoundSamplerNV = 5400,
DecorationBoundImageNV = 5401,
DecorationSIMTCallINTEL = 5599,
DecorationReferencedIndirectlyINTEL = 5602,
DecorationClobberINTEL = 5607,
@ -537,6 +547,7 @@ enum Decoration {
DecorationFunctionFloatingPointModeINTEL = 6080,
DecorationSingleElementVectorINTEL = 6085,
DecorationVectorComputeCallableFunctionINTEL = 6087,
DecorationMediaBlockIOINTEL = 6140,
DecorationMax = 0x7fffffff,
};
@ -621,7 +632,9 @@ enum BuiltIn {
BuiltInLayerPerViewNV = 5279,
BuiltInMeshViewCountNV = 5280,
BuiltInMeshViewIndicesNV = 5281,
BuiltInBaryCoordKHR = 5286,
BuiltInBaryCoordNV = 5286,
BuiltInBaryCoordNoPerspKHR = 5287,
BuiltInBaryCoordNoPerspNV = 5287,
BuiltInFragSizeEXT = 5292,
BuiltInFragmentSizeNV = 5292,
@ -660,6 +673,7 @@ enum BuiltIn {
BuiltInSMCountNV = 5375,
BuiltInWarpIDNV = 5376,
BuiltInSMIDNV = 5377,
BuiltInCullMaskKHR = 6021,
BuiltInMax = 0x7fffffff,
};
@ -722,6 +736,7 @@ enum FunctionControlShift {
FunctionControlDontInlineShift = 1,
FunctionControlPureShift = 2,
FunctionControlConstShift = 3,
FunctionControlOptNoneINTELShift = 16,
FunctionControlMax = 0x7fffffff,
};
@ -731,6 +746,7 @@ enum FunctionControlMask {
FunctionControlDontInlineMask = 0x00000002,
FunctionControlPureMask = 0x00000004,
FunctionControlConstMask = 0x00000008,
FunctionControlOptNoneINTELMask = 0x00010000,
};
enum MemorySemanticsShift {
@ -911,6 +927,7 @@ enum Capability {
CapabilityGroupNonUniformQuad = 68,
CapabilityShaderLayer = 69,
CapabilityShaderViewportIndex = 70,
CapabilityUniformDecoration = 71,
CapabilityFragmentShadingRateKHR = 4422,
CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427,
@ -959,6 +976,7 @@ enum Capability {
CapabilityFragmentFullyCoveredEXT = 5265,
CapabilityMeshShadingNV = 5266,
CapabilityImageFootprintNV = 5282,
CapabilityFragmentBarycentricKHR = 5284,
CapabilityFragmentBarycentricNV = 5284,
CapabilityComputeDerivativeGroupQuadsNV = 5288,
CapabilityFragmentDensityEXT = 5291,
@ -1003,7 +1021,9 @@ enum Capability {
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
CapabilityShaderSMBuiltinsNV = 5373,
CapabilityFragmentShaderPixelInterlockEXT = 5378,
CapabilityDemoteToHelperInvocation = 5379,
CapabilityDemoteToHelperInvocationEXT = 5379,
CapabilityBindlessTextureNV = 5390,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
@ -1028,6 +1048,7 @@ enum Capability {
CapabilityFPGAMemoryAttributesINTEL = 5824,
CapabilityFPFastMathModeINTEL = 5837,
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
CapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
CapabilityUnstructuredLoopControlsINTEL = 5886,
CapabilityFPGALoopControlsINTEL = 5888,
CapabilityKernelAttributesINTEL = 5892,
@ -1036,14 +1057,27 @@ enum Capability {
CapabilityFPGAClusterAttributesINTEL = 5904,
CapabilityLoopFuseINTEL = 5906,
CapabilityFPGABufferLocationINTEL = 5920,
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
CapabilityUSMStorageClassesINTEL = 5935,
CapabilityIOPipesINTEL = 5943,
CapabilityBlockingPipesINTEL = 5945,
CapabilityFPGARegINTEL = 5948,
CapabilityDotProductInputAll = 6016,
CapabilityDotProductInputAllKHR = 6016,
CapabilityDotProductInput4x8Bit = 6017,
CapabilityDotProductInput4x8BitKHR = 6017,
CapabilityDotProductInput4x8BitPacked = 6018,
CapabilityDotProductInput4x8BitPackedKHR = 6018,
CapabilityDotProduct = 6019,
CapabilityDotProductKHR = 6019,
CapabilityRayCullMaskKHR = 6020,
CapabilityBitInstructions = 6025,
CapabilityAtomicFloat32AddEXT = 6033,
CapabilityAtomicFloat64AddEXT = 6034,
CapabilityLongConstantCompositeINTEL = 6089,
CapabilityOptNoneINTEL = 6094,
CapabilityAtomicFloat16AddEXT = 6095,
CapabilityDebugInfoModuleINTEL = 6114,
CapabilityMax = 0x7fffffff,
};
@ -1122,6 +1156,32 @@ enum FPOperationMode {
FPOperationModeMax = 0x7fffffff,
};
enum QuantizationModes {
QuantizationModesTRN = 0,
QuantizationModesTRN_ZERO = 1,
QuantizationModesRND = 2,
QuantizationModesRND_ZERO = 3,
QuantizationModesRND_INF = 4,
QuantizationModesRND_MIN_INF = 5,
QuantizationModesRND_CONV = 6,
QuantizationModesRND_CONV_ODD = 7,
QuantizationModesMax = 0x7fffffff,
};
enum OverflowModes {
OverflowModesWRAP = 0,
OverflowModesSAT = 1,
OverflowModesSAT_ZERO = 2,
OverflowModesSAT_SYM = 3,
OverflowModesMax = 0x7fffffff,
};
enum PackedVectorFormat {
PackedVectorFormatPackedVectorFormat4x8Bit = 0,
PackedVectorFormatPackedVectorFormat4x8BitKHR = 0,
PackedVectorFormatMax = 0x7fffffff,
};
enum Op {
OpNop = 0,
OpUndef = 1,
@ -1479,6 +1539,18 @@ enum Op {
OpConvertUToAccelerationStructureKHR = 4447,
OpIgnoreIntersectionKHR = 4448,
OpTerminateRayKHR = 4449,
OpSDot = 4450,
OpSDotKHR = 4450,
OpUDot = 4451,
OpUDotKHR = 4451,
OpSUDot = 4452,
OpSUDotKHR = 4452,
OpSDotAccSat = 4453,
OpSDotAccSatKHR = 4453,
OpUDotAccSat = 4454,
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@ -1517,8 +1589,16 @@ enum Op {
OpCooperativeMatrixLengthNV = 5362,
OpBeginInvocationInterlockEXT = 5364,
OpEndInvocationInterlockEXT = 5365,
OpDemoteToHelperInvocation = 5380,
OpDemoteToHelperInvocationEXT = 5380,
OpIsHelperInvocationEXT = 5381,
OpConvertUToImageNV = 5391,
OpConvertUToSamplerNV = 5392,
OpConvertImageToUNV = 5393,
OpConvertSamplerToUNV = 5394,
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@ -1543,7 +1623,7 @@ enum Op {
OpUSubSatINTEL = 5596,
OpIMul32x16INTEL = 5597,
OpUMul32x16INTEL = 5598,
OpConstFunctionPointerINTEL = 5600,
OpConstantFunctionPointerINTEL = 5600,
OpFunctionPointerCallINTEL = 5601,
OpAsmTargetINTEL = 5609,
OpAsmINTEL = 5610,
@ -1677,7 +1757,59 @@ enum Op {
OpVariableLengthArrayINTEL = 5818,
OpSaveMemoryINTEL = 5819,
OpRestoreMemoryINTEL = 5820,
OpArbitraryFloatSinCosPiINTEL = 5840,
OpArbitraryFloatCastINTEL = 5841,
OpArbitraryFloatCastFromIntINTEL = 5842,
OpArbitraryFloatCastToIntINTEL = 5843,
OpArbitraryFloatAddINTEL = 5846,
OpArbitraryFloatSubINTEL = 5847,
OpArbitraryFloatMulINTEL = 5848,
OpArbitraryFloatDivINTEL = 5849,
OpArbitraryFloatGTINTEL = 5850,
OpArbitraryFloatGEINTEL = 5851,
OpArbitraryFloatLTINTEL = 5852,
OpArbitraryFloatLEINTEL = 5853,
OpArbitraryFloatEQINTEL = 5854,
OpArbitraryFloatRecipINTEL = 5855,
OpArbitraryFloatRSqrtINTEL = 5856,
OpArbitraryFloatCbrtINTEL = 5857,
OpArbitraryFloatHypotINTEL = 5858,
OpArbitraryFloatSqrtINTEL = 5859,
OpArbitraryFloatLogINTEL = 5860,
OpArbitraryFloatLog2INTEL = 5861,
OpArbitraryFloatLog10INTEL = 5862,
OpArbitraryFloatLog1pINTEL = 5863,
OpArbitraryFloatExpINTEL = 5864,
OpArbitraryFloatExp2INTEL = 5865,
OpArbitraryFloatExp10INTEL = 5866,
OpArbitraryFloatExpm1INTEL = 5867,
OpArbitraryFloatSinINTEL = 5868,
OpArbitraryFloatCosINTEL = 5869,
OpArbitraryFloatSinCosINTEL = 5870,
OpArbitraryFloatSinPiINTEL = 5871,
OpArbitraryFloatCosPiINTEL = 5872,
OpArbitraryFloatASinINTEL = 5873,
OpArbitraryFloatASinPiINTEL = 5874,
OpArbitraryFloatACosINTEL = 5875,
OpArbitraryFloatACosPiINTEL = 5876,
OpArbitraryFloatATanINTEL = 5877,
OpArbitraryFloatATanPiINTEL = 5878,
OpArbitraryFloatATan2INTEL = 5879,
OpArbitraryFloatPowINTEL = 5880,
OpArbitraryFloatPowRINTEL = 5881,
OpArbitraryFloatPowNINTEL = 5882,
OpLoopControlINTEL = 5887,
OpFixedSqrtINTEL = 5923,
OpFixedRecipINTEL = 5924,
OpFixedRsqrtINTEL = 5925,
OpFixedSinINTEL = 5926,
OpFixedCosINTEL = 5927,
OpFixedSinCosINTEL = 5928,
OpFixedSinPiINTEL = 5929,
OpFixedCosPiINTEL = 5930,
OpFixedSinCosPiINTEL = 5931,
OpFixedLogINTEL = 5932,
OpFixedExpINTEL = 5933,
OpPtrCastToCrossWorkgroupINTEL = 5934,
OpCrossWorkgroupCastToPtrINTEL = 5938,
OpReadPipeBlockingINTEL = 5946,
@ -2069,6 +2201,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;
case OpSDot: *hasResult = true; *hasResultType = true; break;
case OpUDot: *hasResult = true; *hasResultType = true; break;
case OpSUDot: *hasResult = true; *hasResultType = true; break;
case OpSDotAccSat: *hasResult = true; *hasResultType = true; break;
case OpUDotAccSat: *hasResult = true; *hasResultType = true; break;
case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
@ -2105,8 +2243,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;
case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break;
case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break;
case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break;
case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break;
case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break;
case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break;
case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break;
case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;
case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;
case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;
case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
@ -2131,7 +2276,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
@ -2263,7 +2408,59 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break;
case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;

View file

@ -111,27 +111,23 @@ public:
void addStringOperand(const char* str)
{
unsigned int word;
char* wordString = (char*)&word;
char* wordPtr = wordString;
int charCount = 0;
unsigned int word = 0;
unsigned int shiftAmount = 0;
char c;
do {
c = *(str++);
*(wordPtr++) = c;
++charCount;
if (charCount == 4) {
word |= ((unsigned int)c) << shiftAmount;
shiftAmount += 8;
if (shiftAmount == 32) {
addImmediateOperand(word);
wordPtr = wordString;
charCount = 0;
word = 0;
shiftAmount = 0;
}
} while (c != 0);
// deal with partial last word
if (charCount > 0) {
// pad with 0s
for (; charCount < 4; ++charCount)
*(wordPtr++) = 0;
if (shiftAmount > 0) {
addImmediateOperand(word);
}
}
@ -361,6 +357,14 @@ public:
Decoration getReturnPrecision() const
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
void setDebugLineInfo(Id fileName, int line, int column) {
lineInstruction = std::unique_ptr<Instruction>{new Instruction(OpLine)};
lineInstruction->addIdOperand(fileName);
lineInstruction->addImmediateOperand(line);
lineInstruction->addImmediateOperand(column);
}
bool hasDebugLineInfo() const { return lineInstruction != nullptr; }
void setImplicitThis() { implicitThis = true; }
bool hasImplicitThis() const { return implicitThis; }
@ -377,6 +381,11 @@ public:
void dump(std::vector<unsigned int>& out) const
{
// OpLine
if (lineInstruction != nullptr) {
lineInstruction->dump(out);
}
// OpFunction
functionInstruction.dump(out);
@ -395,6 +404,7 @@ protected:
Function& operator=(Function&);
Module& parent;
std::unique_ptr<Instruction> lineInstruction;
Instruction functionInstruction;
std::vector<Instruction*> parameterInstructions;
std::vector<Block*> blocks;
@ -461,7 +471,8 @@ protected:
// - the OpFunction instruction
// - all the OpFunctionParameter instructions
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false),
: parent(parent), lineInstruction(nullptr),
functionInstruction(id, resultType, OpFunction), implicitThis(false),
reducedPrecisionReturn(false)
{
// OpFunction

View file

@ -27,111 +27,111 @@
#include <GlslangToSpv.h>
static const TBuiltInResource DefaultTBuiltInResource = {
/* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32,
/* .MaxTextureCoords = */ 32,
/* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 4096,
/* .MaxVaryingFloats = */ 64,
/* .MaxVertexTextureImageUnits = */ 32,
/* .MaxCombinedTextureImageUnits = */ 80,
/* .MaxTextureImageUnits = */ 32,
/* .MaxFragmentUniformComponents = */ 4096,
/* .MaxDrawBuffers = */ 32,
/* .MaxVertexUniformVectors = */ 128,
/* .MaxVaryingVectors = */ 8,
/* .MaxFragmentUniformVectors = */ 16,
/* .MaxVertexOutputVectors = */ 16,
/* .MaxFragmentInputVectors = */ 15,
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 16,
/* .MaxComputeImageUniforms = */ 8,
/* .MaxComputeAtomicCounters = */ 8,
/* .MaxComputeAtomicCounterBuffers = */ 1,
/* .MaxVaryingComponents = */ 60,
/* .MaxVertexOutputComponents = */ 64,
/* .MaxGeometryInputComponents = */ 64,
/* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 128,
/* .MaxImageUnits = */ 8,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
/* .MaxCombinedShaderOutputResources = */ 8,
/* .MaxImageSamples = */ 0,
/* .MaxVertexImageUniforms = */ 0,
/* .MaxTessControlImageUniforms = */ 0,
/* .MaxTessEvaluationImageUniforms = */ 0,
/* .MaxGeometryImageUniforms = */ 0,
/* .MaxFragmentImageUniforms = */ 8,
/* .MaxCombinedImageUniforms = */ 8,
/* .MaxGeometryTextureImageUnits = */ 16,
/* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 16,
/* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 0,
/* .MaxTessControlAtomicCounters = */ 0,
/* .MaxTessEvaluationAtomicCounters = */ 0,
/* .MaxGeometryAtomicCounters = */ 0,
/* .MaxFragmentAtomicCounters = */ 8,
/* .MaxCombinedAtomicCounters = */ 8,
/* .MaxAtomicCounterBindings = */ 1,
/* .MaxVertexAtomicCounterBuffers = */ 0,
/* .MaxTessControlAtomicCounterBuffers = */ 0,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
/* .MaxGeometryAtomicCounterBuffers = */ 0,
/* .MaxFragmentAtomicCounterBuffers = */ 1,
/* .MaxCombinedAtomicCounterBuffers = */ 1,
/* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 4,
/* .maxMeshOutputVerticesNV = */ 256,
/* .maxMeshOutputPrimitivesNV = */ 512,
/* .maxMeshWorkGroupSizeX_NV = */ 32,
/* .maxMeshWorkGroupSizeY_NV = */ 1,
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
/* .maxTaskWorkGroupSizeX_NV = */ 32,
/* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 1,
/* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32,
/* .MaxTextureCoords = */ 32,
/* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 4096,
/* .MaxVaryingFloats = */ 64,
/* .MaxVertexTextureImageUnits = */ 32,
/* .MaxCombinedTextureImageUnits = */ 80,
/* .MaxTextureImageUnits = */ 32,
/* .MaxFragmentUniformComponents = */ 4096,
/* .MaxDrawBuffers = */ 32,
/* .MaxVertexUniformVectors = */ 128,
/* .MaxVaryingVectors = */ 8,
/* .MaxFragmentUniformVectors = */ 16,
/* .MaxVertexOutputVectors = */ 16,
/* .MaxFragmentInputVectors = */ 15,
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 16,
/* .MaxComputeImageUniforms = */ 8,
/* .MaxComputeAtomicCounters = */ 8,
/* .MaxComputeAtomicCounterBuffers = */ 1,
/* .MaxVaryingComponents = */ 60,
/* .MaxVertexOutputComponents = */ 64,
/* .MaxGeometryInputComponents = */ 64,
/* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 128,
/* .MaxImageUnits = */ 8,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
/* .MaxCombinedShaderOutputResources = */ 8,
/* .MaxImageSamples = */ 0,
/* .MaxVertexImageUniforms = */ 0,
/* .MaxTessControlImageUniforms = */ 0,
/* .MaxTessEvaluationImageUniforms = */ 0,
/* .MaxGeometryImageUniforms = */ 0,
/* .MaxFragmentImageUniforms = */ 8,
/* .MaxCombinedImageUniforms = */ 8,
/* .MaxGeometryTextureImageUnits = */ 16,
/* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 16,
/* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 0,
/* .MaxTessControlAtomicCounters = */ 0,
/* .MaxTessEvaluationAtomicCounters = */ 0,
/* .MaxGeometryAtomicCounters = */ 0,
/* .MaxFragmentAtomicCounters = */ 8,
/* .MaxCombinedAtomicCounters = */ 8,
/* .MaxAtomicCounterBindings = */ 1,
/* .MaxVertexAtomicCounterBuffers = */ 0,
/* .MaxTessControlAtomicCounterBuffers = */ 0,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
/* .MaxGeometryAtomicCounterBuffers = */ 0,
/* .MaxFragmentAtomicCounterBuffers = */ 1,
/* .MaxCombinedAtomicCounterBuffers = */ 1,
/* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 4,
/* .maxMeshOutputVerticesNV = */ 256,
/* .maxMeshOutputPrimitivesNV = */ 512,
/* .maxMeshWorkGroupSizeX_NV = */ 32,
/* .maxMeshWorkGroupSizeY_NV = */ 1,
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
/* .maxTaskWorkGroupSizeX_NV = */ 32,
/* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ {
/* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1,
/* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1,
}
/* .limits = */ {
/* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1,
/* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1,
}
};
ShaderBuilder::ShaderBuilder()

View file

@ -352,7 +352,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
vec3 origin = pixelpos.xyz;
vec3 direction = normalize(lightpos.xyz - pixelpos.xyz);
float lightDistance = distance(pixelpos.xyz, lightpos.xyz);
/*
/*
rayQueryEXT rayQuery;
rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, lightDistance);
@ -364,7 +364,8 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
{
return 0.0;
}
*/
*/
return 1.0;
}