mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-18 02:01:18 +00:00
Upgrade glslang to 11.10.0
This commit is contained in:
parent
32d059e432
commit
5cc21c5a4a
53 changed files with 5696 additions and 4693 deletions
|
@ -263,6 +263,7 @@ enum TBuiltInVariable {
|
||||||
EbvObjectRayDirection,
|
EbvObjectRayDirection,
|
||||||
EbvRayTmin,
|
EbvRayTmin,
|
||||||
EbvRayTmax,
|
EbvRayTmax,
|
||||||
|
EbvCullMask,
|
||||||
EbvHitT,
|
EbvHitT,
|
||||||
EbvHitKind,
|
EbvHitKind,
|
||||||
EbvObjectToWorld,
|
EbvObjectToWorld,
|
||||||
|
@ -274,6 +275,8 @@ enum TBuiltInVariable {
|
||||||
// barycentrics
|
// barycentrics
|
||||||
EbvBaryCoordNV,
|
EbvBaryCoordNV,
|
||||||
EbvBaryCoordNoPerspNV,
|
EbvBaryCoordNoPerspNV,
|
||||||
|
EbvBaryCoordEXT,
|
||||||
|
EbvBaryCoordNoPerspEXT,
|
||||||
// mesh shaders
|
// mesh shaders
|
||||||
EbvTaskCountNV,
|
EbvTaskCountNV,
|
||||||
EbvPrimitiveCountNV,
|
EbvPrimitiveCountNV,
|
||||||
|
@ -478,8 +481,10 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvWorldToObject: return "WorldToObjectNV";
|
case EbvWorldToObject: return "WorldToObjectNV";
|
||||||
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
|
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
|
||||||
|
|
||||||
case EbvBaryCoordNV: return "BaryCoordNV";
|
case EbvBaryCoordEXT:
|
||||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case EbvBaryCoordNV: return "BaryCoordKHR";
|
||||||
|
case EbvBaryCoordNoPerspEXT:
|
||||||
|
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspKHR";
|
||||||
|
|
||||||
case EbvTaskCountNV: return "TaskCountNV";
|
case EbvTaskCountNV: return "TaskCountNV";
|
||||||
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
|
|
|
@ -39,6 +39,11 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <cfloat>
|
||||||
|
#else
|
||||||
|
#include <cmath>
|
||||||
|
#endif
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -61,7 +66,7 @@ std::string to_string(const T& val) {
|
||||||
}
|
}
|
||||||
#endif
|
#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>
|
#include <basetsd.h>
|
||||||
#ifndef snprintf
|
#ifndef snprintf
|
||||||
#define snprintf sprintf_s
|
#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.
|
// 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)
|
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
|
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;
|
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
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _COMMON_INCLUDED_
|
#endif // _COMMON_INCLUDED_
|
||||||
|
|
|
@ -306,6 +306,8 @@ public:
|
||||||
|
|
||||||
TPoolAllocator& getAllocator() const { return allocator; }
|
TPoolAllocator& getAllocator() const { return allocator; }
|
||||||
|
|
||||||
|
pool_allocator select_on_container_copy_construction() const { return pool_allocator{}; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
pool_allocator& operator=(const pool_allocator&) { return *this; }
|
pool_allocator& operator=(const pool_allocator&) { return *this; }
|
||||||
TPoolAllocator& allocator;
|
TPoolAllocator& allocator;
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct TSpirvExecutionMode {
|
||||||
// spirv_execution_mode
|
// spirv_execution_mode
|
||||||
TMap<int, TVector<const TIntermConstantUnion*>> modes;
|
TMap<int, TVector<const TIntermConstantUnion*>> modes;
|
||||||
// spirv_execution_mode_id
|
// spirv_execution_mode_id
|
||||||
TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
|
TMap<int, TVector<const TIntermTyped*> > modeIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SPIR-V decorations
|
// SPIR-V decorations
|
||||||
|
@ -75,7 +75,7 @@ struct TSpirvDecorate {
|
||||||
// spirv_decorate
|
// spirv_decorate
|
||||||
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
|
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
|
||||||
// spirv_decorate_id
|
// spirv_decorate_id
|
||||||
TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
|
TMap<int, TVector<const TIntermTyped*>> decorateIds;
|
||||||
// spirv_decorate_string
|
// spirv_decorate_string
|
||||||
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
|
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
|
||||||
};
|
};
|
||||||
|
@ -98,20 +98,12 @@ struct TSpirvInstruction {
|
||||||
struct TSpirvTypeParameter {
|
struct TSpirvTypeParameter {
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
|
||||||
TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
|
TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; }
|
||||||
TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
|
|
||||||
|
|
||||||
bool operator==(const TSpirvTypeParameter& rhs) const
|
bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; }
|
||||||
{
|
|
||||||
return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
|
|
||||||
}
|
|
||||||
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
|
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
|
||||||
|
|
||||||
bool isConstant;
|
const TIntermConstantUnion* constant;
|
||||||
union {
|
|
||||||
const TIntermConstantUnion* constant;
|
|
||||||
const TType* type;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
|
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
|
||||||
|
|
|
@ -552,6 +552,7 @@ public:
|
||||||
perViewNV = false;
|
perViewNV = false;
|
||||||
perTaskNV = false;
|
perTaskNV = false;
|
||||||
#endif
|
#endif
|
||||||
|
pervertexEXT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearMemory()
|
void clearMemory()
|
||||||
|
@ -604,7 +605,8 @@ public:
|
||||||
bool isNoContraction() const { return false; }
|
bool isNoContraction() const { return false; }
|
||||||
void setNoContraction() { }
|
void setNoContraction() { }
|
||||||
bool isPervertexNV() const { return false; }
|
bool isPervertexNV() const { return false; }
|
||||||
void setNullInit() { }
|
bool isPervertexEXT() const { return pervertexEXT; }
|
||||||
|
void setNullInit() {}
|
||||||
bool isNullInit() const { return false; }
|
bool isNullInit() const { return false; }
|
||||||
void setSpirvByReference() { }
|
void setSpirvByReference() { }
|
||||||
bool isSpirvByReference() { return false; }
|
bool isSpirvByReference() { return false; }
|
||||||
|
@ -615,6 +617,7 @@ public:
|
||||||
bool nopersp : 1;
|
bool nopersp : 1;
|
||||||
bool explicitInterp : 1;
|
bool explicitInterp : 1;
|
||||||
bool pervertexNV : 1;
|
bool pervertexNV : 1;
|
||||||
|
bool pervertexEXT : 1;
|
||||||
bool perPrimitiveNV : 1;
|
bool perPrimitiveNV : 1;
|
||||||
bool perViewNV : 1;
|
bool perViewNV : 1;
|
||||||
bool perTaskNV : 1;
|
bool perTaskNV : 1;
|
||||||
|
@ -663,12 +666,13 @@ public:
|
||||||
}
|
}
|
||||||
bool isAuxiliary() const
|
bool isAuxiliary() const
|
||||||
{
|
{
|
||||||
return centroid || patch || sample || pervertexNV;
|
return centroid || patch || sample || pervertexNV || pervertexEXT;
|
||||||
}
|
}
|
||||||
bool isPatch() const { return patch; }
|
bool isPatch() const { return patch; }
|
||||||
bool isNoContraction() const { return noContraction; }
|
bool isNoContraction() const { return noContraction; }
|
||||||
void setNoContraction() { noContraction = true; }
|
void setNoContraction() { noContraction = true; }
|
||||||
bool isPervertexNV() const { return pervertexNV; }
|
bool isPervertexNV() const { return pervertexNV; }
|
||||||
|
bool isPervertexEXT() const { return pervertexEXT; }
|
||||||
void setNullInit() { nullInit = true; }
|
void setNullInit() { nullInit = true; }
|
||||||
bool isNullInit() const { return nullInit; }
|
bool isNullInit() const { return nullInit; }
|
||||||
void setSpirvByReference() { spirvByReference = true; }
|
void setSpirvByReference() { spirvByReference = true; }
|
||||||
|
@ -741,6 +745,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUniform() const
|
||||||
|
{
|
||||||
|
switch (storage) {
|
||||||
|
case EvqUniform:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isIo() const
|
bool isIo() const
|
||||||
{
|
{
|
||||||
switch (storage) {
|
switch (storage) {
|
||||||
|
@ -846,7 +860,7 @@ public:
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
return ! patch && isPipeInput();
|
return ! patch && isPipeInput();
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
return pervertexNV && isPipeInput();
|
return (pervertexNV || pervertexEXT) && isPipeInput();
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
return ! perTaskNV && isPipeOutput();
|
return ! perTaskNV && isPipeOutput();
|
||||||
|
|
||||||
|
@ -1855,10 +1869,12 @@ public:
|
||||||
bool isAtomic() const { return false; }
|
bool isAtomic() const { return false; }
|
||||||
bool isCoopMat() const { return false; }
|
bool isCoopMat() const { return false; }
|
||||||
bool isReference() const { return false; }
|
bool isReference() const { return false; }
|
||||||
|
bool isSpirvType() const { return false; }
|
||||||
#else
|
#else
|
||||||
bool isAtomic() const { return basicType == EbtAtomicUint; }
|
bool isAtomic() const { return basicType == EbtAtomicUint; }
|
||||||
bool isCoopMat() const { return coopmat; }
|
bool isCoopMat() const { return coopmat; }
|
||||||
bool isReference() const { return getBasicType() == EbtReference; }
|
bool isReference() const { return getBasicType() == EbtReference; }
|
||||||
|
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// return true if this type contains any subtype which satisfies the given predicate.
|
// return true if this type contains any subtype which satisfies the given predicate.
|
||||||
|
@ -2130,7 +2146,8 @@ public:
|
||||||
const char* getPrecisionQualifierString() const { return ""; }
|
const char* getPrecisionQualifierString() const { return ""; }
|
||||||
TString getBasicTypeString() const { return ""; }
|
TString getBasicTypeString() const { return ""; }
|
||||||
#else
|
#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;
|
TString typeString;
|
||||||
|
|
||||||
|
@ -2138,232 +2155,337 @@ public:
|
||||||
const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
|
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()); };
|
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());
|
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
|
||||||
|
|
||||||
if (qualifier.hasLayout()) {
|
if (qualifier.hasLayout()) {
|
||||||
// To reduce noise, skip this if the only layout is an xfb_buffer
|
// To reduce noise, skip this if the only layout is an xfb_buffer
|
||||||
// with no triggering xfb_offset.
|
// with no triggering xfb_offset.
|
||||||
TQualifier noXfbBuffer = qualifier;
|
TQualifier noXfbBuffer = qualifier;
|
||||||
noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
|
noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
|
||||||
if (noXfbBuffer.hasLayout()) {
|
if (noXfbBuffer.hasLayout()) {
|
||||||
appendStr("layout(");
|
appendStr("layout(");
|
||||||
if (qualifier.hasAnyLocation()) {
|
if (qualifier.hasAnyLocation()) {
|
||||||
appendStr(" location=");
|
appendStr(" location=");
|
||||||
appendUint(qualifier.layoutLocation);
|
appendUint(qualifier.layoutLocation);
|
||||||
if (qualifier.hasComponent()) {
|
if (qualifier.hasComponent()) {
|
||||||
appendStr(" component=");
|
appendStr(" component=");
|
||||||
appendUint(qualifier.layoutComponent);
|
appendUint(qualifier.layoutComponent);
|
||||||
}
|
|
||||||
if (qualifier.hasIndex()) {
|
|
||||||
appendStr(" index=");
|
|
||||||
appendUint(qualifier.layoutIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (qualifier.hasSet()) {
|
if (qualifier.hasIndex()) {
|
||||||
appendStr(" set=");
|
appendStr(" index=");
|
||||||
appendUint(qualifier.layoutSet);
|
appendUint(qualifier.layoutIndex);
|
||||||
}
|
|
||||||
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.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)
|
if (qualifier.layoutPassthrough)
|
||||||
appendStr(" passthrough");
|
appendStr(" passthrough");
|
||||||
if (qualifier.layoutViewportRelative)
|
if (qualifier.layoutViewportRelative)
|
||||||
appendStr(" layoutViewportRelative");
|
appendStr(" layoutViewportRelative");
|
||||||
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
|
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
|
||||||
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
||||||
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
||||||
}
|
}
|
||||||
if (qualifier.layoutShaderRecord)
|
if (qualifier.layoutShaderRecord)
|
||||||
appendStr(" shaderRecordNV");
|
appendStr(" shaderRecordNV");
|
||||||
|
|
||||||
appendStr(")");
|
appendStr(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qualifier.invariant)
|
if (qualifier.invariant)
|
||||||
appendStr(" invariant");
|
appendStr(" invariant");
|
||||||
if (qualifier.noContraction)
|
if (qualifier.noContraction)
|
||||||
appendStr(" noContraction");
|
appendStr(" noContraction");
|
||||||
if (qualifier.centroid)
|
if (qualifier.centroid)
|
||||||
appendStr(" centroid");
|
appendStr(" centroid");
|
||||||
if (qualifier.smooth)
|
if (qualifier.smooth)
|
||||||
appendStr(" smooth");
|
appendStr(" smooth");
|
||||||
if (qualifier.flat)
|
if (qualifier.flat)
|
||||||
appendStr(" flat");
|
appendStr(" flat");
|
||||||
if (qualifier.nopersp)
|
if (qualifier.nopersp)
|
||||||
appendStr(" noperspective");
|
appendStr(" noperspective");
|
||||||
if (qualifier.explicitInterp)
|
if (qualifier.explicitInterp)
|
||||||
appendStr(" __explicitInterpAMD");
|
appendStr(" __explicitInterpAMD");
|
||||||
if (qualifier.pervertexNV)
|
if (qualifier.pervertexNV)
|
||||||
appendStr(" pervertexNV");
|
appendStr(" pervertexNV");
|
||||||
if (qualifier.perPrimitiveNV)
|
if (qualifier.pervertexEXT)
|
||||||
|
appendStr(" pervertexEXT");
|
||||||
|
if (qualifier.perPrimitiveNV)
|
||||||
appendStr(" perprimitiveNV");
|
appendStr(" perprimitiveNV");
|
||||||
if (qualifier.perViewNV)
|
if (qualifier.perViewNV)
|
||||||
appendStr(" perviewNV");
|
appendStr(" perviewNV");
|
||||||
if (qualifier.perTaskNV)
|
if (qualifier.perTaskNV)
|
||||||
appendStr(" taskNV");
|
appendStr(" taskNV");
|
||||||
if (qualifier.patch)
|
if (qualifier.patch)
|
||||||
appendStr(" patch");
|
appendStr(" patch");
|
||||||
if (qualifier.sample)
|
if (qualifier.sample)
|
||||||
appendStr(" sample");
|
appendStr(" sample");
|
||||||
if (qualifier.coherent)
|
if (qualifier.coherent)
|
||||||
appendStr(" coherent");
|
appendStr(" coherent");
|
||||||
if (qualifier.devicecoherent)
|
if (qualifier.devicecoherent)
|
||||||
appendStr(" devicecoherent");
|
appendStr(" devicecoherent");
|
||||||
if (qualifier.queuefamilycoherent)
|
if (qualifier.queuefamilycoherent)
|
||||||
appendStr(" queuefamilycoherent");
|
appendStr(" queuefamilycoherent");
|
||||||
if (qualifier.workgroupcoherent)
|
if (qualifier.workgroupcoherent)
|
||||||
appendStr(" workgroupcoherent");
|
appendStr(" workgroupcoherent");
|
||||||
if (qualifier.subgroupcoherent)
|
if (qualifier.subgroupcoherent)
|
||||||
appendStr(" subgroupcoherent");
|
appendStr(" subgroupcoherent");
|
||||||
if (qualifier.shadercallcoherent)
|
if (qualifier.shadercallcoherent)
|
||||||
appendStr(" shadercallcoherent");
|
appendStr(" shadercallcoherent");
|
||||||
if (qualifier.nonprivate)
|
if (qualifier.nonprivate)
|
||||||
appendStr(" nonprivate");
|
appendStr(" nonprivate");
|
||||||
if (qualifier.volatil)
|
if (qualifier.volatil)
|
||||||
appendStr(" volatile");
|
appendStr(" volatile");
|
||||||
if (qualifier.restrict)
|
if (qualifier.restrict)
|
||||||
appendStr(" restrict");
|
appendStr(" restrict");
|
||||||
if (qualifier.readonly)
|
if (qualifier.readonly)
|
||||||
appendStr(" readonly");
|
appendStr(" readonly");
|
||||||
if (qualifier.writeonly)
|
if (qualifier.writeonly)
|
||||||
appendStr(" writeonly");
|
appendStr(" writeonly");
|
||||||
if (qualifier.specConstant)
|
if (qualifier.specConstant)
|
||||||
appendStr(" specialization-constant");
|
appendStr(" specialization-constant");
|
||||||
if (qualifier.nonUniform)
|
if (qualifier.nonUniform)
|
||||||
appendStr(" nonuniform");
|
appendStr(" nonuniform");
|
||||||
if (qualifier.isNullInit())
|
if (qualifier.isNullInit())
|
||||||
appendStr(" null-init");
|
appendStr(" null-init");
|
||||||
if (qualifier.isSpirvByReference())
|
if (qualifier.isSpirvByReference())
|
||||||
appendStr(" spirv_by_reference");
|
appendStr(" spirv_by_reference");
|
||||||
if (qualifier.isSpirvLiteral())
|
if (qualifier.isSpirvLiteral())
|
||||||
appendStr(" spirv_literal");
|
appendStr(" spirv_literal");
|
||||||
appendStr(" ");
|
appendStr(" ");
|
||||||
appendStr(getStorageQualifierString());
|
appendStr(getStorageQualifierString());
|
||||||
if (isArray()) {
|
}
|
||||||
for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
|
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);
|
int size = arraySizes->getDimSize(i);
|
||||||
if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
|
if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
|
||||||
appendStr(" runtime-sized array of");
|
appendStr("[]");
|
||||||
else {
|
else {
|
||||||
if (size == UnsizedArraySize) {
|
if (size == UnsizedArraySize) {
|
||||||
appendStr(" unsized");
|
appendStr("[");
|
||||||
if (i == 0) {
|
if (i == 0)
|
||||||
appendStr(" ");
|
appendInt(arraySizes->getImplicitSize());
|
||||||
appendInt(arraySizes->getImplicitSize());
|
appendStr("]");
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
appendStr(" ");
|
appendStr("[");
|
||||||
appendInt(arraySizes->getDimSize(i));
|
appendInt(arraySizes->getDimSize(i));
|
||||||
}
|
appendStr("]");
|
||||||
appendStr("-element array of");
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isParameterized()) {
|
else {
|
||||||
appendStr("<");
|
if (isArray()) {
|
||||||
for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) {
|
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));
|
appendInt(typeParameters->getDimSize(i));
|
||||||
if (i != (int)typeParameters->getNumDims() - 1)
|
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(", ");
|
||||||
}
|
typeString.append((*structure)[i].type->getCompleteString());
|
||||||
appendStr(">");
|
typeString.append(" ");
|
||||||
}
|
typeString.append((*structure)[i].type->getFieldName());
|
||||||
if (qualifier.precision != EpqNone) {
|
hasHiddenMember = false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
appendStr("}");
|
||||||
}
|
}
|
||||||
appendStr("}");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeString;
|
return typeString;
|
||||||
|
@ -2432,13 +2554,27 @@ public:
|
||||||
// type definitions, and member names to be considered the same type.
|
// type definitions, and member names to be considered the same type.
|
||||||
// This rule applies recursively for nested or embedded types."
|
// 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
|
// 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()) ||
|
if ((!isStruct() && !right.isStruct()) ||
|
||||||
(isStruct() && right.isStruct() && structure == right.structure))
|
(isStruct() && right.isStruct() && structure == right.structure))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!isStruct() || !right.isStruct())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Structure names have to match
|
// Structure names have to match
|
||||||
if (*typeName != *right.typeName)
|
if (*typeName != *right.typeName)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2448,17 +2584,30 @@ public:
|
||||||
bool isGLPerVertex = *typeName == "gl_PerVertex";
|
bool isGLPerVertex = *typeName == "gl_PerVertex";
|
||||||
|
|
||||||
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
||||||
if (!isStruct() || !right.isStruct() ||
|
if (lpidx == nullptr &&
|
||||||
(structure->size() != right.structure->size() && !isGLPerVertex))
|
(structure->size() != right.structure->size() && !isGLPerVertex)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Compare the names and types of all the members, which have to match
|
// 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) {
|
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 (li < structure->size() && ri < right.structure->size()) {
|
||||||
if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) {
|
if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) {
|
||||||
if (*(*structure)[li].type != *(*right.structure)[ri].type)
|
if (*(*structure)[li].type != *(*right.structure)[ri].type)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} 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
|
// If one of the members is something that's inconsistently declared, skip over it
|
||||||
// for now.
|
// for now.
|
||||||
if (isGLPerVertex) {
|
if (isGLPerVertex) {
|
||||||
|
@ -2475,11 +2624,19 @@ public:
|
||||||
}
|
}
|
||||||
// If we get here, then there should only be inconsistently declared members left
|
// If we get here, then there should only be inconsistently declared members left
|
||||||
} else if (li < structure->size()) {
|
} 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;
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} 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;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2503,10 +2660,15 @@ public:
|
||||||
return *referentType == *right.referentType;
|
return *referentType == *right.referentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if two types match, in all aspects except arrayness
|
// See if two types match, in all aspects except arrayness
|
||||||
bool sameElementType(const TType& right) const
|
// 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
|
// See if two type's arrayness match
|
||||||
|
@ -2540,15 +2702,20 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// See if two type's elements match in all ways except basic type
|
// 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 &&
|
vectorSize == right.vectorSize &&
|
||||||
matrixCols == right.matrixCols &&
|
matrixCols == right.matrixCols &&
|
||||||
matrixRows == right.matrixRows &&
|
matrixRows == right.matrixRows &&
|
||||||
vector1 == right.vector1 &&
|
vector1 == right.vector1 &&
|
||||||
isCoopMat() == right.isCoopMat() &&
|
isCoopMat() == right.isCoopMat() &&
|
||||||
sameStructType(right) &&
|
sameStructType(right, lpidx, rpidx) &&
|
||||||
sameReferenceType(right);
|
sameReferenceType(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define GLSLANG_BUILD_INFO
|
#define GLSLANG_BUILD_INFO
|
||||||
|
|
||||||
#define GLSLANG_VERSION_MAJOR 11
|
#define GLSLANG_VERSION_MAJOR 11
|
||||||
#define GLSLANG_VERSION_MINOR 6
|
#define GLSLANG_VERSION_MINOR 10
|
||||||
#define GLSLANG_VERSION_PATCH 0
|
#define GLSLANG_VERSION_PATCH 0
|
||||||
#define GLSLANG_VERSION_FLAVOR ""
|
#define GLSLANG_VERSION_FLAVOR ""
|
||||||
|
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ public:
|
||||||
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
||||||
bool isAtomic() const { return type.isAtomic(); }
|
bool isAtomic() const { return type.isAtomic(); }
|
||||||
bool isReference() const { return type.isReference(); }
|
bool isReference() const { return type.isReference(); }
|
||||||
TString getCompleteString() const { return type.getCompleteString(); }
|
TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped& operator=(const TIntermTyped&);
|
TIntermTyped& operator=(const TIntermTyped&);
|
||||||
|
@ -1643,6 +1643,7 @@ public:
|
||||||
~TIntermAggregate() { delete pragmaTable; }
|
~TIntermAggregate() { delete pragmaTable; }
|
||||||
virtual TIntermAggregate* getAsAggregate() { return this; }
|
virtual TIntermAggregate* getAsAggregate() { return this; }
|
||||||
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
||||||
|
virtual void updatePrecision();
|
||||||
virtual void setOperator(TOperator o) { op = o; }
|
virtual void setOperator(TOperator o) { op = o; }
|
||||||
virtual TIntermSequence& getSequence() { return sequence; }
|
virtual TIntermSequence& getSequence() { return sequence; }
|
||||||
virtual const TIntermSequence& getSequence() const { return sequence; }
|
virtual const TIntermSequence& getSequence() const { return sequence; }
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
// This header is generated by the make-revision script.
|
|
||||||
|
|
||||||
#define GLSLANG_PATCH_LEVEL 3559
|
|
|
@ -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$"
|
|
|
@ -42,43 +42,10 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace glslang;
|
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;
|
const double pi = 3.1415926535897932384626433832795;
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
@ -535,7 +502,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||||
// Note: avoid UBSAN error regarding negating 0x80000000
|
// Note: avoid UBSAN error regarding negating 0x80000000
|
||||||
case EbtInt: newConstArray[i].setIConst(
|
case EbtInt: newConstArray[i].setIConst(
|
||||||
unionArray[i].getIConst() == 0x80000000
|
static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
|
||||||
? -0x7FFFFFFF - 1
|
? -0x7FFFFFFF - 1
|
||||||
: -unionArray[i].getIConst());
|
: -unionArray[i].getIConst());
|
||||||
break;
|
break;
|
||||||
|
@ -667,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
|
|
||||||
case EOpIsNan:
|
case EOpIsNan:
|
||||||
{
|
{
|
||||||
newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
|
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOpIsInf:
|
case EOpIsInf:
|
||||||
{
|
{
|
||||||
newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
|
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2020 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// 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.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -316,6 +316,7 @@ const CustomFunction CustomFunctions[] = {
|
||||||
|
|
||||||
{ EOpTextureQuerySize, "textureSize", nullptr },
|
{ EOpTextureQuerySize, "textureSize", nullptr },
|
||||||
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
|
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
|
||||||
|
{ EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
|
||||||
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
|
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
|
||||||
{ EOpTextureQuerySamples, "textureSamples", nullptr },
|
{ EOpTextureQuerySamples, "textureSamples", nullptr },
|
||||||
{ EOpTexture, "texture", nullptr },
|
{ EOpTexture, "texture", nullptr },
|
||||||
|
@ -4159,106 +4160,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||||
"u16vec4 unpack16(uint64_t);"
|
"u16vec4 unpack16(uint64_t);"
|
||||||
"i32vec2 unpack32(int64_t);"
|
"i32vec2 unpack32(int64_t);"
|
||||||
"u32vec2 unpack32(uint64_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");
|
"\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(
|
stageBuiltins[EShLangGeometry].append(
|
||||||
"void EmitStreamVertex(int);"
|
"void EmitStreamVertex(int);"
|
||||||
"void EndStreamPrimitive(int);"
|
"void EndStreamPrimitive(int);"
|
||||||
|
@ -4653,7 +4554,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// GL_ARB_shader_clock & GL_EXT_shader_realtime_clock
|
// GL_ARB_shader_clock& GL_EXT_shader_realtime_clock
|
||||||
if (profile != EEsProfile && version >= 450) {
|
if (profile != EEsProfile && version >= 450) {
|
||||||
commonBuiltins.append(
|
commonBuiltins.append(
|
||||||
"uvec2 clock2x32ARB();"
|
"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(
|
stageBuiltins[EShLangVertex].append(
|
||||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version >= 450)
|
||||||
|
stageBuiltins[EShLangVertex].append(
|
||||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
"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;"
|
"in int gl_InvocationID;"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (version >= 450)
|
if (version >= 430)
|
||||||
stageBuiltins[EShLangGeometry].append(
|
stageBuiltins[EShLangGeometry].append(
|
||||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version >= 450)
|
||||||
|
stageBuiltins[EShLangGeometry].append(
|
||||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
"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)
|
if (version >= 450)
|
||||||
stageBuiltins[EShLangTessControl].append(
|
stageBuiltins[EShLangTessControl].append(
|
||||||
"float gl_CullDistance[];"
|
"float gl_CullDistance[];"
|
||||||
|
);
|
||||||
|
if (version >= 430)
|
||||||
|
stageBuiltins[EShLangTessControl].append(
|
||||||
"int gl_ViewportMask[];" // GL_NV_viewport_array2
|
"int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
|
);
|
||||||
|
if (version >= 450)
|
||||||
|
stageBuiltins[EShLangTessControl].append(
|
||||||
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
"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;"
|
"out int gl_Layer;"
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
if (version >= 450)
|
if (version >= 430)
|
||||||
stageBuiltins[EShLangTessEvaluation].append(
|
stageBuiltins[EShLangTessEvaluation].append(
|
||||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version >= 450)
|
||||||
|
stageBuiltins[EShLangTessEvaluation].append(
|
||||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
"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;"
|
"flat in int gl_InvocationsPerPixelNV;"
|
||||||
"in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric
|
"in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric
|
||||||
"in vec3 gl_BaryCoordNoPerspNV;"
|
"in vec3 gl_BaryCoordNoPerspNV;"
|
||||||
|
"in vec3 gl_BaryCoordEXT;" // GL_EXT_fragment_shader_barycentric
|
||||||
|
"in vec3 gl_BaryCoordNoPerspEXT;"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (version >= 450)
|
if (version >= 450)
|
||||||
|
@ -5716,7 +5637,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||||
stageBuiltins[EShLangFragment].append(
|
stageBuiltins[EShLangFragment].append(
|
||||||
"in vec3 gl_BaryCoordNV;"
|
"in vec3 gl_BaryCoordNV;"
|
||||||
"in vec3 gl_BaryCoordNoPerspNV;"
|
"in vec3 gl_BaryCoordNoPerspNV;"
|
||||||
);
|
"in vec3 gl_BaryCoordEXT;"
|
||||||
|
"in vec3 gl_BaryCoordNoPerspEXT;"
|
||||||
|
);
|
||||||
if (version >= 310)
|
if (version >= 310)
|
||||||
stageBuiltins[EShLangFragment].append(
|
stageBuiltins[EShLangFragment].append(
|
||||||
"flat in highp int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate
|
"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_IncomingRayFlagsNV;"
|
||||||
"in uint gl_IncomingRayFlagsEXT;"
|
"in uint gl_IncomingRayFlagsEXT;"
|
||||||
"in float gl_CurrentRayTimeNV;"
|
"in float gl_CurrentRayTimeNV;"
|
||||||
|
"in uint gl_CullMaskEXT;"
|
||||||
"\n";
|
"\n";
|
||||||
const char *hitDecls =
|
const char *hitDecls =
|
||||||
"in uvec3 gl_LaunchIDNV;"
|
"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_IncomingRayFlagsNV;"
|
||||||
"in uint gl_IncomingRayFlagsEXT;"
|
"in uint gl_IncomingRayFlagsEXT;"
|
||||||
"in float gl_CurrentRayTimeNV;"
|
"in float gl_CurrentRayTimeNV;"
|
||||||
|
"in uint gl_CullMaskEXT;"
|
||||||
"\n";
|
"\n";
|
||||||
const char *missDecls =
|
const char *missDecls =
|
||||||
"in uvec3 gl_LaunchIDNV;"
|
"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_IncomingRayFlagsNV;"
|
||||||
"in uint gl_IncomingRayFlagsEXT;"
|
"in uint gl_IncomingRayFlagsEXT;"
|
||||||
"in float gl_CurrentRayTimeNV;"
|
"in float gl_CurrentRayTimeNV;"
|
||||||
|
"in uint gl_CullMaskEXT;"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
const char *callableDecls =
|
const char *callableDecls =
|
||||||
|
@ -6329,38 +6255,44 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
|
||||||
//
|
//
|
||||||
// textureQueryLod(), fragment stage only
|
// textureQueryLod(), fragment stage only
|
||||||
// Also enabled with extension GL_ARB_texture_query_lod
|
// 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 &&
|
if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect &&
|
||||||
! sampler.isMultiSample() && ! sampler.isBuffer()) {
|
! 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(");
|
const TString funcName[2] = {"vec2 textureQueryLod(", "vec2 textureQueryLOD("};
|
||||||
stageBuiltins[EShLangCompute].append(typeName);
|
|
||||||
if (dimMap[sampler.dim] == 1)
|
for (int i = 0; i < 2; ++i){
|
||||||
stageBuiltins[EShLangCompute].append(", float");
|
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
|
||||||
else {
|
if (f16TexAddr && sampler.type != EbtFloat16)
|
||||||
stageBuiltins[EShLangCompute].append(", vec");
|
continue;
|
||||||
stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
|
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;
|
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.
|
// For built-in variables inside a named block.
|
||||||
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
|
// 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) {
|
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
|
||||||
// treat these built-ins as aliases of VertexIndex and InstanceIndex
|
// treat these built-ins as aliases of VertexIndex and InstanceIndex
|
||||||
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
|
RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
|
||||||
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
|
RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile != EEsProfile) {
|
if (profile != EEsProfile) {
|
||||||
|
@ -8140,7 +8077,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile != EEsProfile && version < 400) {
|
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) {
|
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);
|
symbolTable.setVariableExtensions("gl_BaryCoordNoPerspNV", 1, &E_GL_NV_fragment_shader_barycentric);
|
||||||
BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable);
|
BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable);
|
||||||
BuiltInVariable("gl_BaryCoordNoPerspNV", EbvBaryCoordNoPerspNV, 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) ||
|
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("clockARB", 1, &E_GL_ARB_shader_clock);
|
||||||
symbolTable.setFunctionExtensions("clock2x32ARB", 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);
|
symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
|
||||||
|
|
||||||
if (profile == EEsProfile && version < 320) {
|
if (profile == EEsProfile && version < 320) {
|
||||||
|
@ -8423,10 +8364,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile != EEsProfile && version < 330 ) {
|
if (profile != EEsProfile && version < 330 ) {
|
||||||
symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding);
|
const char* bitsConvertExt[2] = {E_GL_ARB_shader_bit_encoding, E_GL_ARB_gpu_shader5};
|
||||||
symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding);
|
symbolTable.setFunctionExtensions("floatBitsToInt", 2, bitsConvertExt);
|
||||||
symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
|
symbolTable.setFunctionExtensions("floatBitsToUint", 2, bitsConvertExt);
|
||||||
symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
|
symbolTable.setFunctionExtensions("intBitsToFloat", 2, bitsConvertExt);
|
||||||
|
symbolTable.setFunctionExtensions("uintBitsToFloat", 2, bitsConvertExt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile != EEsProfile && version < 430 ) {
|
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_RayTminEXT", 1, &E_GL_EXT_ray_tracing);
|
||||||
symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_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_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_HitTNV", 1, &E_GL_NV_ray_tracing);
|
||||||
symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing);
|
symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing);
|
||||||
symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_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_RayTminEXT", EbvRayTmin, symbolTable);
|
||||||
BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable);
|
BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable);
|
||||||
BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable);
|
BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable);
|
||||||
|
BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable);
|
||||||
BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable);
|
BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable);
|
||||||
BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable);
|
BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable);
|
||||||
BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable);
|
BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable);
|
||||||
|
|
|
@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
|
||||||
// TODO: but, did this bypass constant folding?
|
// TODO: but, did this bypass constant folding?
|
||||||
//
|
//
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpConstructInt8:
|
case EOpConstructInt8:
|
||||||
case EOpConstructUint8:
|
case EOpConstructUint8:
|
||||||
case EOpConstructInt16:
|
case EOpConstructInt16:
|
||||||
case EOpConstructUint16:
|
case EOpConstructUint16:
|
||||||
case EOpConstructInt:
|
case EOpConstructInt:
|
||||||
case EOpConstructUint:
|
case EOpConstructUint:
|
||||||
case EOpConstructInt64:
|
case EOpConstructInt64:
|
||||||
case EOpConstructUint64:
|
case EOpConstructUint64:
|
||||||
case EOpConstructBool:
|
case EOpConstructBool:
|
||||||
case EOpConstructFloat:
|
case EOpConstructFloat:
|
||||||
case EOpConstructDouble:
|
case EOpConstructDouble:
|
||||||
case EOpConstructFloat16:
|
case EOpConstructFloat16: {
|
||||||
return child;
|
TIntermUnary* unary_node = child->getAsUnaryNode();
|
||||||
default: break; // some compilers want this
|
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;
|
return;
|
||||||
|
|
||||||
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
|
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
|
||||||
exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
|
exp->getBasicType() == EbtFloat) {
|
||||||
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
|
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
|
||||||
exp->propagatePrecision(parentPrecision);
|
exp->propagatePrecision(parentPrecision);
|
||||||
}
|
}
|
||||||
|
@ -3280,7 +3284,7 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
||||||
void TIntermUnary::updatePrecision()
|
void TIntermUnary::updatePrecision()
|
||||||
{
|
{
|
||||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
getBasicType() == EbtFloat) {
|
||||||
if (operand->getQualifier().precision > getQualifier().precision)
|
if (operand->getQualifier().precision > getQualifier().precision)
|
||||||
getQualifier().precision = operand->getQualifier().precision;
|
getQualifier().precision = operand->getQualifier().precision;
|
||||||
}
|
}
|
||||||
|
@ -3776,12 +3780,34 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
||||||
return false;
|
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
|
// Propagate precision qualifiers *up* from children to parent, and then
|
||||||
// back *down* again to the children's subtrees.
|
// back *down* again to the children's subtrees.
|
||||||
void TIntermBinary::updatePrecision()
|
void TIntermBinary::updatePrecision()
|
||||||
{
|
{
|
||||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
getBasicType() == EbtFloat) {
|
||||||
if (op == EOpRightShift || op == EOpLeftShift) {
|
if (op == EOpRightShift || op == EOpLeftShift) {
|
||||||
// For shifts get precision from left side only and thus no need to propagate
|
// For shifts get precision from left side only and thus no need to propagate
|
||||||
getQualifier().precision = left->getQualifier().precision;
|
getQualifier().precision = left->getQualifier().precision;
|
||||||
|
@ -3876,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
||||||
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
|
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
|
||||||
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
|
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
|
||||||
case EbtDouble: 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 EbtInt16: PROMOTE(setI16Const, short, Get); break; \
|
||||||
case EbtInt: PROMOTE(setIConst, int, Get); break; \
|
case EbtInt: PROMOTE(setIConst, int, Get); break; \
|
||||||
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
|
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
|
||||||
|
|
|
@ -74,6 +74,9 @@ void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason
|
||||||
{
|
{
|
||||||
if (messages & EShMsgOnlyPreprocessor)
|
if (messages & EShMsgOnlyPreprocessor)
|
||||||
return;
|
return;
|
||||||
|
// If enhanced msg readability, only print one error
|
||||||
|
if (messages & EShMsgEnhanced && numErrors > 0)
|
||||||
|
return;
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, szExtraInfoFormat);
|
va_start(args, szExtraInfoFormat);
|
||||||
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
|
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().layoutBinding = globalUniformBinding;
|
||||||
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
|
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.
|
// Add the requested member as a member to the global block.
|
||||||
TType* type = new TType;
|
TType* type = new TType;
|
||||||
type->shallowCopy(memberType);
|
type->shallowCopy(memberType);
|
||||||
|
|
|
@ -716,7 +716,7 @@ bool TParseContext::isIoResizeArray(const TType& type) const
|
||||||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
|
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
|
||||||
! type.getQualifier().patch) ||
|
! type.getQualifier().patch) ||
|
||||||
(language == EShLangFragment && 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 &&
|
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
|
||||||
!type.getQualifier().perTaskNV));
|
!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());
|
error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
|
||||||
else if (language == EShLangFragment) {
|
else if (language == EShLangFragment) {
|
||||||
if (type.getOuterArraySize() > requiredSize)
|
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)
|
else if (language == EShLangMeshNV)
|
||||||
error(loc, "inconsistent output array size of", feature, name.c_str());
|
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);
|
result = intermediate.addBinaryMath(op, left, right, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == nullptr)
|
if (result == nullptr) {
|
||||||
binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
|
bool enhanced = intermediate.getEnhancedMsgs();
|
||||||
|
binaryOpError(loc, str, left->getCompleteString(enhanced), right->getCompleteString(enhanced));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -926,8 +928,10 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
else
|
else {
|
||||||
unaryOpError(loc, str, childNode->getCompleteString());
|
bool enhanced = intermediate.getEnhancedMsgs();
|
||||||
|
unaryOpError(loc, str, childNode->getCompleteString(enhanced));
|
||||||
|
}
|
||||||
|
|
||||||
return childNode;
|
return childNode;
|
||||||
}
|
}
|
||||||
|
@ -953,8 +957,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
||||||
requireProfile(loc, ~EEsProfile, feature);
|
requireProfile(loc, ~EEsProfile, feature);
|
||||||
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
|
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
|
||||||
} else if (!base->getType().isCoopMat()) {
|
} 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;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,10 +1009,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
||||||
intermediate.addIoAccessed(field);
|
intermediate.addIoAccessed(field);
|
||||||
}
|
}
|
||||||
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
|
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
|
||||||
} else
|
} else {
|
||||||
error(loc, "no such field in structure", field.c_str(), "");
|
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
|
} 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
|
// Propagate noContraction up the dereference chain
|
||||||
if (base->getQualifier().isNoContraction())
|
if (base->getQualifier().isNoContraction())
|
||||||
|
@ -1314,14 +1324,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
||||||
//
|
//
|
||||||
result = addConstructor(loc, arguments, type);
|
result = addConstructor(loc, arguments, type);
|
||||||
if (result == nullptr)
|
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 {
|
} else {
|
||||||
//
|
//
|
||||||
// Find it in the symbol table.
|
// Find it in the symbol table.
|
||||||
//
|
//
|
||||||
const TFunction* fnCandidate;
|
const TFunction* fnCandidate;
|
||||||
bool builtIn;
|
bool builtIn {false};
|
||||||
fnCandidate = findFunction(loc, *function, builtIn);
|
fnCandidate = findFunction(loc, *function, builtIn);
|
||||||
if (fnCandidate) {
|
if (fnCandidate) {
|
||||||
// This is a declared function that might map to
|
// This is a declared function that might map to
|
||||||
|
@ -1494,7 +1504,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
|
||||||
else
|
else
|
||||||
error(arguments->getLoc(), " wrong operand type", "Internal Error",
|
error(arguments->getLoc(), " wrong operand type", "Internal Error",
|
||||||
"built in unary operator function. Type: %s",
|
"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())
|
} else if (result->getAsOperator())
|
||||||
builtInOpCheck(loc, function, *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");
|
error(loc, "argument must be compile-time constant", "payload number", "a");
|
||||||
else {
|
else {
|
||||||
unsigned int location = (*argp)[10]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
|
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);
|
error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location);
|
||||||
}
|
}
|
||||||
break;
|
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", "");
|
error(loc, "argument must be compile-time constant", "callable data number", "");
|
||||||
else {
|
else {
|
||||||
unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
|
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);
|
error(loc, "with layout(location =", "no callableDataEXT/callableDataInEXT declared", "%d)", location);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2495,6 +2505,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
||||||
|
|
||||||
case EOpEmitStreamVertex:
|
case EOpEmitStreamVertex:
|
||||||
case EOpEndStreamPrimitive:
|
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();
|
intermediate.setMultiStream();
|
||||||
break;
|
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.
|
// Check that if extended types are being used that the correct extensions are enabled.
|
||||||
if (arg0 != nullptr) {
|
if (arg0 != nullptr) {
|
||||||
const TType& type = arg0->getType();
|
const TType& type = arg0->getType();
|
||||||
|
bool enhanced = intermediate.getEnhancedMsgs();
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
case EbtUint8:
|
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;
|
break;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
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;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
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;
|
break;
|
||||||
case EbtFloat16:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2786,7 +2799,10 @@ TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPu
|
||||||
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
if (op == EOpNull) {
|
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;
|
op = EOpConstructFloat;
|
||||||
TType errorType(EbtFloat);
|
TType errorType(EbtFloat);
|
||||||
type.shallowCopy(errorType);
|
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
|
// 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)
|
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;
|
return;
|
||||||
|
|
||||||
error(node->getLoc(), "scalar integer expression required", token, "");
|
error(node->getLoc(), "scalar integer expression required", token, "");
|
||||||
|
@ -3193,6 +3212,12 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
break;
|
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
|
// See if it's a matrix
|
||||||
bool constructingMatrix = false;
|
bool constructingMatrix = false;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -3250,7 +3275,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
if (function[arg].type->isArray()) {
|
if (function[arg].type->isArray()) {
|
||||||
if (function[arg].type->isUnsizedArray()) {
|
if (function[arg].type->isUnsizedArray()) {
|
||||||
// Can't construct from an unsized array.
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
arrayArg = true;
|
arrayArg = true;
|
||||||
|
@ -3280,13 +3305,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
intArgument = true;
|
intArgument = true;
|
||||||
if (type.isStruct()) {
|
if (type.isStruct()) {
|
||||||
if (function[arg].type->contains16BitFloat()) {
|
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()) {
|
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()) {
|
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 EOpConstructF16Vec3:
|
||||||
case EOpConstructF16Vec4:
|
case EOpConstructF16Vec4:
|
||||||
if (type.isArray())
|
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)
|
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;
|
break;
|
||||||
case EOpConstructUint16:
|
case EOpConstructUint16:
|
||||||
case EOpConstructU16Vec2:
|
case EOpConstructU16Vec2:
|
||||||
|
@ -3313,9 +3338,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
case EOpConstructI16Vec3:
|
case EOpConstructI16Vec3:
|
||||||
case EOpConstructI16Vec4:
|
case EOpConstructI16Vec4:
|
||||||
if (type.isArray())
|
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)
|
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;
|
break;
|
||||||
case EOpConstructUint8:
|
case EOpConstructUint8:
|
||||||
case EOpConstructU8Vec2:
|
case EOpConstructU8Vec2:
|
||||||
|
@ -3326,9 +3351,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
case EOpConstructI8Vec3:
|
case EOpConstructI8Vec3:
|
||||||
case EOpConstructI8Vec4:
|
case EOpConstructI8Vec4:
|
||||||
if (type.isArray())
|
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)
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -3410,7 +3435,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
|
|
||||||
if (type.isArray()) {
|
if (type.isArray()) {
|
||||||
if (function.getParamCount() == 0) {
|
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;
|
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
|
// auto adapt the constructor type to the number of arguments
|
||||||
type.changeOuterArraySize(function.getParamCount());
|
type.changeOuterArraySize(function.getParamCount());
|
||||||
} else if (type.getOuterArraySize() != 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3431,7 +3456,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
// At least the dimensionalities have to match.
|
// At least the dimensionalities have to match.
|
||||||
if (! function[0].type->isArray() ||
|
if (! function[0].type->isArray() ||
|
||||||
arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3448,7 +3473,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
|
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;
|
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,
|
// "If a matrix argument is given to a matrix constructor,
|
||||||
// it is a compile-time error to have any other arguments."
|
// it is a compile-time error to have any other arguments."
|
||||||
if (function.getParamCount() != 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overFull) {
|
if (overFull) {
|
||||||
error(loc, "too many arguments", "constructor", "");
|
error(loc, "too many arguments", constructorString.c_str(), "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
|
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
|
||||||
(op == EOpConstructStruct && 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.isCoopMat() && function.getParamCount() != 1) {
|
if (type.isCoopMat() && function.getParamCount() != 1) {
|
||||||
error(loc, "wrong number of arguments", "constructor", "");
|
error(loc, "wrong number of arguments", constructorString.c_str(), "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type.isCoopMat() &&
|
if (type.isCoopMat() &&
|
||||||
!(function[0].type->isScalar() || function[0].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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermTyped* typed = node->getAsTyped();
|
TIntermTyped* typed = node->getAsTyped();
|
||||||
if (typed == nullptr) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
if (op != EOpConstructStruct && typed->isAtomic()) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
if (typed->getBasicType() == EbtVoid) {
|
if (typed->getBasicType() == EbtVoid) {
|
||||||
error(loc, "cannot convert a void", "constructor", "");
|
error(loc, "cannot convert a void", constructorString.c_str(), "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3781,7 +3806,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
||||||
if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble)
|
if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble)
|
||||||
profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
|
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) ||
|
if (isTypeInt(publicType.basicType) ||
|
||||||
publicType.basicType == EbtDouble ||
|
publicType.basicType == EbtDouble ||
|
||||||
(publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt)
|
(publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt)
|
||||||
|
@ -4586,7 +4611,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||||
|
|
||||||
if (ssoPre150 ||
|
if (ssoPre150 ||
|
||||||
(identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) ||
|
(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_ClipDistance" ||
|
||||||
identifier == "gl_CullDistance" ||
|
identifier == "gl_CullDistance" ||
|
||||||
identifier == "gl_ShadingRateEXT" ||
|
identifier == "gl_ShadingRateEXT" ||
|
||||||
|
@ -4655,7 +4680,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||||
symbolQualifier.storage != qualifier.storage)
|
symbolQualifier.storage != qualifier.storage)
|
||||||
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
|
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
|
||||||
} else if (identifier == "gl_FragCoord") {
|
} 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", "");
|
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
|
||||||
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
||||||
qualifier.isMemory() || qualifier.isAuxiliary())
|
qualifier.isMemory() || qualifier.isAuxiliary())
|
||||||
|
@ -4665,6 +4690,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||||
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
|
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
|
||||||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
|
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
|
||||||
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
|
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
|
||||||
|
|
||||||
|
|
||||||
|
intermediate.setTexCoordRedeclared();
|
||||||
if (publicType.pixelCenterInteger)
|
if (publicType.pixelCenterInteger)
|
||||||
intermediate.setPixelCenterInteger();
|
intermediate.setPixelCenterInteger();
|
||||||
if (publicType.originUpperLeft)
|
if (publicType.originUpperLeft)
|
||||||
|
@ -5496,12 +5524,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||||
}
|
}
|
||||||
if (language == EShLangFragment) {
|
if (language == EShLangFragment) {
|
||||||
if (id == "origin_upper_left") {
|
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;
|
publicType.shaderQualifiers.originUpperLeft = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "pixel_center_integer") {
|
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;
|
publicType.shaderQualifiers.pixelCenterInteger = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6034,6 +6069,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
||||||
dst.layoutShaderRecord = true;
|
dst.layoutShaderRecord = true;
|
||||||
if (src.pervertexNV)
|
if (src.pervertexNV)
|
||||||
dst.pervertexNV = true;
|
dst.pervertexNV = true;
|
||||||
|
if (src.pervertexEXT)
|
||||||
|
dst.pervertexEXT = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6207,11 +6244,13 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
|
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
|
||||||
int repeated = intermediate.addXfbBufferOffset(type);
|
if (type.isUnsizedArray()) {
|
||||||
if (repeated >= 0)
|
|
||||||
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
|
|
||||||
if (type.isUnsizedArray())
|
|
||||||
error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
|
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
|
// "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
|
// 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);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock)
|
if (qualifier.isPushConstant()) {
|
||||||
error(loc, "can only be used with a block", "push_constant", "");
|
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)
|
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
|
||||||
error(loc, "can only be used with a block", "buffer_reference", "");
|
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", "");
|
error(loc, "can only be used with a uniform", "push_constant", "");
|
||||||
if (qualifier.hasSet())
|
if (qualifier.hasSet())
|
||||||
error(loc, "cannot be used with push_constant", "set", "");
|
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.hasBufferReference()) {
|
||||||
if (qualifier.storage != EvqBuffer)
|
if (qualifier.storage != EvqBuffer)
|
||||||
|
@ -6647,8 +6692,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
|
||||||
: findFunctionExact(loc, call, builtIn));
|
: findFunctionExact(loc, call, builtIn));
|
||||||
else if (version < 120)
|
else if (version < 120)
|
||||||
function = findFunctionExact(loc, call, builtIn);
|
function = findFunctionExact(loc, call, builtIn);
|
||||||
else if (version < 400)
|
else if (version < 400) {
|
||||||
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
|
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)
|
else if (explicitTypesEnabled)
|
||||||
function = findFunctionExplicitTypes(loc, call, builtIn);
|
function = findFunctionExplicitTypes(loc, call, builtIn);
|
||||||
else
|
else
|
||||||
|
@ -7419,14 +7466,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
|
||||||
// Uniforms require a compile-time constant initializer
|
// Uniforms require a compile-time constant initializer
|
||||||
if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
|
if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
|
||||||
error(loc, "uniform initializers must be constant", "=", "'%s'",
|
error(loc, "uniform initializers must be constant", "=", "'%s'",
|
||||||
variable->getType().getCompleteString().c_str());
|
variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
|
||||||
variable->getWritableType().getQualifier().makeTemporary();
|
variable->getWritableType().getQualifier().makeTemporary();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// Global consts require a constant initializer (specialization constant is okay)
|
// Global consts require a constant initializer (specialization constant is okay)
|
||||||
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
|
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
|
||||||
error(loc, "global const initializers must be constant", "=", "'%s'",
|
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();
|
variable->getWritableType().getQualifier().makeTemporary();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -7489,7 +7536,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
|
||||||
TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
|
TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
|
||||||
TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
|
TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
|
||||||
if (! initNode)
|
if (! initNode)
|
||||||
assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
|
assignError(loc, "=", intermSymbol->getCompleteString(intermediate.getEnhancedMsgs()), initializer->getCompleteString(intermediate.getEnhancedMsgs()));
|
||||||
|
|
||||||
return initNode;
|
return initNode;
|
||||||
}
|
}
|
||||||
|
@ -7560,7 +7607,7 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
|
||||||
}
|
}
|
||||||
} else if (type.isMatrix()) {
|
} else if (type.isMatrix()) {
|
||||||
if (type.getMatrixCols() != (int)initList->getSequence().size()) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TType vectorType(type, 0); // dereferenced type
|
TType vectorType(type, 0); // dereferenced type
|
||||||
|
@ -7571,20 +7618,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
|
||||||
}
|
}
|
||||||
} else if (type.isVector()) {
|
} else if (type.isVector()) {
|
||||||
if (type.getVectorSize() != (int)initList->getSequence().size()) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TBasicType destType = type.getBasicType();
|
TBasicType destType = type.getBasicType();
|
||||||
for (int i = 0; i < type.getVectorSize(); ++i) {
|
for (int i = 0; i < type.getVectorSize(); ++i) {
|
||||||
TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType();
|
TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType();
|
||||||
if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7691,7 +7738,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
|
||||||
return nullptr;
|
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
|
// 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());
|
TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
|
||||||
if (! converted || converted->getType() != type) {
|
if (! converted || converted->getType() != type) {
|
||||||
|
bool enhanced = intermediate.getEnhancedMsgs();
|
||||||
error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
|
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;
|
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."
|
// "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),
|
// 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.
|
// 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", "");
|
error(loc, "last case/default label not followed by statements", "switch", "");
|
||||||
else
|
else
|
||||||
warn(loc, "last case/default label not followed by statements", "switch", "");
|
warn(loc, "last case/default label not followed by statements", "switch", "");
|
||||||
|
|
||||||
|
|
||||||
// emulate a break for error recovery
|
// emulate a break for error recovery
|
||||||
lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
|
lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
|
||||||
lastStatements->setOperator(EOpSequence);
|
lastStatements->setOperator(EOpSequence);
|
||||||
|
|
|
@ -241,7 +241,7 @@ protected:
|
||||||
// override this to set the language-specific name
|
// override this to set the language-specific name
|
||||||
virtual const char* getAtomicCounterBlockName() const { return ""; }
|
virtual const char* getAtomicCounterBlockName() const { return ""; }
|
||||||
virtual void setAtomicCounterBlockDefaults(TType&) const {}
|
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&) {}
|
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
|
||||||
bool isAtomicCounterBlock(const TSymbol& symbol) {
|
bool isAtomicCounterBlock(const TSymbol& symbol) {
|
||||||
const TVariable* var = symbol.getAsVariable();
|
const TVariable* var = symbol.getAsVariable();
|
||||||
|
@ -472,7 +472,7 @@ public:
|
||||||
// Determine loop control from attributes
|
// Determine loop control from attributes
|
||||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
// Function attributes
|
// Function attributes
|
||||||
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
|
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
|
||||||
|
|
||||||
// GL_EXT_spirv_intrinsics
|
// GL_EXT_spirv_intrinsics
|
||||||
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
|
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
|
||||||
|
@ -480,7 +480,6 @@ public:
|
||||||
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
|
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
|
||||||
TSpirvRequirement* spirvReq2);
|
TSpirvRequirement* spirvReq2);
|
||||||
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
|
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
|
||||||
TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
|
|
||||||
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
|
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
|
||||||
TSpirvTypeParameters* spirvTypeParams2);
|
TSpirvTypeParameters* spirvTypeParams2);
|
||||||
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
|
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
|
||||||
|
|
|
@ -739,6 +739,7 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS;
|
(*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS;
|
||||||
(*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD;
|
(*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD;
|
||||||
(*KeywordMap)["pervertexNV"] = PERVERTEXNV;
|
(*KeywordMap)["pervertexNV"] = PERVERTEXNV;
|
||||||
|
(*KeywordMap)["pervertexEXT"] = PERVERTEXEXT;
|
||||||
(*KeywordMap)["precise"] = PRECISE;
|
(*KeywordMap)["precise"] = PRECISE;
|
||||||
|
|
||||||
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
|
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
|
||||||
|
@ -1719,6 +1720,12 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
case PERVERTEXEXT:
|
||||||
|
if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_EXT_fragment_shader_barycentric))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
case PRECISE:
|
case PRECISE:
|
||||||
if ((parseContext.isEsProfile() &&
|
if ((parseContext.isEsProfile() &&
|
||||||
(parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||
|
(parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||
|
||||||
|
|
|
@ -813,6 +813,7 @@ bool ProcessDeferred(
|
||||||
// set version/profile to defaultVersion/defaultProfile regardless of the #version
|
// set version/profile to defaultVersion/defaultProfile regardless of the #version
|
||||||
// directive in the source code
|
// directive in the source code
|
||||||
bool forceDefaultVersionAndProfile,
|
bool forceDefaultVersionAndProfile,
|
||||||
|
int overrideVersion, // overrides version specified by #verison or default version
|
||||||
bool forwardCompatible, // give errors for use of deprecated features
|
bool forwardCompatible, // give errors for use of deprecated features
|
||||||
EShMessages messages, // warnings/errors/AST; things to print out
|
EShMessages messages, // warnings/errors/AST; things to print out
|
||||||
TIntermediate& intermediate, // returned tree, etc.
|
TIntermediate& intermediate, // returned tree, etc.
|
||||||
|
@ -900,6 +901,9 @@ bool ProcessDeferred(
|
||||||
version = defaultVersion;
|
version = defaultVersion;
|
||||||
profile = defaultProfile;
|
profile = defaultProfile;
|
||||||
}
|
}
|
||||||
|
if (source == EShSourceGlsl && overrideVersion != 0) {
|
||||||
|
version = overrideVersion;
|
||||||
|
}
|
||||||
|
|
||||||
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
||||||
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
|
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
|
||||||
|
@ -1275,6 +1279,7 @@ bool PreprocessDeferred(
|
||||||
int defaultVersion, // use 100 for ES environment, 110 for desktop
|
int defaultVersion, // use 100 for ES environment, 110 for desktop
|
||||||
EProfile defaultProfile,
|
EProfile defaultProfile,
|
||||||
bool forceDefaultVersionAndProfile,
|
bool forceDefaultVersionAndProfile,
|
||||||
|
int overrideVersion, // use 0 if not overriding GLSL version
|
||||||
bool forwardCompatible, // give errors for use of deprecated features
|
bool forwardCompatible, // give errors for use of deprecated features
|
||||||
EShMessages messages, // warnings/errors/AST; things to print out
|
EShMessages messages, // warnings/errors/AST; things to print out
|
||||||
TShader::Includer& includer,
|
TShader::Includer& includer,
|
||||||
|
@ -1285,7 +1290,7 @@ bool PreprocessDeferred(
|
||||||
DoPreprocessing parser(outputString);
|
DoPreprocessing parser(outputString);
|
||||||
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
||||||
preamble, optLevel, resources, defaultVersion,
|
preamble, optLevel, resources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||||
forwardCompatible, messages, intermediate, parser,
|
forwardCompatible, messages, intermediate, parser,
|
||||||
false, includer, "", environment);
|
false, includer, "", environment);
|
||||||
}
|
}
|
||||||
|
@ -1314,6 +1319,7 @@ bool CompileDeferred(
|
||||||
int defaultVersion, // use 100 for ES environment, 110 for desktop
|
int defaultVersion, // use 100 for ES environment, 110 for desktop
|
||||||
EProfile defaultProfile,
|
EProfile defaultProfile,
|
||||||
bool forceDefaultVersionAndProfile,
|
bool forceDefaultVersionAndProfile,
|
||||||
|
int overrideVersion, // use 0 if not overriding GLSL version
|
||||||
bool forwardCompatible, // give errors for use of deprecated features
|
bool forwardCompatible, // give errors for use of deprecated features
|
||||||
EShMessages messages, // warnings/errors/AST; things to print out
|
EShMessages messages, // warnings/errors/AST; things to print out
|
||||||
TIntermediate& intermediate,// returned tree, etc.
|
TIntermediate& intermediate,// returned tree, etc.
|
||||||
|
@ -1324,7 +1330,7 @@ bool CompileDeferred(
|
||||||
DoFullParse parser;
|
DoFullParse parser;
|
||||||
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
||||||
preamble, optLevel, resources, defaultVersion,
|
preamble, optLevel, resources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||||
forwardCompatible, messages, intermediate, parser,
|
forwardCompatible, messages, intermediate, parser,
|
||||||
true, includer, sourceEntryPointName, environment);
|
true, includer, sourceEntryPointName, environment);
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1349,6 @@ int ShInitialize()
|
||||||
|
|
||||||
glslang::GetGlobalLock();
|
glslang::GetGlobalLock();
|
||||||
++NumberOfClients;
|
++NumberOfClients;
|
||||||
glslang::ReleaseGlobalLock();
|
|
||||||
|
|
||||||
if (PerProcessGPA == nullptr)
|
if (PerProcessGPA == nullptr)
|
||||||
PerProcessGPA = new TPoolAllocator();
|
PerProcessGPA = new TPoolAllocator();
|
||||||
|
@ -1353,6 +1358,7 @@ int ShInitialize()
|
||||||
glslang::HlslScanContext::fillInKeywordMap();
|
glslang::HlslScanContext::fillInKeywordMap();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glslang::ReleaseGlobalLock();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,9 +1421,10 @@ int ShFinalize()
|
||||||
--NumberOfClients;
|
--NumberOfClients;
|
||||||
assert(NumberOfClients >= 0);
|
assert(NumberOfClients >= 0);
|
||||||
bool finalize = NumberOfClients == 0;
|
bool finalize = NumberOfClients == 0;
|
||||||
glslang::ReleaseGlobalLock();
|
if (! finalize) {
|
||||||
if (! finalize)
|
glslang::ReleaseGlobalLock();
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int version = 0; version < VersionCount; ++version) {
|
for (int version = 0; version < VersionCount; ++version) {
|
||||||
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
||||||
|
@ -1455,6 +1462,7 @@ int ShFinalize()
|
||||||
glslang::HlslScanContext::deleteKeywordMap();
|
glslang::HlslScanContext::deleteKeywordMap();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glslang::ReleaseGlobalLock();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,7 +1504,7 @@ int ShCompile(
|
||||||
TIntermediate intermediate(compiler->getLanguage());
|
TIntermediate intermediate(compiler->getLanguage());
|
||||||
TShader::ForbidIncluder includer;
|
TShader::ForbidIncluder includer;
|
||||||
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
|
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
|
||||||
"", optLevel, resources, defaultVersion, ENoProfile, false,
|
"", optLevel, resources, defaultVersion, ENoProfile, false, 0,
|
||||||
forwardCompatible, messages, intermediate, includer);
|
forwardCompatible, messages, intermediate, includer);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1757,7 +1765,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
TShader::TShader(EShLanguage s)
|
TShader::TShader(EShLanguage s)
|
||||||
: stage(s), lengths(nullptr), stringNames(nullptr), preamble("")
|
: stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0)
|
||||||
{
|
{
|
||||||
pool = new TPoolAllocator;
|
pool = new TPoolAllocator;
|
||||||
infoSink = new TInfoSink;
|
infoSink = new TInfoSink;
|
||||||
|
@ -1826,7 +1834,14 @@ void TShader::setUniqueId(unsigned long long id)
|
||||||
intermediate->setUniqueId(id);
|
intermediate->setUniqueId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TShader::setOverrideVersion(int version)
|
||||||
|
{
|
||||||
|
overrideVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
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); }
|
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
|
@ -1906,7 +1921,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
||||||
|
|
||||||
return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
|
return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
|
||||||
preamble, EShOptNone, builtInResources, defaultVersion,
|
preamble, EShOptNone, builtInResources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||||
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
|
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
|
||||||
&environment);
|
&environment);
|
||||||
}
|
}
|
||||||
|
@ -1933,7 +1948,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
||||||
|
|
||||||
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
|
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
|
||||||
EShOptNone, builtInResources, defaultVersion,
|
EShOptNone, builtInResources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||||
forwardCompatible, message, includer, *intermediate, output_string,
|
forwardCompatible, message, includer, *intermediate, output_string,
|
||||||
&environment);
|
&environment);
|
||||||
}
|
}
|
||||||
|
@ -2046,6 +2061,8 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
||||||
firstIntermediate->getVersion(),
|
firstIntermediate->getVersion(),
|
||||||
firstIntermediate->getProfile());
|
firstIntermediate->getProfile());
|
||||||
intermediate[stage]->setLimits(firstIntermediate->getLimits());
|
intermediate[stage]->setLimits(firstIntermediate->getLimits());
|
||||||
|
if (firstIntermediate->getEnhancedMsgs())
|
||||||
|
intermediate[stage]->setEnhancedMsgs();
|
||||||
|
|
||||||
// The new TIntermediate must use the same origin as the original TIntermediates.
|
// The new TIntermediate must use the same origin as the original TIntermediates.
|
||||||
// Otherwise linking will fail due to different coordinate systems.
|
// Otherwise linking will fail due to different coordinate systems.
|
||||||
|
|
|
@ -130,11 +130,11 @@ void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermA
|
||||||
spirvExecutionMode = new TSpirvExecutionMode;
|
spirvExecutionMode = new TSpirvExecutionMode;
|
||||||
|
|
||||||
assert(args);
|
assert(args);
|
||||||
TVector<const TIntermConstantUnion*> extraOperands;
|
TVector<const TIntermTyped*> extraOperands;
|
||||||
|
|
||||||
for (auto arg : args->getSequence()) {
|
for (auto arg : args->getSequence()) {
|
||||||
auto extraOperand = arg->getAsConstantUnion();
|
auto extraOperand = arg->getAsTyped();
|
||||||
assert(extraOperand != nullptr);
|
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
|
||||||
extraOperands.push_back(extraOperand);
|
extraOperands.push_back(extraOperand);
|
||||||
}
|
}
|
||||||
spirvExecutionMode->modeIds[executionMode] = extraOperands;
|
spirvExecutionMode->modeIds[executionMode] = extraOperands;
|
||||||
|
@ -165,10 +165,10 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args
|
||||||
spirvDecorate = new TSpirvDecorate;
|
spirvDecorate = new TSpirvDecorate;
|
||||||
|
|
||||||
assert(args);
|
assert(args);
|
||||||
TVector<const TIntermConstantUnion*> extraOperands;
|
TVector<const TIntermTyped*> extraOperands;
|
||||||
for (auto arg : args->getSequence()) {
|
for (auto arg : args->getSequence()) {
|
||||||
auto extraOperand = arg->getAsConstantUnion();
|
auto extraOperand = arg->getAsTyped();
|
||||||
assert(extraOperand != nullptr);
|
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
|
||||||
extraOperands.push_back(extraOperand);
|
extraOperands.push_back(extraOperand);
|
||||||
}
|
}
|
||||||
spirvDecorate->decorateIds[decoration] = extraOperands;
|
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 appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
|
||||||
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
|
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) {
|
if (constant->getBasicType() == EbtFloat) {
|
||||||
float value = static_cast<float>(constant->getConstArray()[0].getDConst());
|
float value = static_cast<float>(constArray[0].getDConst());
|
||||||
appendFloat(value);
|
appendFloat(value);
|
||||||
}
|
}
|
||||||
else if (constant->getBasicType() == EbtInt) {
|
else if (constant->getBasicType() == EbtInt) {
|
||||||
int value = constant->getConstArray()[0].getIConst();
|
int value = constArray[0].getIConst();
|
||||||
appendInt(value);
|
appendInt(value);
|
||||||
}
|
}
|
||||||
else if (constant->getBasicType() == EbtUint) {
|
else if (constant->getBasicType() == EbtUint) {
|
||||||
unsigned value = constant->getConstArray()[0].getUConst();
|
unsigned value = constArray[0].getUConst();
|
||||||
appendUint(value);
|
appendUint(value);
|
||||||
}
|
}
|
||||||
else if (constant->getBasicType() == EbtBool) {
|
else if (constant->getBasicType() == EbtBool) {
|
||||||
bool value = constant->getConstArray()[0].getBConst();
|
bool value = constArray[0].getBConst();
|
||||||
appendBool(value);
|
appendBool(value);
|
||||||
}
|
}
|
||||||
else if (constant->getBasicType() == EbtString) {
|
else if (constant->getBasicType() == EbtString) {
|
||||||
const TString* value = constant->getConstArray()[0].getSConst();
|
const TString* value = constArray[0].getSConst();
|
||||||
appendStr(value->c_str());
|
appendStr(value->c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -290,13 +292,6 @@ TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& l
|
||||||
return spirvTypeParams;
|
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)
|
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
|
||||||
{
|
{
|
||||||
// Merge SPIR-V type parameters of the second one to the first one
|
// Merge SPIR-V type parameters of the second one to the first one
|
||||||
|
|
|
@ -279,8 +279,14 @@ TFunction::~TFunction()
|
||||||
//
|
//
|
||||||
TSymbolTableLevel::~TSymbolTableLevel()
|
TSymbolTableLevel::~TSymbolTableLevel()
|
||||||
{
|
{
|
||||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||||
delete (*it).second;
|
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;
|
delete [] defaultPrecision;
|
||||||
}
|
}
|
||||||
|
@ -418,6 +424,10 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||||
symTableLevel->anonId = anonId;
|
symTableLevel->anonId = anonId;
|
||||||
symTableLevel->thisLevel = thisLevel;
|
symTableLevel->thisLevel = thisLevel;
|
||||||
|
symTableLevel->retargetedSymbols.clear();
|
||||||
|
for (auto &s : retargetedSymbols) {
|
||||||
|
symTableLevel->retargetedSymbols.push_back({s.first, s.second});
|
||||||
|
}
|
||||||
std::vector<bool> containerCopied(anonId, false);
|
std::vector<bool> containerCopied(anonId, false);
|
||||||
tLevel::const_iterator iter;
|
tLevel::const_iterator iter;
|
||||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||||
|
@ -433,8 +443,21 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||||
symTableLevel->insert(*container, false);
|
symTableLevel->insert(*container, false);
|
||||||
containerCopied[anon->getAnonId()] = true;
|
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);
|
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;
|
return symTableLevel;
|
||||||
|
|
|
@ -84,7 +84,7 @@ typedef TVector<const char*> TExtensionList;
|
||||||
class TSymbol {
|
class TSymbol {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
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* clone() const = 0;
|
||||||
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
|
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() : defaultPrecision(0), anonId(0), thisLevel(false) { }
|
||||||
~TSymbolTableLevel();
|
~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
|
// returning true means symbol was added to the table with no semantic errors
|
||||||
//
|
//
|
||||||
const TString& name = symbol.getName();
|
const TString& name = symbol.getName();
|
||||||
if (name == "") {
|
if (forcedKeyName.length()) {
|
||||||
|
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
|
||||||
|
}
|
||||||
|
else if (name == "") {
|
||||||
symbol.getAsVariable()->setAnonId(anonId++);
|
symbol.getAsVariable()->setAnonId(anonId++);
|
||||||
// An empty name means an anonymous container, exposing its members to the external scope.
|
// 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.
|
// Give it a name and insert its members in the symbol table, pointing to the container.
|
||||||
|
@ -471,6 +478,16 @@ public:
|
||||||
return true;
|
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
|
TSymbol* find(const TString& name) const
|
||||||
{
|
{
|
||||||
tLevel::const_iterator it = level.find(name);
|
tLevel::const_iterator it = level.find(name);
|
||||||
|
@ -583,6 +600,8 @@ protected:
|
||||||
|
|
||||||
tLevel level; // named mappings
|
tLevel level; // named mappings
|
||||||
TPrecisionQualifier *defaultPrecision;
|
TPrecisionQualifier *defaultPrecision;
|
||||||
|
// pair<FromName, ToName>
|
||||||
|
TVector<std::pair<TString, TString>> retargetedSymbols;
|
||||||
int anonId;
|
int anonId;
|
||||||
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
|
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.
|
// that are supposed to see anonymous access to member variables.
|
||||||
|
@ -788,6 +807,12 @@ public:
|
||||||
return symbol;
|
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
|
// Find of a symbol that returns how many layers deep of nested
|
||||||
// structures-with-member-functions ('this' scopes) deep the symbol was
|
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||||
// found in.
|
// found in.
|
||||||
|
|
|
@ -225,6 +225,9 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
|
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = 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_basic] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = 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_shader_8bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
|
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
|
||||||
|
|
||||||
|
extensionBehavior[E_GL_EXT_fragment_shader_barycentric] = EBhDisable;
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||||
extensionBehavior[E_GL_GOOGLE_include_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_tracing] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_ray_query] = EBhDisable;
|
extensionBehavior[E_GL_EXT_ray_query] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = 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_blend_func_extended] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_fragment_shading_rate] = 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_shader_storage_buffer_object 1\n"
|
||||||
"#define GL_ARB_texture_query_lod 1\n"
|
"#define GL_ARB_texture_query_lod 1\n"
|
||||||
"#define GL_ARB_vertex_attrib_64bit 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_non_constant_global_initializers 1\n"
|
||||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
"#define GL_EXT_post_depth_coverage 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_debug_printf 1\n"
|
||||||
"#define GL_EXT_fragment_shading_rate 1\n"
|
"#define GL_EXT_fragment_shading_rate 1\n"
|
||||||
"#define GL_EXT_shared_memory_block 1\n"
|
"#define GL_EXT_shared_memory_block 1\n"
|
||||||
|
"#define GL_EXT_shader_integer_mix 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#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_tracing 1\n"
|
||||||
"#define GL_EXT_ray_query 1\n"
|
"#define GL_EXT_ray_query 1\n"
|
||||||
"#define GL_EXT_ray_flags_primitive_culling 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_EXT_spirv_intrinsics 1\n"
|
||||||
|
|
||||||
"#define GL_AMD_shader_ballot 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_float 1\n"
|
||||||
"#define GL_EXT_shader_atomic_float2 1\n"
|
"#define GL_EXT_shader_atomic_float2 1\n"
|
||||||
|
|
||||||
|
"#define GL_EXT_fragment_shader_barycentric 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
if (version >= 150) {
|
if (version >= 150) {
|
||||||
|
|
|
@ -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_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_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_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_basic = "GL_KHR_shader_subgroup_basic";
|
||||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
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_tracing = "GL_EXT_ray_tracing";
|
||||||
const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query";
|
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_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_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_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
|
||||||
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
|
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_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_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_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
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
|
|
@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
|
||||||
//
|
//
|
||||||
// Function attributes
|
// 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) {
|
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||||
if (it->size() > 0) {
|
if (it->size() > 0) {
|
||||||
|
|
|
@ -315,7 +315,7 @@ GLSLANG_WEB_EXCLUDE_ON
|
||||||
%token <lex> PATCH SAMPLE NONUNIFORM
|
%token <lex> PATCH SAMPLE NONUNIFORM
|
||||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
|
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
|
||||||
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
|
%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
|
%token <lex> PRECISE
|
||||||
GLSLANG_WEB_EXCLUDE_OFF
|
GLSLANG_WEB_EXCLUDE_OFF
|
||||||
|
|
||||||
|
@ -798,7 +798,7 @@ conditional_expression
|
||||||
parseContext.rValueErrorCheck($5.loc, ":", $6);
|
parseContext.rValueErrorCheck($5.loc, ":", $6);
|
||||||
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
|
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,7 +815,7 @@ assignment_expression
|
||||||
parseContext.rValueErrorCheck($2.loc, "assign", $3);
|
parseContext.rValueErrorCheck($2.loc, "assign", $3);
|
||||||
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
|
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,7 +877,7 @@ expression
|
||||||
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
|
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
|
||||||
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
|
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,20 +983,20 @@ function_prototype
|
||||||
$$.function = $1;
|
$$.function = $1;
|
||||||
$$.loc = $2.loc;
|
$$.loc = $2.loc;
|
||||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
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 {
|
| attribute function_declarator RIGHT_PAREN {
|
||||||
$$.function = $2;
|
$$.function = $2;
|
||||||
$$.loc = $3.loc;
|
$$.loc = $3.loc;
|
||||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
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 {
|
| attribute function_declarator RIGHT_PAREN attribute {
|
||||||
$$.function = $2;
|
$$.function = $2;
|
||||||
$$.loc = $3.loc;
|
$$.loc = $3.loc;
|
||||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||||
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
|
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1290,6 +1290,14 @@ GLSLANG_WEB_EXCLUDE_ON
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.pervertexNV = true;
|
$$.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 {
|
| PERPRIMITIVENV {
|
||||||
// No need for profile version or extension check. Shader stage already checks both.
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
||||||
|
@ -3926,6 +3934,7 @@ iteration_statement_nonattributed
|
||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
}
|
}
|
||||||
| DO {
|
| DO {
|
||||||
|
parseContext.symbolTable.push();
|
||||||
++parseContext.loopNestingLevel;
|
++parseContext.loopNestingLevel;
|
||||||
++parseContext.statementNestingLevel;
|
++parseContext.statementNestingLevel;
|
||||||
++parseContext.controlFlowNestingLevel;
|
++parseContext.controlFlowNestingLevel;
|
||||||
|
@ -3937,6 +3946,7 @@ iteration_statement_nonattributed
|
||||||
parseContext.boolCheck($8.loc, $6);
|
parseContext.boolCheck($8.loc, $6);
|
||||||
|
|
||||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||||
|
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||||
--parseContext.loopNestingLevel;
|
--parseContext.loopNestingLevel;
|
||||||
--parseContext.statementNestingLevel;
|
--parseContext.statementNestingLevel;
|
||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
|
@ -4365,9 +4375,6 @@ spirv_type_parameter
|
||||||
: constant_expression {
|
: constant_expression {
|
||||||
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
||||||
}
|
}
|
||||||
| type_specifier {
|
|
||||||
$$ = parseContext.makeSpirvTypeParameters($1);
|
|
||||||
}
|
|
||||||
|
|
||||||
spirv_instruction_qualifier
|
spirv_instruction_qualifier
|
||||||
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||||
|
|
|
@ -315,7 +315,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||||
%token <lex> PATCH SAMPLE NONUNIFORM
|
%token <lex> PATCH SAMPLE NONUNIFORM
|
||||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
|
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
|
||||||
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
|
%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
|
%token <lex> PRECISE
|
||||||
|
|
||||||
|
|
||||||
|
@ -798,7 +798,7 @@ conditional_expression
|
||||||
parseContext.rValueErrorCheck($5.loc, ":", $6);
|
parseContext.rValueErrorCheck($5.loc, ":", $6);
|
||||||
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
|
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,7 +815,7 @@ assignment_expression
|
||||||
parseContext.rValueErrorCheck($2.loc, "assign", $3);
|
parseContext.rValueErrorCheck($2.loc, "assign", $3);
|
||||||
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
|
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,7 +877,7 @@ expression
|
||||||
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
|
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
|
||||||
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
|
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
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;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,20 +983,20 @@ function_prototype
|
||||||
$$.function = $1;
|
$$.function = $1;
|
||||||
$$.loc = $2.loc;
|
$$.loc = $2.loc;
|
||||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
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 {
|
| attribute function_declarator RIGHT_PAREN {
|
||||||
$$.function = $2;
|
$$.function = $2;
|
||||||
$$.loc = $3.loc;
|
$$.loc = $3.loc;
|
||||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
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 {
|
| attribute function_declarator RIGHT_PAREN attribute {
|
||||||
$$.function = $2;
|
$$.function = $2;
|
||||||
$$.loc = $3.loc;
|
$$.loc = $3.loc;
|
||||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||||
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
|
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1290,6 +1290,14 @@ interpolation_qualifier
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.pervertexNV = true;
|
$$.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 {
|
| PERPRIMITIVENV {
|
||||||
// No need for profile version or extension check. Shader stage already checks both.
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
||||||
|
@ -3926,6 +3934,7 @@ iteration_statement_nonattributed
|
||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
}
|
}
|
||||||
| DO {
|
| DO {
|
||||||
|
parseContext.symbolTable.push();
|
||||||
++parseContext.loopNestingLevel;
|
++parseContext.loopNestingLevel;
|
||||||
++parseContext.statementNestingLevel;
|
++parseContext.statementNestingLevel;
|
||||||
++parseContext.controlFlowNestingLevel;
|
++parseContext.controlFlowNestingLevel;
|
||||||
|
@ -3937,6 +3946,7 @@ iteration_statement_nonattributed
|
||||||
parseContext.boolCheck($8.loc, $6);
|
parseContext.boolCheck($8.loc, $6);
|
||||||
|
|
||||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||||
|
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||||
--parseContext.loopNestingLevel;
|
--parseContext.loopNestingLevel;
|
||||||
--parseContext.statementNestingLevel;
|
--parseContext.statementNestingLevel;
|
||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
|
@ -4365,9 +4375,6 @@ spirv_type_parameter
|
||||||
: constant_expression {
|
: constant_expression {
|
||||||
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
||||||
}
|
}
|
||||||
| type_specifier {
|
|
||||||
$$ = parseContext.makeSpirvTypeParameters($1);
|
|
||||||
}
|
|
||||||
|
|
||||||
spirv_instruction_qualifier
|
spirv_instruction_qualifier
|
||||||
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -501,11 +501,12 @@ extern int yydebug;
|
||||||
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
|
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
|
||||||
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
|
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
|
||||||
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
|
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
|
||||||
PERVERTEXNV = 705, /* PERVERTEXNV */
|
PERVERTEXEXT = 705, /* PERVERTEXEXT */
|
||||||
PERPRIMITIVENV = 706, /* PERPRIMITIVENV */
|
PERVERTEXNV = 706, /* PERVERTEXNV */
|
||||||
PERVIEWNV = 707, /* PERVIEWNV */
|
PERPRIMITIVENV = 707, /* PERPRIMITIVENV */
|
||||||
PERTASKNV = 708, /* PERTASKNV */
|
PERVIEWNV = 708, /* PERVIEWNV */
|
||||||
PRECISE = 709 /* PRECISE */
|
PERTASKNV = 709, /* PERTASKNV */
|
||||||
|
PRECISE = 710 /* PRECISE */
|
||||||
};
|
};
|
||||||
typedef enum yytokentype yytoken_kind_t;
|
typedef enum yytokentype yytoken_kind_t;
|
||||||
#endif
|
#endif
|
||||||
|
@ -553,7 +554,7 @@ union YYSTYPE
|
||||||
glslang::TArraySizes* typeParameters;
|
glslang::TArraySizes* typeParameters;
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 557 "MachineIndependent/glslang_tab.cpp.h"
|
#line 558 "MachineIndependent/glslang_tab.cpp.h"
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
|
|
@ -48,37 +48,6 @@
|
||||||
#endif
|
#endif
|
||||||
#include <cstdint>
|
#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 {
|
namespace glslang {
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public:
|
||||||
target = &inputList;
|
target = &inputList;
|
||||||
else if (base->getQualifier().storage == EvqVaryingOut)
|
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||||
target = &outputList;
|
target = &outputList;
|
||||||
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant() && !base->getQualifier().isShaderRecord())
|
||||||
target = &uniformList;
|
target = &uniformList;
|
||||||
// If a global is being visited, then we should also traverse it incase it's evaluation
|
// 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
|
// 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) {
|
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
|
||||||
TVarEntryInfo& ent = entKey.second;
|
TVarEntryInfo& ent = entKey.second;
|
||||||
ent.newLocation = -1;
|
ent.clearNewAssignments();
|
||||||
ent.newComponent = -1;
|
|
||||||
ent.newBinding = -1;
|
|
||||||
ent.newSet = -1;
|
|
||||||
ent.newIndex = -1;
|
|
||||||
const bool isValid = resolver.validateBinding(stage, ent);
|
const bool isValid = resolver.validateBinding(stage, ent);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
resolver.resolveSet(ent.stage, ent);
|
resolver.resolveSet(ent.stage, ent);
|
||||||
|
@ -281,11 +277,7 @@ struct TResolverInOutAdaptor {
|
||||||
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
|
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
|
||||||
{
|
{
|
||||||
TVarEntryInfo& ent = entKey.second;
|
TVarEntryInfo& ent = entKey.second;
|
||||||
ent.newLocation = -1;
|
ent.clearNewAssignments();
|
||||||
ent.newComponent = -1;
|
|
||||||
ent.newBinding = -1;
|
|
||||||
ent.newSet = -1;
|
|
||||||
ent.newIndex = -1;
|
|
||||||
const bool isValid = resolver.validateInOut(ent.stage, ent);
|
const bool isValid = resolver.validateInOut(ent.stage, ent);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
resolver.resolveInOutLocation(stage, ent);
|
resolver.resolveInOutLocation(stage, ent);
|
||||||
|
@ -514,6 +506,24 @@ struct TSymbolValidater
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
TString err = "Invalid In/Out variable type : " + entKey.first;
|
||||||
infoSink.info.message(EPrefixInternalError, err.c_str());
|
infoSink.info.message(EPrefixInternalError, err.c_str());
|
||||||
hadError = true;
|
hadError = true;
|
||||||
|
@ -748,7 +758,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
|
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
|
||||||
: intermediate(intermediate)
|
: referenceIntermediate(intermediate)
|
||||||
, nextUniformLocation(intermediate.getUniformLocationBase())
|
, nextUniformLocation(intermediate.getUniformLocationBase())
|
||||||
, nextInputLocation(0)
|
, nextInputLocation(0)
|
||||||
, nextOutputLocation(0)
|
, nextOutputLocation(0)
|
||||||
|
@ -760,17 +770,17 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
|
||||||
|
|
||||||
int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
|
int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
|
||||||
return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
|
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 {
|
const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
|
||||||
return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
|
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) {
|
TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
|
||||||
return std::lower_bound(slots[set].begin(), slots[set].end(), 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
|
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
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;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
// no locations on blocks of built-in variables
|
// no locations on blocks of built-in variables
|
||||||
|
@ -839,7 +849,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int location = intermediate.getUniformLocationOverride(name);
|
int location = referenceIntermediate.getUniformLocationOverride(name);
|
||||||
if (location != -1) {
|
if (location != -1) {
|
||||||
return ent.newLocation = location;
|
return ent.newLocation = location;
|
||||||
}
|
}
|
||||||
|
@ -855,8 +865,8 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no locations added if already present, or a built-in variable
|
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||||
if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
|
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,8 +952,8 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
||||||
if (type.getQualifier().hasLocation()) {
|
if (type.getQualifier().hasLocation()) {
|
||||||
return ent.newLocation = type.getQualifier().layoutLocation;
|
return ent.newLocation = type.getQualifier().layoutLocation;
|
||||||
}
|
}
|
||||||
// no locations added if already present, or a built-in variable
|
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||||
if (type.isBuiltIn()) {
|
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
// no locations on blocks of built-in variables
|
// no locations on blocks of built-in variables
|
||||||
|
@ -1024,7 +1034,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||||
} else {
|
} else {
|
||||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
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;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
// no locations on blocks of built-in variables
|
// 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) {
|
if (location != -1) {
|
||||||
return ent.newLocation = location;
|
return ent.newLocation = location;
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1097,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getAccessName();
|
const TString& name = ent.symbol->getAccessName();
|
||||||
// On OpenGL arrays of opaque types take a separate binding for each element
|
// 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);
|
TResourceType resource = getResourceType(type);
|
||||||
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
||||||
if (resource == EResUbo && type.getBasicType() != EbtBlock) {
|
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
|
// 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 name space, so remap the 'set' to resource type which make each resource
|
||||||
// binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
|
// 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;
|
int resourceKey = set;
|
||||||
if (resource < EResCount) {
|
if (resource < EResCount) {
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
@ -1223,7 +1234,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getAccessName();
|
const TString& name = ent.symbol->getAccessName();
|
||||||
TResourceType resource = getResourceType(type);
|
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;
|
int resourceKey = set;
|
||||||
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
@ -1233,7 +1244,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
||||||
|
|
||||||
if (iter == varSlotMap.end()) {
|
if (iter == varSlotMap.end()) {
|
||||||
// Reserve the slots for the ubo, ssbo and opaques who has explicit binding
|
// 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;
|
varSlotMap[name] = binding;
|
||||||
reserveSlot(resourceKey, binding, numBindings);
|
reserveSlot(resourceKey, binding, numBindings);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1288,7 +1299,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const int set = getLayoutSet(type);
|
const int set = getLayoutSet(type);
|
||||||
// On OpenGL arrays of opaque types take a seperate binding for each element
|
// 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);
|
TResourceType resource = getResourceType(type);
|
||||||
if (resource < EResCount) {
|
if (resource < EResCount) {
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
@ -1633,6 +1644,45 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
|
||||||
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
||||||
});
|
});
|
||||||
resolver->endResolve(EShLangCount);
|
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++) {
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
if (intermediates[stage] != nullptr) {
|
if (intermediates[stage] != nullptr) {
|
||||||
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
||||||
|
|
|
@ -61,6 +61,15 @@ struct TVarEntryInfo {
|
||||||
int newComponent;
|
int newComponent;
|
||||||
int newIndex;
|
int newIndex;
|
||||||
EShLanguage stage;
|
EShLanguage stage;
|
||||||
|
|
||||||
|
void clearNewAssignments() {
|
||||||
|
newBinding = -1;
|
||||||
|
newSet = -1;
|
||||||
|
newLocation = -1;
|
||||||
|
newComponent = -1;
|
||||||
|
newIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
struct TOrderById {
|
struct TOrderById {
|
||||||
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
|
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
|
||||||
};
|
};
|
||||||
|
@ -165,7 +174,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
||||||
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
|
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
|
||||||
const TIntermediate& intermediate;
|
const TIntermediate& referenceIntermediate;
|
||||||
int nextUniformLocation;
|
int nextUniformLocation;
|
||||||
int nextInputLocation;
|
int nextInputLocation;
|
||||||
int nextOutputLocation;
|
int nextOutputLocation;
|
||||||
|
@ -291,7 +300,7 @@ public:
|
||||||
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// I/O mapper for OpenGL
|
// I/O mapper for GLSL
|
||||||
class TGlslIoMapper : public TIoMapper {
|
class TGlslIoMapper : public TIoMapper {
|
||||||
public:
|
public:
|
||||||
TGlslIoMapper() {
|
TGlslIoMapper() {
|
||||||
|
@ -301,6 +310,8 @@ public:
|
||||||
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
||||||
profile = ENoProfile;
|
profile = ENoProfile;
|
||||||
version = 0;
|
version = 0;
|
||||||
|
autoPushConstantMaxSize = 128;
|
||||||
|
autoPushConstantBlockPacking = ElpStd430;
|
||||||
}
|
}
|
||||||
virtual ~TGlslIoMapper() {
|
virtual ~TGlslIoMapper() {
|
||||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
|
@ -320,6 +331,13 @@ public:
|
||||||
intermediates[stage] = nullptr;
|
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
|
// grow the reflection stage by stage
|
||||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
||||||
bool doMap(TIoMapResolver*, TInfoSink&) override;
|
bool doMap(TIoMapResolver*, TInfoSink&) override;
|
||||||
|
@ -329,6 +347,11 @@ public:
|
||||||
bool hadError = false;
|
bool hadError = false;
|
||||||
EProfile profile;
|
EProfile profile;
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TString autoPushConstantBlockName;
|
||||||
|
unsigned int autoPushConstantMaxSize;
|
||||||
|
TLayoutPacking autoPushConstantBlockPacking;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -55,22 +55,28 @@ namespace glslang {
|
||||||
//
|
//
|
||||||
// Link-time error emitter.
|
// 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
|
#ifndef GLSLANG_WEB
|
||||||
infoSink.info.prefix(EPrefixError);
|
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
|
#endif
|
||||||
|
|
||||||
++numErrors;
|
++numErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link-time warning.
|
// Link-time warning.
|
||||||
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
|
||||||
{
|
{
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
infoSink.info.prefix(EPrefixWarning);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,6 +318,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
MERGE_TRUE(autoMapBindings);
|
MERGE_TRUE(autoMapBindings);
|
||||||
MERGE_TRUE(autoMapLocations);
|
MERGE_TRUE(autoMapLocations);
|
||||||
MERGE_TRUE(invertY);
|
MERGE_TRUE(invertY);
|
||||||
|
MERGE_TRUE(dxPositionW);
|
||||||
MERGE_TRUE(flattenUniformArrays);
|
MERGE_TRUE(flattenUniformArrays);
|
||||||
MERGE_TRUE(useUnknownFormat);
|
MERGE_TRUE(useUnknownFormat);
|
||||||
MERGE_TRUE(hlslOffsets);
|
MERGE_TRUE(hlslOffsets);
|
||||||
|
@ -579,9 +586,6 @@ void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate&
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
|
void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
|
||||||
if (block->getType() == unitBlock->getType()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
|
if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
|
||||||
block->getType().getBasicType() != unitBlock->getType().getBasicType() ||
|
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,
|
// update symbol node in unit tree,
|
||||||
// and other nodes that may reference it
|
// and other nodes that may reference it
|
||||||
class TMergeBlockTraverser : public TIntermTraverser {
|
class TMergeBlockTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType,
|
TMergeBlockTraverser(const TIntermSymbol* newSym)
|
||||||
glslang::TIntermediate& unit,
|
: newSymbol(newSym), unitType(nullptr), unit(nullptr), memberIndexUpdates(nullptr)
|
||||||
const std::map<unsigned int, unsigned int>& memberIdxUpdates) :
|
{
|
||||||
newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
|
}
|
||||||
{ }
|
TMergeBlockTraverser(const TIntermSymbol* newSym, const glslang::TType* unitType, glslang::TIntermediate* unit,
|
||||||
virtual ~TMergeBlockTraverser() { }
|
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 TIntermSymbol* newSymbol;
|
||||||
const glslang::TType& unitType; // copy of original type
|
const glslang::TType* unitType; // copy of original type
|
||||||
glslang::TIntermediate& unit; // intermediate that is being updated
|
glslang::TIntermediate* unit; // intermediate that is being updated
|
||||||
const std::map<unsigned int, unsigned int>& memberIndexUpdates;
|
const std::map<unsigned int, unsigned int>* memberIndexUpdates;
|
||||||
|
|
||||||
virtual void visitSymbol(TIntermSymbol* symbol)
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
{
|
{
|
||||||
glslang::TType& symType = symbol->getWritableType();
|
if (newSymbol->getAccessName() == symbol->getAccessName() &&
|
||||||
|
newSymbol->getQualifier().getBlockStorage() == symbol->getQualifier().getBlockStorage()) {
|
||||||
if (symType == unitType) {
|
// Each symbol node may have a local copy of the block structure.
|
||||||
// each symbol node has a local copy of the unitType
|
// Update those structures to match the new one post-merge
|
||||||
// if merging involves changing properties that aren't shared objects
|
*(symbol->getWritableType().getWritableStruct()) = *(newSymbol->getType().getStruct());
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool visitBinary(TVisit, glslang::TIntermBinary* node)
|
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
|
// this is a dereference to a member of the block since the
|
||||||
// member list changed, need to update this to point to the
|
// member list changed, need to update this to point to the
|
||||||
// right index
|
// right index
|
||||||
|
@ -673,8 +675,8 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
|
||||||
|
|
||||||
glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
|
glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
|
||||||
unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
|
unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
|
||||||
unsigned int newIdx = memberIndexUpdates.at(memberIdx);
|
unsigned int newIdx = memberIndexUpdates->at(memberIdx);
|
||||||
TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc());
|
TIntermTyped* newConstNode = unit->addConstantUnion(newIdx, node->getRight()->getLoc());
|
||||||
|
|
||||||
node->setRight(newConstNode);
|
node->setRight(newConstNode);
|
||||||
delete constNode;
|
delete constNode;
|
||||||
|
@ -683,10 +685,20 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates);
|
};
|
||||||
|
|
||||||
// update the tree to use the new type
|
// 'this' may have symbols that are using the old block structure, so traverse the tree to update those
|
||||||
unit->getTreeRoot()->traverse(&finalLinkTraverser);
|
// 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
|
// update the member list
|
||||||
(*unitMemberList) = (*memberList);
|
(*unitMemberList) = (*memberList);
|
||||||
|
@ -759,7 +771,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
||||||
|
|
||||||
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
|
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
|
||||||
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
|
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: ");
|
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
|
||||||
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
|
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)
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
bool crossStage = getStage() != unitStage;
|
bool crossStage = getStage() != unitStage;
|
||||||
bool writeTypeComparison = false;
|
bool writeTypeComparison = false;
|
||||||
|
bool errorReported = false;
|
||||||
|
bool printQualifiers = false;
|
||||||
|
bool printPrecision = false;
|
||||||
|
bool printType = false;
|
||||||
|
|
||||||
// Types have to match
|
// Types have to match
|
||||||
{
|
{
|
||||||
|
@ -846,11 +865,48 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
|
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!symbol.getType().sameElementType(unitSymbol.getType()) ||
|
int lpidx = -1;
|
||||||
!symbol.getType().sameTypeParameters(unitSymbol.getType()) ||
|
int rpidx = -1;
|
||||||
!arraysMatch ) {
|
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;
|
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 &&
|
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
|
||||||
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
|
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
|
||||||
symbol.getType().sameStructType(unitSymbol.getType())) {
|
symbol.getType().sameStructType(unitSymbol.getType())) {
|
||||||
for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
|
unsigned int li = 0;
|
||||||
const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
|
unsigned int ri = 0;
|
||||||
const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
|
while (li < symbol.getType().getStruct()->size() && ri < unitSymbol.getType().getStruct()->size()) {
|
||||||
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
|
if ((*symbol.getType().getStruct())[li].type->hiddenMember()) {
|
||||||
qualifier.layoutOffset != unitQualifier.layoutOffset ||
|
++li;
|
||||||
qualifier.layoutAlign != unitQualifier.layoutAlign ||
|
continue;
|
||||||
qualifier.layoutLocation != unitQualifier.layoutLocation ||
|
|
||||||
qualifier.layoutComponent != unitQualifier.layoutComponent) {
|
|
||||||
error(infoSink, "Interface block member layout qualifiers must match:");
|
|
||||||
writeTypeComparison = true;
|
|
||||||
}
|
}
|
||||||
|
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
|
// Qualifiers have to (almost) match
|
||||||
// Storage...
|
// Storage...
|
||||||
if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
|
if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
|
||||||
error(infoSink, "Storage qualifiers must match:");
|
error(infoSink, "Storage qualifiers must match:", unitStage);
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
|
printQualifiers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uniform and buffer blocks must either both have an instance name, or
|
// 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() &&
|
if (symbol.getQualifier().isUniformOrBuffer() &&
|
||||||
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) {
|
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) {
|
||||||
error(infoSink, "Matched Uniform or Storage blocks must all be anonymous,"
|
error(infoSink, "Matched Uniform or Storage blocks must all be anonymous,"
|
||||||
" or all be named:");
|
" or all be named:", unitStage);
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage &&
|
if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage &&
|
||||||
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) ||
|
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) ||
|
||||||
(!IsAnonymous(symbol.getName()) && symbol.getName() != 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;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precision...
|
// Precision...
|
||||||
if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
|
if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
|
||||||
error(infoSink, "Precision qualifiers must match:");
|
error(infoSink, "Precision qualifiers must match:", unitStage);
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
|
printPrecision = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invariance...
|
// Invariance...
|
||||||
if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
|
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;
|
writeTypeComparison = true;
|
||||||
|
printQualifiers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precise...
|
// Precise...
|
||||||
if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) {
|
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;
|
writeTypeComparison = true;
|
||||||
|
printPrecision = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliary and interpolation...
|
// Auxiliary and interpolation...
|
||||||
|
@ -928,57 +1022,137 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
|
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
|
||||||
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
|
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
|
||||||
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) {
|
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;
|
writeTypeComparison = true;
|
||||||
|
printQualifiers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory...
|
// Memory...
|
||||||
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
|
bool memoryQualifierError = false;
|
||||||
symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
|
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent) {
|
||||||
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
|
error(infoSink, "Memory coherent qualifier must match:", unitStage);
|
||||||
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
|
memoryQualifierError = true;
|
||||||
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
|
}
|
||||||
symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent ||
|
if (symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent) {
|
||||||
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
|
error(infoSink, "Memory devicecoherent qualifier must match:", unitStage);
|
||||||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
memoryQualifierError = true;
|
||||||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
}
|
||||||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
|
if (symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent) {
|
||||||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
|
error(infoSink, "Memory queuefamilycoherent qualifier must match:", unitStage);
|
||||||
error(infoSink, "Memory qualifiers must match:");
|
memoryQualifierError = true;
|
||||||
writeTypeComparison = 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...
|
// Layouts...
|
||||||
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
|
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
|
||||||
// requires separate user-supplied offset from actual computed offset, but
|
// requires separate user-supplied offset from actual computed offset, but
|
||||||
// current implementation only has one offset.
|
// current implementation only has one offset.
|
||||||
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
|
bool layoutQualifierError = false;
|
||||||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
|
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix) {
|
||||||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
|
error(infoSink, "Layout matrix qualifier must match:", unitStage);
|
||||||
symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
|
layoutQualifierError = true;
|
||||||
symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex ||
|
}
|
||||||
symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding ||
|
if (symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking) {
|
||||||
(symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
|
error(infoSink, "Layout packing qualifier must match:", unitStage);
|
||||||
error(infoSink, "Layout qualification must match:");
|
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;
|
writeTypeComparison = true;
|
||||||
|
printQualifiers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializers have to match, if both are present, and if we don't already know the types don't match
|
// 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().empty() && ! unitSymbol.getConstArray().empty()) {
|
||||||
if (symbol.getConstArray() != unitSymbol.getConstArray()) {
|
if (symbol.getConstArray() != unitSymbol.getConstArray()) {
|
||||||
error(infoSink, "Initializers must match:");
|
error(infoSink, "Initializers must match:", unitStage);
|
||||||
infoSink.info << " " << symbol.getName() << "\n";
|
infoSink.info << " " << symbol.getName() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeTypeComparison) {
|
if (writeTypeComparison) {
|
||||||
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus ";
|
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
|
||||||
if (symbol.getName() != unitSymbol.getName())
|
symbol.getType().getStruct() && unitSymbol.getType().getStruct()) {
|
||||||
infoSink.info << unitSymbol.getName() << ": ";
|
if (printType) {
|
||||||
|
infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision,
|
||||||
infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n";
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1786,7 +1960,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numComponents;
|
int numComponents {0};
|
||||||
if (type.isScalar())
|
if (type.isScalar())
|
||||||
numComponents = 1;
|
numComponents = 1;
|
||||||
else if (type.isVector())
|
else if (type.isVector())
|
||||||
|
@ -1934,7 +2108,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
||||||
}
|
}
|
||||||
|
|
||||||
// rule 9
|
// rule 9
|
||||||
if (type.getBasicType() == EbtStruct) {
|
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
|
||||||
const TTypeList& memberList = *type.getStruct();
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -2159,10 +2333,11 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
|
||||||
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
|
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
|
||||||
return type.isArray() &&
|
return type.isArray() &&
|
||||||
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
|
((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) ||
|
! type.getQualifier().patch) ||
|
||||||
|
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
|
||||||
(language == EShLangFragment && 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 &&
|
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
|
||||||
!type.getQualifier().perTaskNV));
|
!type.getQualifier().perTaskNV));
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,6 +290,8 @@ public:
|
||||||
resources(TBuiltInResource{}),
|
resources(TBuiltInResource{}),
|
||||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||||
invertY(false),
|
invertY(false),
|
||||||
|
dxPositionW(false),
|
||||||
|
enhancedMsgs(false),
|
||||||
useStorageBuffer(false),
|
useStorageBuffer(false),
|
||||||
invariantAll(false),
|
invariantAll(false),
|
||||||
nanMinMaxClamp(false),
|
nanMinMaxClamp(false),
|
||||||
|
@ -307,7 +309,7 @@ public:
|
||||||
useVulkanMemoryModel(false),
|
useVulkanMemoryModel(false),
|
||||||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||||
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
||||||
pixelCenterInteger(false), originUpperLeft(false),
|
pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
||||||
postDepthCoverage(false), depthLayout(EldNone),
|
postDepthCoverage(false), depthLayout(EldNone),
|
||||||
hlslFunctionality1(false),
|
hlslFunctionality1(false),
|
||||||
|
@ -397,6 +399,9 @@ public:
|
||||||
case EShTargetSpv_1_5:
|
case EShTargetSpv_1_5:
|
||||||
processes.addProcess("target-env spirv1.5");
|
processes.addProcess("target-env spirv1.5");
|
||||||
break;
|
break;
|
||||||
|
case EShTargetSpv_1_6:
|
||||||
|
processes.addProcess("target-env spirv1.6");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
processes.addProcess("target-env spirvUnknown");
|
processes.addProcess("target-env spirvUnknown");
|
||||||
break;
|
break;
|
||||||
|
@ -415,6 +420,9 @@ public:
|
||||||
case EShTargetVulkan_1_2:
|
case EShTargetVulkan_1_2:
|
||||||
processes.addProcess("target-env vulkan1.2");
|
processes.addProcess("target-env vulkan1.2");
|
||||||
break;
|
break;
|
||||||
|
case EShTargetVulkan_1_3:
|
||||||
|
processes.addProcess("target-env vulkan1.3");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
processes.addProcess("target-env vulkanUnknown");
|
processes.addProcess("target-env vulkanUnknown");
|
||||||
break;
|
break;
|
||||||
|
@ -460,6 +468,20 @@ public:
|
||||||
}
|
}
|
||||||
bool getInvertY() const { return invertY; }
|
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
|
#ifdef ENABLE_HLSL
|
||||||
void setSource(EShSource s) { source = s; }
|
void setSource(EShSource s) { source = s; }
|
||||||
EShSource getSource() const { return source; }
|
EShSource getSource() const { return source; }
|
||||||
|
@ -812,6 +834,8 @@ public:
|
||||||
bool getOriginUpperLeft() const { return originUpperLeft; }
|
bool getOriginUpperLeft() const { return originUpperLeft; }
|
||||||
void setPixelCenterInteger() { pixelCenterInteger = true; }
|
void setPixelCenterInteger() { pixelCenterInteger = true; }
|
||||||
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
||||||
|
void setTexCoordRedeclared() { texCoordBuiltinRedeclared = true; }
|
||||||
|
bool getTexCoordRedeclared() const { return texCoordBuiltinRedeclared; }
|
||||||
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
||||||
unsigned int getBlendEquations() const { return blendEquations; }
|
unsigned int getBlendEquations() const { return blendEquations; }
|
||||||
bool setXfbBufferStride(int buffer, unsigned stride)
|
bool setXfbBufferStride(int buffer, unsigned stride)
|
||||||
|
@ -1016,8 +1040,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
|
||||||
void warn(TInfoSink& infoSink, const char*);
|
void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
|
||||||
void mergeCallGraphs(TInfoSink&, TIntermediate&);
|
void mergeCallGraphs(TInfoSink&, TIntermediate&);
|
||||||
void mergeModes(TInfoSink&, TIntermediate&);
|
void mergeModes(TInfoSink&, TIntermediate&);
|
||||||
void mergeTrees(TInfoSink&, TIntermediate&);
|
void mergeTrees(TInfoSink&, TIntermediate&);
|
||||||
|
@ -1070,6 +1094,8 @@ protected:
|
||||||
int numPushConstants;
|
int numPushConstants;
|
||||||
bool recursive;
|
bool recursive;
|
||||||
bool invertY;
|
bool invertY;
|
||||||
|
bool dxPositionW;
|
||||||
|
bool enhancedMsgs;
|
||||||
bool useStorageBuffer;
|
bool useStorageBuffer;
|
||||||
bool invariantAll;
|
bool invariantAll;
|
||||||
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
|
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
|
||||||
|
@ -1098,6 +1124,7 @@ protected:
|
||||||
TLayoutGeometry outputPrimitive;
|
TLayoutGeometry outputPrimitive;
|
||||||
bool pixelCenterInteger;
|
bool pixelCenterInteger;
|
||||||
bool originUpperLeft;
|
bool originUpperLeft;
|
||||||
|
bool texCoordBuiltinRedeclared;
|
||||||
TVertexSpacing vertexSpacing;
|
TVertexSpacing vertexSpacing;
|
||||||
TVertexOrder vertexOrder;
|
TVertexOrder vertexOrder;
|
||||||
TInterlockOrdering interlockOrdering;
|
TInterlockOrdering interlockOrdering;
|
||||||
|
@ -1158,6 +1185,7 @@ protected:
|
||||||
// for callableData/callableDataIn
|
// for callableData/callableDataIn
|
||||||
// set of names of statically read/written I/O that might need extra checking
|
// set of names of statically read/written I/O that might need extra checking
|
||||||
std::set<TString> ioAccessed;
|
std::set<TString> ioAccessed;
|
||||||
|
|
||||||
// source code of shader, useful as part of debug information
|
// source code of shader, useful as part of debug information
|
||||||
std::string sourceFile;
|
std::string sourceFile;
|
||||||
std::string sourceText;
|
std::string sourceText;
|
||||||
|
|
|
@ -56,4 +56,4 @@ if(ENABLE_GLSLANG_INSTALL)
|
||||||
install(TARGETS OSDependent EXPORT OSDependentTargets
|
install(TARGETS OSDependent EXPORT OSDependentTargets
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||||
endif(ENABLE_GLSLANG_INSTALL)
|
endif()
|
||||||
|
|
|
@ -172,7 +172,7 @@ namespace {
|
||||||
pthread_mutex_t gMutex;
|
pthread_mutex_t gMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitGlobalLock()
|
static void InitMutex(void)
|
||||||
{
|
{
|
||||||
pthread_mutexattr_t mutexattr;
|
pthread_mutexattr_t mutexattr;
|
||||||
pthread_mutexattr_init(&mutexattr);
|
pthread_mutexattr_init(&mutexattr);
|
||||||
|
@ -180,6 +180,12 @@ void InitGlobalLock()
|
||||||
pthread_mutex_init(&gMutex, &mutexattr);
|
pthread_mutex_init(&gMutex, &mutexattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitGlobalLock()
|
||||||
|
{
|
||||||
|
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||||
|
pthread_once(&once, InitMutex);
|
||||||
|
}
|
||||||
|
|
||||||
void GetGlobalLock()
|
void GetGlobalLock()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&gMutex);
|
pthread_mutex_lock(&gMutex);
|
||||||
|
|
|
@ -55,7 +55,7 @@ if(ENABLE_GLSLANG_JS)
|
||||||
|
|
||||||
if(ENABLE_EMSCRIPTEN_SINGLE_FILE)
|
if(ENABLE_EMSCRIPTEN_SINGLE_FILE)
|
||||||
target_link_libraries(glslang.js "-s SINGLE_FILE=1")
|
target_link_libraries(glslang.js "-s SINGLE_FILE=1")
|
||||||
endif(ENABLE_EMSCRIPTEN_SINGLE_FILE)
|
endif()
|
||||||
|
|
||||||
if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE)
|
if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE)
|
||||||
target_link_libraries(glslang.js "-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0")
|
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
|
add_custom_command(TARGET glslang.js POST_BUILD
|
||||||
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js)
|
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js)
|
||||||
endif()
|
endif()
|
||||||
endif(EMSCRIPTEN)
|
endif()
|
||||||
endif(ENABLE_GLSLANG_JS)
|
endif()
|
||||||
|
|
|
@ -45,10 +45,10 @@ endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
source_group("Source" FILES ${SOURCES})
|
source_group("Source" FILES ${SOURCES})
|
||||||
endif(WIN32)
|
endif()
|
||||||
|
|
||||||
if(ENABLE_GLSLANG_INSTALL)
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
install(TARGETS OSDependent EXPORT OSDependentTargets
|
install(TARGETS OSDependent EXPORT OSDependentTargets
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||||
endif(ENABLE_GLSLANG_INSTALL)
|
endif()
|
||||||
|
|
|
@ -150,8 +150,8 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShClientNone, // use when there is no client, e.g. for validation
|
EShClientNone, // use when there is no client, e.g. for validation
|
||||||
EShClientVulkan,
|
EShClientVulkan, // as GLSL dialect, specifies KHR_vulkan_glsl extension
|
||||||
EShClientOpenGL,
|
EShClientOpenGL, // as GLSL dialect, specifies ARB_gl_spirv extension
|
||||||
LAST_ELEMENT_MARKER(EShClientCount),
|
LAST_ELEMENT_MARKER(EShClientCount),
|
||||||
} EShClient;
|
} EShClient;
|
||||||
|
|
||||||
|
@ -166,8 +166,9 @@ typedef enum {
|
||||||
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
||||||
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
||||||
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
|
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
|
||||||
|
EShTargetVulkan_1_3 = (1 << 22) | (3 << 12), // Vulkan 1.3
|
||||||
EShTargetOpenGL_450 = 450, // OpenGL
|
EShTargetOpenGL_450 = 450, // OpenGL
|
||||||
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
|
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 5),
|
||||||
} EShTargetClientVersion;
|
} EShTargetClientVersion;
|
||||||
|
|
||||||
typedef EShTargetClientVersion EshTargetClientVersion;
|
typedef EShTargetClientVersion EshTargetClientVersion;
|
||||||
|
@ -179,7 +180,8 @@ typedef enum {
|
||||||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
||||||
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
||||||
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
|
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;
|
} EShTargetLanguageVersion;
|
||||||
|
|
||||||
struct TInputLanguage {
|
struct TInputLanguage {
|
||||||
|
@ -262,6 +264,7 @@ enum EShMessages : unsigned {
|
||||||
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
||||||
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
|
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
|
||||||
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
|
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
|
||||||
|
EShMsgEnhanced = (1 << 15), // enhanced message readability
|
||||||
LAST_ELEMENT_MARKER(EShMsgCount),
|
LAST_ELEMENT_MARKER(EShMsgCount),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -468,6 +471,7 @@ public:
|
||||||
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
|
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
|
||||||
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
|
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
|
||||||
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
|
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
|
||||||
|
GLSLANG_EXPORT void setOverrideVersion(int version);
|
||||||
|
|
||||||
// IO resolver binding data: see comments in ShaderLang.cpp
|
// IO resolver binding data: see comments in ShaderLang.cpp
|
||||||
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
|
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 addUniformLocationOverride(const char* name, int loc);
|
||||||
GLSLANG_EXPORT void setUniformLocationBase(int base);
|
GLSLANG_EXPORT void setUniformLocationBase(int base);
|
||||||
GLSLANG_EXPORT void setInvertY(bool invert);
|
GLSLANG_EXPORT void setInvertY(bool invert);
|
||||||
|
GLSLANG_EXPORT void setDxPositionW(bool dxPosW);
|
||||||
|
GLSLANG_EXPORT void setEnhancedMsgs();
|
||||||
#ifdef ENABLE_HLSL
|
#ifdef ENABLE_HLSL
|
||||||
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
|
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
|
||||||
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
|
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
|
||||||
|
@ -512,6 +518,9 @@ public:
|
||||||
// use EShClientNone and version of 0, e.g. for validation mode.
|
// use EShClientNone and version of 0, e.g. for validation mode.
|
||||||
// Note 'version' does not describe the target environment,
|
// Note 'version' does not describe the target environment,
|
||||||
// just the version of the source dialect to compile under.
|
// 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,
|
// See the definitions of TEnvironment, EShSource, EShLanguage,
|
||||||
// and EShClient for choices and more detail.
|
// 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.
|
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
|
||||||
std::string sourceEntryPointName;
|
std::string sourceEntryPointName;
|
||||||
|
|
||||||
|
// overrides #version in shader source or default version if #version isn't present
|
||||||
|
int overrideVersion;
|
||||||
|
|
||||||
TEnvironment environment;
|
TEnvironment environment;
|
||||||
|
|
||||||
friend class TProgram;
|
friend class TProgram;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define GLSLextKHR_H
|
#define GLSLextKHR_H
|
||||||
|
|
||||||
static const int GLSLextKHRVersion = 100;
|
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_shader_ballot = "SPV_KHR_shader_ballot";
|
||||||
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
|
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_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_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_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
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
|
|
@ -260,6 +260,7 @@ protected:
|
||||||
std::unordered_map<std::string, spv::Id> extBuiltinMap;
|
std::unordered_map<std::string, spv::Id> extBuiltinMap;
|
||||||
|
|
||||||
std::unordered_map<long long, spv::Id> symbolValues;
|
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,
|
std::unordered_set<long long> rValueParameters; // set of formal function parameters passed as rValues,
|
||||||
// rather than a pointer
|
// rather than a pointer
|
||||||
std::unordered_map<std::string, spv::Function*> functionMap;
|
std::unordered_map<std::string, spv::Function*> functionMap;
|
||||||
|
@ -1007,6 +1008,8 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
||||||
return spv::BuiltInRayTminKHR;
|
return spv::BuiltInRayTminKHR;
|
||||||
case glslang::EbvRayTmax:
|
case glslang::EbvRayTmax:
|
||||||
return spv::BuiltInRayTmaxKHR;
|
return spv::BuiltInRayTmaxKHR;
|
||||||
|
case glslang::EbvCullMask:
|
||||||
|
return spv::BuiltInCullMaskKHR;
|
||||||
case glslang::EbvInstanceCustomIndex:
|
case glslang::EbvInstanceCustomIndex:
|
||||||
return spv::BuiltInInstanceCustomIndexKHR;
|
return spv::BuiltInInstanceCustomIndexKHR;
|
||||||
case glslang::EbvHitT:
|
case glslang::EbvHitT:
|
||||||
|
@ -1048,6 +1051,15 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
||||||
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
|
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
|
||||||
return spv::BuiltInBaryCoordNoPerspNV;
|
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
|
// mesh shaders
|
||||||
case glslang::EbvTaskCountNV:
|
case glslang::EbvTaskCountNV:
|
||||||
return spv::BuiltInTaskCountNV;
|
return spv::BuiltInTaskCountNV;
|
||||||
|
@ -1256,8 +1268,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
||||||
if (type.getBasicType() == glslang::EbtRayQuery)
|
if (type.getBasicType() == glslang::EbtRayQuery)
|
||||||
return spv::StorageClassPrivate;
|
return spv::StorageClassPrivate;
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (type.getQualifier().isSpirvByReference())
|
if (type.getQualifier().isSpirvByReference()) {
|
||||||
return spv::StorageClassFunction;
|
if (type.getQualifier().isParamInput() || type.getQualifier().isParamOutput())
|
||||||
|
return spv::StorageClassFunction;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (type.getQualifier().isPipeInput())
|
if (type.getQualifier().isPipeInput())
|
||||||
return spv::StorageClassInput;
|
return spv::StorageClassInput;
|
||||||
|
@ -1662,9 +1676,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
||||||
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
builder.addCapability(spv::CapabilityShader);
|
builder.addCapability(spv::CapabilityShader);
|
||||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||||
glslangIntermediate->getLocalSize(1),
|
std::vector<spv::Id> dimConstId;
|
||||||
glslangIntermediate->getLocalSize(2));
|
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) {
|
if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) {
|
||||||
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
|
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
|
||||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV);
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV);
|
||||||
|
@ -1762,15 +1789,35 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
||||||
builder.addCapability(spv::CapabilityRayTracingNV);
|
builder.addCapability(spv::CapabilityRayTracingNV);
|
||||||
builder.addExtension("SPV_NV_ray_tracing");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case EShLangTaskNV:
|
case EShLangTaskNV:
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
builder.addCapability(spv::CapabilityMeshShadingNV);
|
builder.addCapability(spv::CapabilityMeshShadingNV);
|
||||||
builder.addExtension(spv::E_SPV_NV_mesh_shader);
|
builder.addExtension(spv::E_SPV_NV_mesh_shader);
|
||||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||||
glslangIntermediate->getLocalSize(1),
|
std::vector<spv::Id> dimConstId;
|
||||||
glslangIntermediate->getLocalSize(2));
|
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) {
|
if (glslangIntermediate->getStage() == EShLangMeshNV) {
|
||||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
|
||||||
glslangIntermediate->getVertices());
|
glslangIntermediate->getVertices());
|
||||||
|
@ -1830,10 +1877,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
||||||
std::vector<spv::Id> operandIds;
|
std::vector<spv::Id> operandIds;
|
||||||
assert(!modeId.second.empty());
|
assert(!modeId.second.empty());
|
||||||
for (auto extraOperand : modeId.second) {
|
for (auto extraOperand : modeId.second) {
|
||||||
int nextConst = 0;
|
if (extraOperand->getType().getQualifier().isSpecConstant())
|
||||||
spv::Id operandId = createSpvConstantFromConstUnionArray(
|
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||||
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
|
else
|
||||||
operandIds.push_back(operandId);
|
operandIds.push_back(createSpvConstant(*extraOperand));
|
||||||
}
|
}
|
||||||
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
|
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
|
||||||
}
|
}
|
||||||
|
@ -2746,6 +2793,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||||
} else {
|
} else {
|
||||||
handleFunctionEntry(node);
|
handleFunctionEntry(node);
|
||||||
}
|
}
|
||||||
|
if (options.generateDebugInfo) {
|
||||||
|
const auto& loc = node->getLoc();
|
||||||
|
currentFunction->setDebugLineInfo(builder.getSourceFile(), loc.line, loc.column);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (inEntryPoint)
|
if (inEntryPoint)
|
||||||
entryPointTerminated = true;
|
entryPointTerminated = true;
|
||||||
|
@ -3384,7 +3435,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||||
const auto& spirvInst = node->getSpirvInstruction();
|
const auto& spirvInst = node->getSpirvInstruction();
|
||||||
if (spirvInst.set == "") {
|
if (spirvInst.set == "") {
|
||||||
std::vector<spv::IdImmediate> idImmOps;
|
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()) {
|
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||||
// Translate the constant to a literal value
|
// Translate the constant to a literal value
|
||||||
std::vector<unsigned> literals;
|
std::vector<unsigned> literals;
|
||||||
|
@ -3777,7 +3828,16 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
||||||
|
|
||||||
switch (node->getFlowOp()) {
|
switch (node->getFlowOp()) {
|
||||||
case glslang::EOpKill:
|
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;
|
break;
|
||||||
case glslang::EOpTerminateInvocation:
|
case glslang::EOpTerminateInvocation:
|
||||||
builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
|
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.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
|
||||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||||
return builder.makeFloatType(16);
|
return builder.makeFloatType(16);
|
||||||
case glslang::EbtInt64: return builder.makeIntType(64);
|
case glslang::EbtInt64:
|
||||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||||
case glslang::EbtUint64: return builder.makeUintType(64);
|
return builder.makeIntType(64);
|
||||||
|
case glslang::EbtUint64:
|
||||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||||
|
return builder.makeUintType(64);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -4146,68 +4208,55 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
||||||
const auto& spirvType = type.getSpirvType();
|
const auto& spirvType = type.getSpirvType();
|
||||||
const auto& spirvInst = spirvType.spirvInst;
|
const auto& spirvInst = spirvType.spirvInst;
|
||||||
|
|
||||||
std::vector<spv::Id> operands;
|
std::vector<spv::IdImmediate> operands;
|
||||||
for (const auto& typeParam : spirvType.typeParams) {
|
for (const auto& typeParam : spirvType.typeParams) {
|
||||||
if (typeParam.isConstant) {
|
// Constant expression
|
||||||
// Constant expression
|
if (typeParam.constant->isLiteral()) {
|
||||||
if (typeParam.constant->isLiteral()) {
|
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
|
||||||
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
|
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
|
||||||
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
|
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
|
||||||
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
|
operands.push_back({false, literal});
|
||||||
operands.push_back(literal);
|
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
|
||||||
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
|
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
|
||||||
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
|
operands.push_back({false, literal});
|
||||||
operands.push_back(literal);
|
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
|
||||||
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
|
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
|
||||||
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
|
operands.push_back({false, literal});
|
||||||
operands.push_back(literal);
|
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
|
||||||
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
|
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
|
||||||
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
|
operands.push_back({false, literal});
|
||||||
operands.push_back(literal);
|
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
|
||||||
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
|
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
|
||||||
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
|
unsigned literal = 0;
|
||||||
unsigned literal = 0;
|
char* literalPtr = reinterpret_cast<char*>(&literal);
|
||||||
char* literalPtr = reinterpret_cast<char*>(&literal);
|
unsigned charCount = 0;
|
||||||
unsigned charCount = 0;
|
char ch = 0;
|
||||||
char ch = 0;
|
do {
|
||||||
do {
|
ch = *(str++);
|
||||||
ch = *(str++);
|
*(literalPtr++) = ch;
|
||||||
*(literalPtr++) = ch;
|
++charCount;
|
||||||
++charCount;
|
if (charCount == 4) {
|
||||||
if (charCount == 4) {
|
operands.push_back({false, literal});
|
||||||
operands.push_back(literal);
|
literalPtr = reinterpret_cast<char*>(&literal);
|
||||||
literalPtr = reinterpret_cast<char*>(&literal);
|
charCount = 0;
|
||||||
charCount = 0;
|
|
||||||
}
|
|
||||||
} while (ch != 0);
|
|
||||||
|
|
||||||
// Partial literal is padded with 0
|
|
||||||
if (charCount > 0) {
|
|
||||||
for (; charCount < 4; ++charCount)
|
|
||||||
*(literalPtr++) = 0;
|
|
||||||
operands.push_back(literal);
|
|
||||||
}
|
}
|
||||||
} else
|
} while (ch != 0);
|
||||||
assert(0); // Unexpected type
|
|
||||||
} else {
|
// Partial literal is padded with 0
|
||||||
int nextConst = 0;
|
if (charCount > 0) {
|
||||||
spv::Id constant = createSpvConstantFromConstUnionArray(
|
for (; charCount < 4; ++charCount)
|
||||||
typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
|
*(literalPtr++) = 0;
|
||||||
operands.push_back(constant);
|
operands.push_back({false, literal});
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
// Type specifier
|
assert(0); // Unexpected type
|
||||||
spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
|
} else
|
||||||
operands.push_back(typeId);
|
operands.push_back({true, createSpvConstant(*typeParam.constant)});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spirvInst.set == "")
|
assert(spirvInst.set == ""); // Currently, couldn't be extended instructions.
|
||||||
spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
|
spvType = builder.makeGenericType(static_cast<spv::Op>(spirvInst.id), operands);
|
||||||
else {
|
|
||||||
spvType = builder.createBuiltinCall(
|
|
||||||
spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7506,6 +7555,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
|
||||||
break;
|
break;
|
||||||
case glslang::EOpReadFirstInvocation:
|
case glslang::EOpReadFirstInvocation:
|
||||||
opCode = spv::OpSubgroupFirstInvocationKHR;
|
opCode = spv::OpSubgroupFirstInvocationKHR;
|
||||||
|
if (builder.isVectorType(typeId))
|
||||||
|
return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
|
||||||
break;
|
break;
|
||||||
case glslang::EOpBallot:
|
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 ||
|
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
|
||||||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
|
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
|
||||||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
|
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::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
|
||||||
op == spv::OpGroupSMinNonUniformAMD ||
|
op == spv::OpGroupSMinNonUniformAMD ||
|
||||||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
|
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
|
||||||
|
@ -7659,6 +7710,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
|
||||||
spvGroupOperands.push_back(scalar);
|
spvGroupOperands.push_back(scalar);
|
||||||
spv::IdImmediate operand = { true, operands[1] };
|
spv::IdImmediate operand = { true, operands[1] };
|
||||||
spvGroupOperands.push_back(operand);
|
spvGroupOperands.push_back(operand);
|
||||||
|
} else if (op == spv::OpSubgroupFirstInvocationKHR) {
|
||||||
|
spvGroupOperands.push_back(scalar);
|
||||||
} else if (op == spv::OpGroupBroadcast) {
|
} else if (op == spv::OpGroupBroadcast) {
|
||||||
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
||||||
spvGroupOperands.push_back(scope);
|
spvGroupOperands.push_back(scope);
|
||||||
|
@ -8698,7 +8751,32 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||||
// it was not found, create it
|
// it was not found, create it
|
||||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
|
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
|
||||||
auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType());
|
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);
|
id = createSpvVariable(symbol, forcedType.first);
|
||||||
|
|
||||||
|
if (mayNeedToReuseBuiltIn) {
|
||||||
|
builtInVariableIds.insert({uint32_t(builtIn), id});
|
||||||
|
}
|
||||||
|
|
||||||
symbolValues[symbol->getId()] = id;
|
symbolValues[symbol->getId()] = id;
|
||||||
if (forcedType.second != spv::NoType)
|
if (forcedType.second != spv::NoType)
|
||||||
forceType[id] = forcedType.second;
|
forceType[id] = forcedType.second;
|
||||||
|
@ -8721,8 +8799,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||||
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
|
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol->getQualifier().hasLocation())
|
if (symbol->getQualifier().hasLocation()) {
|
||||||
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
|
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()));
|
builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
|
||||||
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||||
|
@ -8756,7 +8844,16 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||||
|
|
||||||
// add built-in variable decoration
|
// add built-in variable decoration
|
||||||
if (builtIn != spv::BuiltInMax) {
|
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
|
#ifndef GLSLANG_WEB
|
||||||
|
@ -8808,6 +8905,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||||
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
|
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) {
|
if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
|
||||||
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
|
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
|
||||||
builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
|
builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
|
||||||
|
@ -8841,12 +8944,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||||
std::vector<spv::Id> operandIds;
|
std::vector<spv::Id> operandIds;
|
||||||
assert(!decorateId.second.empty());
|
assert(!decorateId.second.empty());
|
||||||
for (auto extraOperand : decorateId.second) {
|
for (auto extraOperand : decorateId.second) {
|
||||||
int nextConst = 0;
|
if (extraOperand->getQualifier().isSpecConstant())
|
||||||
spv::Id operandId = createSpvConstantFromConstUnionArray(
|
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||||
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
|
else
|
||||||
operandIds.push_back(operandId);
|
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
|
// Add spirv_decorate_string
|
||||||
|
@ -9029,15 +9132,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
||||||
break;
|
break;
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case glslang::EbtInt8:
|
case glslang::EbtInt8:
|
||||||
|
builder.addCapability(spv::CapabilityInt8);
|
||||||
spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
|
spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
|
||||||
break;
|
break;
|
||||||
case glslang::EbtUint8:
|
case glslang::EbtUint8:
|
||||||
|
builder.addCapability(spv::CapabilityInt8);
|
||||||
spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
|
spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
|
||||||
break;
|
break;
|
||||||
case glslang::EbtInt16:
|
case glslang::EbtInt16:
|
||||||
|
builder.addCapability(spv::CapabilityInt16);
|
||||||
spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
|
spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
|
||||||
break;
|
break;
|
||||||
case glslang::EbtUint16:
|
case glslang::EbtUint16:
|
||||||
|
builder.addCapability(spv::CapabilityInt16);
|
||||||
spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
|
spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
|
||||||
break;
|
break;
|
||||||
case glslang::EbtInt64:
|
case glslang::EbtInt64:
|
||||||
|
@ -9050,6 +9157,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
||||||
spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
|
spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
|
||||||
break;
|
break;
|
||||||
case glslang::EbtFloat16:
|
case glslang::EbtFloat16:
|
||||||
|
builder.addCapability(spv::CapabilityFloat16);
|
||||||
spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
|
spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -9078,15 +9186,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
||||||
break;
|
break;
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case glslang::EbtInt8:
|
case glslang::EbtInt8:
|
||||||
|
builder.addCapability(spv::CapabilityInt8);
|
||||||
scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
|
scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtUint8:
|
case glslang::EbtUint8:
|
||||||
|
builder.addCapability(spv::CapabilityInt8);
|
||||||
scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
|
scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtInt16:
|
case glslang::EbtInt16:
|
||||||
|
builder.addCapability(spv::CapabilityInt16);
|
||||||
scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
|
scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtUint16:
|
case glslang::EbtUint16:
|
||||||
|
builder.addCapability(spv::CapabilityInt16);
|
||||||
scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
|
scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtInt64:
|
case glslang::EbtInt64:
|
||||||
|
@ -9099,6 +9211,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
||||||
scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
|
scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtFloat16:
|
case glslang::EbtFloat16:
|
||||||
|
builder.addCapability(spv::CapabilityFloat16);
|
||||||
scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
|
scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
|
||||||
break;
|
break;
|
||||||
case glslang::EbtReference:
|
case glslang::EbtReference:
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SpvTools.h"
|
#include "SpvTools.h"
|
||||||
#include "../glslang/Include/intermediate.h"
|
#include "glslang/Include/intermediate.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -160,15 +160,29 @@ namespace spv {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this an opcode we should remove when using --strip?
|
// 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) {
|
switch (opCode) {
|
||||||
case spv::OpSource:
|
case spv::OpSource:
|
||||||
case spv::OpSourceExtension:
|
case spv::OpSourceExtension:
|
||||||
case spv::OpName:
|
case spv::OpName:
|
||||||
case spv::OpMemberName:
|
case spv::OpMemberName:
|
||||||
case spv::OpLine: return true;
|
case spv::OpLine :
|
||||||
default: return false;
|
{
|
||||||
|
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 spirvbin_t::literalString(unsigned word) const
|
||||||
{
|
{
|
||||||
std::string literal;
|
std::string literal;
|
||||||
|
const spirword_t * pos = spv.data() + word;
|
||||||
|
|
||||||
literal.reserve(16);
|
literal.reserve(16);
|
||||||
|
|
||||||
const char* bytes = reinterpret_cast<const char*>(spv.data() + word);
|
do {
|
||||||
|
spirword_t word = *pos;
|
||||||
while (bytes && *bytes)
|
for (int i = 0; i < 4; i++) {
|
||||||
literal += *bytes++;
|
char c = word & 0xff;
|
||||||
|
if (c == '\0')
|
||||||
return literal;
|
return literal;
|
||||||
|
literal += c;
|
||||||
|
word >>= 8;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spirvbin_t::applyMap()
|
void spirvbin_t::applyMap()
|
||||||
|
@ -366,7 +386,7 @@ namespace spv {
|
||||||
process(
|
process(
|
||||||
[&](spv::Op opCode, unsigned start) {
|
[&](spv::Op opCode, unsigned start) {
|
||||||
// remember opcodes we want to strip later
|
// remember opcodes we want to strip later
|
||||||
if (isStripOp(opCode))
|
if (isStripOp(opCode, start))
|
||||||
stripInst(start);
|
stripInst(start);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1488,13 +1508,24 @@ namespace spv {
|
||||||
}
|
}
|
||||||
|
|
||||||
// remap from a memory image
|
// 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);
|
spv.swap(in_spv);
|
||||||
remap(opts);
|
remap(opts);
|
||||||
spv.swap(in_spv);
|
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
|
} // namespace SPV
|
||||||
|
|
||||||
#endif // defined (use_cpp11)
|
#endif // defined (use_cpp11)
|
||||||
|
|
|
@ -118,6 +118,10 @@ public:
|
||||||
virtual ~spirvbin_t() { }
|
virtual ~spirvbin_t() { }
|
||||||
|
|
||||||
// remap on an existing binary in memory
|
// 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);
|
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||||
|
|
||||||
// Type for error/log handler functions
|
// Type for error/log handler functions
|
||||||
|
@ -180,6 +184,8 @@ private:
|
||||||
unsigned typeSizeInWords(spv::Id id) const;
|
unsigned typeSizeInWords(spv::Id id) const;
|
||||||
unsigned idTypeSizeInWords(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]; }
|
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||||
spv::Op asOpCode(unsigned word) const { return opOpCode(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<spirword_t> spv; // SPIR words
|
||||||
|
|
||||||
|
std::vector<std::string> stripWhiteList;
|
||||||
|
|
||||||
namemap_t nameMap; // ID names from OpName
|
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
|
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
|
||||||
|
|
|
@ -427,6 +427,37 @@ Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols)
|
||||||
return type->getResultId();
|
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
|
// TODO: performance: track arrays per stride
|
||||||
// If a stride is supplied (non-zero) make an array.
|
// If a stride is supplied (non-zero) make an array.
|
||||||
|
|
|
@ -99,6 +99,10 @@ public:
|
||||||
stringIds[file_c_str] = strId;
|
stringIds[file_c_str] = strId;
|
||||||
return strId;
|
return strId;
|
||||||
}
|
}
|
||||||
|
spv::Id getSourceFile() const
|
||||||
|
{
|
||||||
|
return sourceFileStringId;
|
||||||
|
}
|
||||||
void setSourceFile(const std::string& file)
|
void setSourceFile(const std::string& file)
|
||||||
{
|
{
|
||||||
sourceFileStringId = getStringId(file);
|
sourceFileStringId = getStringId(file);
|
||||||
|
@ -181,6 +185,7 @@ public:
|
||||||
Id makeSamplerType();
|
Id makeSamplerType();
|
||||||
Id makeSampledImageType(Id imageType);
|
Id makeSampledImageType(Id imageType);
|
||||||
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||||
|
Id makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands);
|
||||||
|
|
||||||
// accelerationStructureNV type
|
// accelerationStructureNV type
|
||||||
Id makeAccelerationStructureType();
|
Id makeAccelerationStructureType();
|
||||||
|
|
|
@ -44,10 +44,8 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "SpvBuilder.h"
|
#include "SpvBuilder.h"
|
||||||
|
|
||||||
#include "spirv.hpp"
|
#include "spirv.hpp"
|
||||||
#include "GlslangToSpv.h"
|
|
||||||
#include "SpvBuilder.h"
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
#include "GLSL.std.450.h"
|
#include "GLSL.std.450.h"
|
||||||
#include "GLSL.ext.KHR.h"
|
#include "GLSL.ext.KHR.h"
|
||||||
|
@ -113,8 +111,6 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OpAccessChain:
|
|
||||||
case OpPtrAccessChain:
|
|
||||||
case OpCopyObject:
|
case OpCopyObject:
|
||||||
break;
|
break;
|
||||||
case OpFConvert:
|
case OpFConvert:
|
||||||
|
@ -161,26 +157,43 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
switch (inst.getImmediateOperand(1)) {
|
switch (inst.getImmediateOperand(1)) {
|
||||||
case GLSLstd450Frexp:
|
case GLSLstd450Frexp:
|
||||||
case GLSLstd450FrexpStruct:
|
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);
|
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||||
break;
|
break;
|
||||||
case GLSLstd450InterpolateAtCentroid:
|
case GLSLstd450InterpolateAtCentroid:
|
||||||
case GLSLstd450InterpolateAtSample:
|
case GLSLstd450InterpolateAtSample:
|
||||||
case GLSLstd450InterpolateAtOffset:
|
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);
|
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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:
|
default:
|
||||||
if (basicTypeOp == OpTypeFloat && width == 16)
|
if (basicTypeOp == OpTypeInt) {
|
||||||
addCapability(CapabilityFloat16);
|
if (width == 16)
|
||||||
if (basicTypeOp == OpTypeInt && width == 16)
|
addCapability(CapabilityInt16);
|
||||||
addCapability(CapabilityInt16);
|
else if (width == 8)
|
||||||
if (basicTypeOp == OpTypeInt && width == 8)
|
addCapability(CapabilityInt8);
|
||||||
addCapability(CapabilityInt8);
|
else if (width == 64)
|
||||||
|
addCapability(CapabilityInt64);
|
||||||
|
} else if (basicTypeOp == OpTypeFloat) {
|
||||||
|
if (width == 16)
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
else if (width == 64)
|
||||||
|
addCapability(CapabilityFloat64);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
|
||||||
}
|
}
|
||||||
case glslang::EShTargetVulkan_1_2:
|
case glslang::EShTargetVulkan_1_2:
|
||||||
return spv_target_env::SPV_ENV_VULKAN_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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +212,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
|
||||||
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
|
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
|
||||||
if (options->optimizeSize) {
|
if (options->optimizeSize) {
|
||||||
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass());
|
||||||
}
|
}
|
||||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
#include "spirv-tools/libspirv.h"
|
#include "spirv-tools/libspirv.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../glslang/MachineIndependent/localintermediate.h"
|
#include "glslang/MachineIndependent/localintermediate.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
|
@ -100,6 +101,7 @@ protected:
|
||||||
void outputMask(OperandClass operandClass, unsigned mask);
|
void outputMask(OperandClass operandClass, unsigned mask);
|
||||||
void disassembleImmediates(int numOperands);
|
void disassembleImmediates(int numOperands);
|
||||||
void disassembleIds(int numOperands);
|
void disassembleIds(int numOperands);
|
||||||
|
std::pair<int, std::string> decodeString();
|
||||||
int disassembleString();
|
int disassembleString();
|
||||||
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
|
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
|
// decode string from words at current position (non-consuming)
|
||||||
int SpirvStream::disassembleString()
|
std::pair<int, std::string> SpirvStream::decodeString()
|
||||||
{
|
{
|
||||||
int startWord = word;
|
std::string res;
|
||||||
|
int wordPos = word;
|
||||||
out << " \"";
|
char c;
|
||||||
|
|
||||||
const char* wordString;
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
unsigned int content = stream[word];
|
unsigned int content = stream[wordPos];
|
||||||
wordString = (const char*)&content;
|
|
||||||
for (int charCount = 0; charCount < 4; ++charCount) {
|
for (int charCount = 0; charCount < 4; ++charCount) {
|
||||||
if (*wordString == 0) {
|
c = content & 0xff;
|
||||||
|
content >>= 8;
|
||||||
|
if (c == '\0') {
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out << *(wordString++);
|
res += c;
|
||||||
}
|
}
|
||||||
++word;
|
++wordPos;
|
||||||
} while (! done);
|
} 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 << "\"";
|
out << "\"";
|
||||||
|
|
||||||
return word - startWord;
|
word += decoderes.first;
|
||||||
|
|
||||||
|
return decoderes.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
|
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;
|
nextNestedControl = 0;
|
||||||
}
|
}
|
||||||
} else if (opCode == OpExtInstImport) {
|
} else if (opCode == OpExtInstImport) {
|
||||||
idDescriptor[resultId] = (const char*)(&stream[word]);
|
idDescriptor[resultId] = decodeString().second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||||
|
@ -428,7 +443,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
--numOperands;
|
--numOperands;
|
||||||
// Get names for printing "(XXX)" for readability, *after* this id
|
// Get names for printing "(XXX)" for readability, *after* this id
|
||||||
if (opCode == OpName)
|
if (opCode == OpName)
|
||||||
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
|
idDescriptor[stream[word - 1]] = decodeString().second;
|
||||||
break;
|
break;
|
||||||
case OperandVariableIds:
|
case OperandVariableIds:
|
||||||
disassembleIds(numOperands);
|
disassembleIds(numOperands);
|
||||||
|
|
|
@ -305,7 +305,8 @@ const char* DecorationString(int decoration)
|
||||||
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||||
case DecorationPerViewNV: return "PerViewNV";
|
case DecorationPerViewNV: return "PerViewNV";
|
||||||
case DecorationPerTaskNV: return "PerTaskNV";
|
case DecorationPerTaskNV: return "PerTaskNV";
|
||||||
case DecorationPerVertexNV: return "PerVertexNV";
|
|
||||||
|
case DecorationPerVertexKHR: return "PerVertexKHR";
|
||||||
|
|
||||||
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
||||||
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||||
|
@ -392,6 +393,7 @@ const char* BuiltInString(int builtIn)
|
||||||
case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
|
case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
|
||||||
case BuiltInRayTminKHR: return "RayTminKHR";
|
case BuiltInRayTminKHR: return "RayTminKHR";
|
||||||
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
|
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
|
||||||
|
case BuiltInCullMaskKHR: return "CullMaskKHR";
|
||||||
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
|
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
|
||||||
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
|
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
|
||||||
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
|
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
|
||||||
|
@ -406,8 +408,8 @@ const char* BuiltInString(int builtIn)
|
||||||
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
|
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
|
||||||
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
||||||
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
case BuiltInBaryCoordKHR: return "BaryCoordKHR";
|
||||||
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR";
|
||||||
|
|
||||||
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
||||||
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
@ -900,6 +902,12 @@ const char* CapabilityString(int info)
|
||||||
case CapabilityDeviceGroup: return "DeviceGroup";
|
case CapabilityDeviceGroup: return "DeviceGroup";
|
||||||
case CapabilityMultiView: return "MultiView";
|
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 CapabilityStencilExportEXT: return "StencilExportEXT";
|
||||||
|
|
||||||
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
|
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
|
||||||
|
@ -919,12 +927,13 @@ const char* CapabilityString(int info)
|
||||||
case CapabilityRayTracingNV: return "RayTracingNV";
|
case CapabilityRayTracingNV: return "RayTracingNV";
|
||||||
case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
|
case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
|
||||||
case CapabilityRayTracingKHR: return "RayTracingKHR";
|
case CapabilityRayTracingKHR: return "RayTracingKHR";
|
||||||
|
case CapabilityRayCullMaskKHR: return "RayCullMaskKHR";
|
||||||
case CapabilityRayQueryKHR: return "RayQueryKHR";
|
case CapabilityRayQueryKHR: return "RayQueryKHR";
|
||||||
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
|
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
|
||||||
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
|
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
|
||||||
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
||||||
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
||||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR";
|
||||||
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||||
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT
|
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT
|
||||||
|
|
|
@ -49,12 +49,12 @@ namespace spv {
|
||||||
|
|
||||||
typedef unsigned int Id;
|
typedef unsigned int Id;
|
||||||
|
|
||||||
#define SPV_VERSION 0x10500
|
#define SPV_VERSION 0x10600
|
||||||
#define SPV_REVISION 4
|
#define SPV_REVISION 1
|
||||||
|
|
||||||
static const unsigned int MagicNumber = 0x07230203;
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
static const unsigned int Version = 0x00010500;
|
static const unsigned int Version = 0x00010600;
|
||||||
static const unsigned int Revision = 4;
|
static const unsigned int Revision = 1;
|
||||||
static const unsigned int OpCodeMask = 0xffff;
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
static const unsigned int WordCountShift = 16;
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ enum SourceLanguage {
|
||||||
SourceLanguageOpenCL_C = 3,
|
SourceLanguageOpenCL_C = 3,
|
||||||
SourceLanguageOpenCL_CPP = 4,
|
SourceLanguageOpenCL_CPP = 4,
|
||||||
SourceLanguageHLSL = 5,
|
SourceLanguageHLSL = 5,
|
||||||
|
SourceLanguageCPP_for_OpenCL = 6,
|
||||||
SourceLanguageMax = 0x7fffffff,
|
SourceLanguageMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -352,6 +353,8 @@ enum ImageOperandsShift {
|
||||||
ImageOperandsVolatileTexelKHRShift = 11,
|
ImageOperandsVolatileTexelKHRShift = 11,
|
||||||
ImageOperandsSignExtendShift = 12,
|
ImageOperandsSignExtendShift = 12,
|
||||||
ImageOperandsZeroExtendShift = 13,
|
ImageOperandsZeroExtendShift = 13,
|
||||||
|
ImageOperandsNontemporalShift = 14,
|
||||||
|
ImageOperandsOffsetsShift = 16,
|
||||||
ImageOperandsMax = 0x7fffffff,
|
ImageOperandsMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -375,6 +378,8 @@ enum ImageOperandsMask {
|
||||||
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||||
ImageOperandsSignExtendMask = 0x00001000,
|
ImageOperandsSignExtendMask = 0x00001000,
|
||||||
ImageOperandsZeroExtendMask = 0x00002000,
|
ImageOperandsZeroExtendMask = 0x00002000,
|
||||||
|
ImageOperandsNontemporalMask = 0x00004000,
|
||||||
|
ImageOperandsOffsetsMask = 0x00010000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FPFastMathModeShift {
|
enum FPFastMathModeShift {
|
||||||
|
@ -491,6 +496,7 @@ enum Decoration {
|
||||||
DecorationPerPrimitiveNV = 5271,
|
DecorationPerPrimitiveNV = 5271,
|
||||||
DecorationPerViewNV = 5272,
|
DecorationPerViewNV = 5272,
|
||||||
DecorationPerTaskNV = 5273,
|
DecorationPerTaskNV = 5273,
|
||||||
|
DecorationPerVertexKHR = 5285,
|
||||||
DecorationPerVertexNV = 5285,
|
DecorationPerVertexNV = 5285,
|
||||||
DecorationNonUniform = 5300,
|
DecorationNonUniform = 5300,
|
||||||
DecorationNonUniformEXT = 5300,
|
DecorationNonUniformEXT = 5300,
|
||||||
|
@ -498,6 +504,10 @@ enum Decoration {
|
||||||
DecorationRestrictPointerEXT = 5355,
|
DecorationRestrictPointerEXT = 5355,
|
||||||
DecorationAliasedPointer = 5356,
|
DecorationAliasedPointer = 5356,
|
||||||
DecorationAliasedPointerEXT = 5356,
|
DecorationAliasedPointerEXT = 5356,
|
||||||
|
DecorationBindlessSamplerNV = 5398,
|
||||||
|
DecorationBindlessImageNV = 5399,
|
||||||
|
DecorationBoundSamplerNV = 5400,
|
||||||
|
DecorationBoundImageNV = 5401,
|
||||||
DecorationSIMTCallINTEL = 5599,
|
DecorationSIMTCallINTEL = 5599,
|
||||||
DecorationReferencedIndirectlyINTEL = 5602,
|
DecorationReferencedIndirectlyINTEL = 5602,
|
||||||
DecorationClobberINTEL = 5607,
|
DecorationClobberINTEL = 5607,
|
||||||
|
@ -537,6 +547,7 @@ enum Decoration {
|
||||||
DecorationFunctionFloatingPointModeINTEL = 6080,
|
DecorationFunctionFloatingPointModeINTEL = 6080,
|
||||||
DecorationSingleElementVectorINTEL = 6085,
|
DecorationSingleElementVectorINTEL = 6085,
|
||||||
DecorationVectorComputeCallableFunctionINTEL = 6087,
|
DecorationVectorComputeCallableFunctionINTEL = 6087,
|
||||||
|
DecorationMediaBlockIOINTEL = 6140,
|
||||||
DecorationMax = 0x7fffffff,
|
DecorationMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -621,7 +632,9 @@ enum BuiltIn {
|
||||||
BuiltInLayerPerViewNV = 5279,
|
BuiltInLayerPerViewNV = 5279,
|
||||||
BuiltInMeshViewCountNV = 5280,
|
BuiltInMeshViewCountNV = 5280,
|
||||||
BuiltInMeshViewIndicesNV = 5281,
|
BuiltInMeshViewIndicesNV = 5281,
|
||||||
|
BuiltInBaryCoordKHR = 5286,
|
||||||
BuiltInBaryCoordNV = 5286,
|
BuiltInBaryCoordNV = 5286,
|
||||||
|
BuiltInBaryCoordNoPerspKHR = 5287,
|
||||||
BuiltInBaryCoordNoPerspNV = 5287,
|
BuiltInBaryCoordNoPerspNV = 5287,
|
||||||
BuiltInFragSizeEXT = 5292,
|
BuiltInFragSizeEXT = 5292,
|
||||||
BuiltInFragmentSizeNV = 5292,
|
BuiltInFragmentSizeNV = 5292,
|
||||||
|
@ -660,6 +673,7 @@ enum BuiltIn {
|
||||||
BuiltInSMCountNV = 5375,
|
BuiltInSMCountNV = 5375,
|
||||||
BuiltInWarpIDNV = 5376,
|
BuiltInWarpIDNV = 5376,
|
||||||
BuiltInSMIDNV = 5377,
|
BuiltInSMIDNV = 5377,
|
||||||
|
BuiltInCullMaskKHR = 6021,
|
||||||
BuiltInMax = 0x7fffffff,
|
BuiltInMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -722,6 +736,7 @@ enum FunctionControlShift {
|
||||||
FunctionControlDontInlineShift = 1,
|
FunctionControlDontInlineShift = 1,
|
||||||
FunctionControlPureShift = 2,
|
FunctionControlPureShift = 2,
|
||||||
FunctionControlConstShift = 3,
|
FunctionControlConstShift = 3,
|
||||||
|
FunctionControlOptNoneINTELShift = 16,
|
||||||
FunctionControlMax = 0x7fffffff,
|
FunctionControlMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -731,6 +746,7 @@ enum FunctionControlMask {
|
||||||
FunctionControlDontInlineMask = 0x00000002,
|
FunctionControlDontInlineMask = 0x00000002,
|
||||||
FunctionControlPureMask = 0x00000004,
|
FunctionControlPureMask = 0x00000004,
|
||||||
FunctionControlConstMask = 0x00000008,
|
FunctionControlConstMask = 0x00000008,
|
||||||
|
FunctionControlOptNoneINTELMask = 0x00010000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemorySemanticsShift {
|
enum MemorySemanticsShift {
|
||||||
|
@ -911,6 +927,7 @@ enum Capability {
|
||||||
CapabilityGroupNonUniformQuad = 68,
|
CapabilityGroupNonUniformQuad = 68,
|
||||||
CapabilityShaderLayer = 69,
|
CapabilityShaderLayer = 69,
|
||||||
CapabilityShaderViewportIndex = 70,
|
CapabilityShaderViewportIndex = 70,
|
||||||
|
CapabilityUniformDecoration = 71,
|
||||||
CapabilityFragmentShadingRateKHR = 4422,
|
CapabilityFragmentShadingRateKHR = 4422,
|
||||||
CapabilitySubgroupBallotKHR = 4423,
|
CapabilitySubgroupBallotKHR = 4423,
|
||||||
CapabilityDrawParameters = 4427,
|
CapabilityDrawParameters = 4427,
|
||||||
|
@ -959,6 +976,7 @@ enum Capability {
|
||||||
CapabilityFragmentFullyCoveredEXT = 5265,
|
CapabilityFragmentFullyCoveredEXT = 5265,
|
||||||
CapabilityMeshShadingNV = 5266,
|
CapabilityMeshShadingNV = 5266,
|
||||||
CapabilityImageFootprintNV = 5282,
|
CapabilityImageFootprintNV = 5282,
|
||||||
|
CapabilityFragmentBarycentricKHR = 5284,
|
||||||
CapabilityFragmentBarycentricNV = 5284,
|
CapabilityFragmentBarycentricNV = 5284,
|
||||||
CapabilityComputeDerivativeGroupQuadsNV = 5288,
|
CapabilityComputeDerivativeGroupQuadsNV = 5288,
|
||||||
CapabilityFragmentDensityEXT = 5291,
|
CapabilityFragmentDensityEXT = 5291,
|
||||||
|
@ -1003,7 +1021,9 @@ enum Capability {
|
||||||
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
||||||
CapabilityShaderSMBuiltinsNV = 5373,
|
CapabilityShaderSMBuiltinsNV = 5373,
|
||||||
CapabilityFragmentShaderPixelInterlockEXT = 5378,
|
CapabilityFragmentShaderPixelInterlockEXT = 5378,
|
||||||
|
CapabilityDemoteToHelperInvocation = 5379,
|
||||||
CapabilityDemoteToHelperInvocationEXT = 5379,
|
CapabilityDemoteToHelperInvocationEXT = 5379,
|
||||||
|
CapabilityBindlessTextureNV = 5390,
|
||||||
CapabilitySubgroupShuffleINTEL = 5568,
|
CapabilitySubgroupShuffleINTEL = 5568,
|
||||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||||
|
@ -1028,6 +1048,7 @@ enum Capability {
|
||||||
CapabilityFPGAMemoryAttributesINTEL = 5824,
|
CapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||||
CapabilityFPFastMathModeINTEL = 5837,
|
CapabilityFPFastMathModeINTEL = 5837,
|
||||||
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
|
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
|
||||||
|
CapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
|
||||||
CapabilityUnstructuredLoopControlsINTEL = 5886,
|
CapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||||
CapabilityFPGALoopControlsINTEL = 5888,
|
CapabilityFPGALoopControlsINTEL = 5888,
|
||||||
CapabilityKernelAttributesINTEL = 5892,
|
CapabilityKernelAttributesINTEL = 5892,
|
||||||
|
@ -1036,14 +1057,27 @@ enum Capability {
|
||||||
CapabilityFPGAClusterAttributesINTEL = 5904,
|
CapabilityFPGAClusterAttributesINTEL = 5904,
|
||||||
CapabilityLoopFuseINTEL = 5906,
|
CapabilityLoopFuseINTEL = 5906,
|
||||||
CapabilityFPGABufferLocationINTEL = 5920,
|
CapabilityFPGABufferLocationINTEL = 5920,
|
||||||
|
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||||
CapabilityUSMStorageClassesINTEL = 5935,
|
CapabilityUSMStorageClassesINTEL = 5935,
|
||||||
CapabilityIOPipesINTEL = 5943,
|
CapabilityIOPipesINTEL = 5943,
|
||||||
CapabilityBlockingPipesINTEL = 5945,
|
CapabilityBlockingPipesINTEL = 5945,
|
||||||
CapabilityFPGARegINTEL = 5948,
|
CapabilityFPGARegINTEL = 5948,
|
||||||
|
CapabilityDotProductInputAll = 6016,
|
||||||
|
CapabilityDotProductInputAllKHR = 6016,
|
||||||
|
CapabilityDotProductInput4x8Bit = 6017,
|
||||||
|
CapabilityDotProductInput4x8BitKHR = 6017,
|
||||||
|
CapabilityDotProductInput4x8BitPacked = 6018,
|
||||||
|
CapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||||
|
CapabilityDotProduct = 6019,
|
||||||
|
CapabilityDotProductKHR = 6019,
|
||||||
|
CapabilityRayCullMaskKHR = 6020,
|
||||||
|
CapabilityBitInstructions = 6025,
|
||||||
CapabilityAtomicFloat32AddEXT = 6033,
|
CapabilityAtomicFloat32AddEXT = 6033,
|
||||||
CapabilityAtomicFloat64AddEXT = 6034,
|
CapabilityAtomicFloat64AddEXT = 6034,
|
||||||
CapabilityLongConstantCompositeINTEL = 6089,
|
CapabilityLongConstantCompositeINTEL = 6089,
|
||||||
|
CapabilityOptNoneINTEL = 6094,
|
||||||
CapabilityAtomicFloat16AddEXT = 6095,
|
CapabilityAtomicFloat16AddEXT = 6095,
|
||||||
|
CapabilityDebugInfoModuleINTEL = 6114,
|
||||||
CapabilityMax = 0x7fffffff,
|
CapabilityMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1122,6 +1156,32 @@ enum FPOperationMode {
|
||||||
FPOperationModeMax = 0x7fffffff,
|
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 {
|
enum Op {
|
||||||
OpNop = 0,
|
OpNop = 0,
|
||||||
OpUndef = 1,
|
OpUndef = 1,
|
||||||
|
@ -1479,6 +1539,18 @@ enum Op {
|
||||||
OpConvertUToAccelerationStructureKHR = 4447,
|
OpConvertUToAccelerationStructureKHR = 4447,
|
||||||
OpIgnoreIntersectionKHR = 4448,
|
OpIgnoreIntersectionKHR = 4448,
|
||||||
OpTerminateRayKHR = 4449,
|
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,
|
OpTypeRayQueryKHR = 4472,
|
||||||
OpRayQueryInitializeKHR = 4473,
|
OpRayQueryInitializeKHR = 4473,
|
||||||
OpRayQueryTerminateKHR = 4474,
|
OpRayQueryTerminateKHR = 4474,
|
||||||
|
@ -1517,8 +1589,16 @@ enum Op {
|
||||||
OpCooperativeMatrixLengthNV = 5362,
|
OpCooperativeMatrixLengthNV = 5362,
|
||||||
OpBeginInvocationInterlockEXT = 5364,
|
OpBeginInvocationInterlockEXT = 5364,
|
||||||
OpEndInvocationInterlockEXT = 5365,
|
OpEndInvocationInterlockEXT = 5365,
|
||||||
|
OpDemoteToHelperInvocation = 5380,
|
||||||
OpDemoteToHelperInvocationEXT = 5380,
|
OpDemoteToHelperInvocationEXT = 5380,
|
||||||
OpIsHelperInvocationEXT = 5381,
|
OpIsHelperInvocationEXT = 5381,
|
||||||
|
OpConvertUToImageNV = 5391,
|
||||||
|
OpConvertUToSamplerNV = 5392,
|
||||||
|
OpConvertImageToUNV = 5393,
|
||||||
|
OpConvertSamplerToUNV = 5394,
|
||||||
|
OpConvertUToSampledImageNV = 5395,
|
||||||
|
OpConvertSampledImageToUNV = 5396,
|
||||||
|
OpSamplerImageAddressingModeNV = 5397,
|
||||||
OpSubgroupShuffleINTEL = 5571,
|
OpSubgroupShuffleINTEL = 5571,
|
||||||
OpSubgroupShuffleDownINTEL = 5572,
|
OpSubgroupShuffleDownINTEL = 5572,
|
||||||
OpSubgroupShuffleUpINTEL = 5573,
|
OpSubgroupShuffleUpINTEL = 5573,
|
||||||
|
@ -1543,7 +1623,7 @@ enum Op {
|
||||||
OpUSubSatINTEL = 5596,
|
OpUSubSatINTEL = 5596,
|
||||||
OpIMul32x16INTEL = 5597,
|
OpIMul32x16INTEL = 5597,
|
||||||
OpUMul32x16INTEL = 5598,
|
OpUMul32x16INTEL = 5598,
|
||||||
OpConstFunctionPointerINTEL = 5600,
|
OpConstantFunctionPointerINTEL = 5600,
|
||||||
OpFunctionPointerCallINTEL = 5601,
|
OpFunctionPointerCallINTEL = 5601,
|
||||||
OpAsmTargetINTEL = 5609,
|
OpAsmTargetINTEL = 5609,
|
||||||
OpAsmINTEL = 5610,
|
OpAsmINTEL = 5610,
|
||||||
|
@ -1677,7 +1757,59 @@ enum Op {
|
||||||
OpVariableLengthArrayINTEL = 5818,
|
OpVariableLengthArrayINTEL = 5818,
|
||||||
OpSaveMemoryINTEL = 5819,
|
OpSaveMemoryINTEL = 5819,
|
||||||
OpRestoreMemoryINTEL = 5820,
|
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,
|
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,
|
OpPtrCastToCrossWorkgroupINTEL = 5934,
|
||||||
OpCrossWorkgroupCastToPtrINTEL = 5938,
|
OpCrossWorkgroupCastToPtrINTEL = 5938,
|
||||||
OpReadPipeBlockingINTEL = 5946,
|
OpReadPipeBlockingINTEL = 5946,
|
||||||
|
@ -2069,6 +2201,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||||
case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
|
case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpTerminateRayKHR: *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 OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
|
||||||
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpRayQueryTerminateKHR: *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 OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpEndInvocationInterlockEXT: *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 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 OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupShuffleUpINTEL: *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 OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpUMul32x16INTEL: *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 OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpAsmINTEL: *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 OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; 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 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 OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
|
|
@ -111,27 +111,23 @@ public:
|
||||||
|
|
||||||
void addStringOperand(const char* str)
|
void addStringOperand(const char* str)
|
||||||
{
|
{
|
||||||
unsigned int word;
|
unsigned int word = 0;
|
||||||
char* wordString = (char*)&word;
|
unsigned int shiftAmount = 0;
|
||||||
char* wordPtr = wordString;
|
|
||||||
int charCount = 0;
|
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
c = *(str++);
|
c = *(str++);
|
||||||
*(wordPtr++) = c;
|
word |= ((unsigned int)c) << shiftAmount;
|
||||||
++charCount;
|
shiftAmount += 8;
|
||||||
if (charCount == 4) {
|
if (shiftAmount == 32) {
|
||||||
addImmediateOperand(word);
|
addImmediateOperand(word);
|
||||||
wordPtr = wordString;
|
word = 0;
|
||||||
charCount = 0;
|
shiftAmount = 0;
|
||||||
}
|
}
|
||||||
} while (c != 0);
|
} while (c != 0);
|
||||||
|
|
||||||
// deal with partial last word
|
// deal with partial last word
|
||||||
if (charCount > 0) {
|
if (shiftAmount > 0) {
|
||||||
// pad with 0s
|
|
||||||
for (; charCount < 4; ++charCount)
|
|
||||||
*(wordPtr++) = 0;
|
|
||||||
addImmediateOperand(word);
|
addImmediateOperand(word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,6 +357,14 @@ public:
|
||||||
Decoration getReturnPrecision() const
|
Decoration getReturnPrecision() const
|
||||||
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
|
{ 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; }
|
void setImplicitThis() { implicitThis = true; }
|
||||||
bool hasImplicitThis() const { return implicitThis; }
|
bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
|
||||||
|
@ -377,6 +381,11 @@ public:
|
||||||
|
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
|
// OpLine
|
||||||
|
if (lineInstruction != nullptr) {
|
||||||
|
lineInstruction->dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
// OpFunction
|
// OpFunction
|
||||||
functionInstruction.dump(out);
|
functionInstruction.dump(out);
|
||||||
|
|
||||||
|
@ -395,6 +404,7 @@ protected:
|
||||||
Function& operator=(Function&);
|
Function& operator=(Function&);
|
||||||
|
|
||||||
Module& parent;
|
Module& parent;
|
||||||
|
std::unique_ptr<Instruction> lineInstruction;
|
||||||
Instruction functionInstruction;
|
Instruction functionInstruction;
|
||||||
std::vector<Instruction*> parameterInstructions;
|
std::vector<Instruction*> parameterInstructions;
|
||||||
std::vector<Block*> blocks;
|
std::vector<Block*> blocks;
|
||||||
|
@ -461,7 +471,8 @@ protected:
|
||||||
// - the OpFunction instruction
|
// - the OpFunction instruction
|
||||||
// - all the OpFunctionParameter instructions
|
// - all the OpFunctionParameter instructions
|
||||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
__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)
|
reducedPrecisionReturn(false)
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
|
|
|
@ -27,111 +27,111 @@
|
||||||
#include <GlslangToSpv.h>
|
#include <GlslangToSpv.h>
|
||||||
|
|
||||||
static const TBuiltInResource DefaultTBuiltInResource = {
|
static const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
/* .MaxLights = */ 32,
|
/* .MaxLights = */ 32,
|
||||||
/* .MaxClipPlanes = */ 6,
|
/* .MaxClipPlanes = */ 6,
|
||||||
/* .MaxTextureUnits = */ 32,
|
/* .MaxTextureUnits = */ 32,
|
||||||
/* .MaxTextureCoords = */ 32,
|
/* .MaxTextureCoords = */ 32,
|
||||||
/* .MaxVertexAttribs = */ 64,
|
/* .MaxVertexAttribs = */ 64,
|
||||||
/* .MaxVertexUniformComponents = */ 4096,
|
/* .MaxVertexUniformComponents = */ 4096,
|
||||||
/* .MaxVaryingFloats = */ 64,
|
/* .MaxVaryingFloats = */ 64,
|
||||||
/* .MaxVertexTextureImageUnits = */ 32,
|
/* .MaxVertexTextureImageUnits = */ 32,
|
||||||
/* .MaxCombinedTextureImageUnits = */ 80,
|
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||||
/* .MaxTextureImageUnits = */ 32,
|
/* .MaxTextureImageUnits = */ 32,
|
||||||
/* .MaxFragmentUniformComponents = */ 4096,
|
/* .MaxFragmentUniformComponents = */ 4096,
|
||||||
/* .MaxDrawBuffers = */ 32,
|
/* .MaxDrawBuffers = */ 32,
|
||||||
/* .MaxVertexUniformVectors = */ 128,
|
/* .MaxVertexUniformVectors = */ 128,
|
||||||
/* .MaxVaryingVectors = */ 8,
|
/* .MaxVaryingVectors = */ 8,
|
||||||
/* .MaxFragmentUniformVectors = */ 16,
|
/* .MaxFragmentUniformVectors = */ 16,
|
||||||
/* .MaxVertexOutputVectors = */ 16,
|
/* .MaxVertexOutputVectors = */ 16,
|
||||||
/* .MaxFragmentInputVectors = */ 15,
|
/* .MaxFragmentInputVectors = */ 15,
|
||||||
/* .MinProgramTexelOffset = */ -8,
|
/* .MinProgramTexelOffset = */ -8,
|
||||||
/* .MaxProgramTexelOffset = */ 7,
|
/* .MaxProgramTexelOffset = */ 7,
|
||||||
/* .MaxClipDistances = */ 8,
|
/* .MaxClipDistances = */ 8,
|
||||||
/* .MaxComputeWorkGroupCountX = */ 65535,
|
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||||
/* .MaxComputeWorkGroupCountY = */ 65535,
|
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||||
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||||
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||||
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||||
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||||
/* .MaxComputeUniformComponents = */ 1024,
|
/* .MaxComputeUniformComponents = */ 1024,
|
||||||
/* .MaxComputeTextureImageUnits = */ 16,
|
/* .MaxComputeTextureImageUnits = */ 16,
|
||||||
/* .MaxComputeImageUniforms = */ 8,
|
/* .MaxComputeImageUniforms = */ 8,
|
||||||
/* .MaxComputeAtomicCounters = */ 8,
|
/* .MaxComputeAtomicCounters = */ 8,
|
||||||
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||||
/* .MaxVaryingComponents = */ 60,
|
/* .MaxVaryingComponents = */ 60,
|
||||||
/* .MaxVertexOutputComponents = */ 64,
|
/* .MaxVertexOutputComponents = */ 64,
|
||||||
/* .MaxGeometryInputComponents = */ 64,
|
/* .MaxGeometryInputComponents = */ 64,
|
||||||
/* .MaxGeometryOutputComponents = */ 128,
|
/* .MaxGeometryOutputComponents = */ 128,
|
||||||
/* .MaxFragmentInputComponents = */ 128,
|
/* .MaxFragmentInputComponents = */ 128,
|
||||||
/* .MaxImageUnits = */ 8,
|
/* .MaxImageUnits = */ 8,
|
||||||
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||||
/* .MaxCombinedShaderOutputResources = */ 8,
|
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||||
/* .MaxImageSamples = */ 0,
|
/* .MaxImageSamples = */ 0,
|
||||||
/* .MaxVertexImageUniforms = */ 0,
|
/* .MaxVertexImageUniforms = */ 0,
|
||||||
/* .MaxTessControlImageUniforms = */ 0,
|
/* .MaxTessControlImageUniforms = */ 0,
|
||||||
/* .MaxTessEvaluationImageUniforms = */ 0,
|
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||||
/* .MaxGeometryImageUniforms = */ 0,
|
/* .MaxGeometryImageUniforms = */ 0,
|
||||||
/* .MaxFragmentImageUniforms = */ 8,
|
/* .MaxFragmentImageUniforms = */ 8,
|
||||||
/* .MaxCombinedImageUniforms = */ 8,
|
/* .MaxCombinedImageUniforms = */ 8,
|
||||||
/* .MaxGeometryTextureImageUnits = */ 16,
|
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||||
/* .MaxGeometryOutputVertices = */ 256,
|
/* .MaxGeometryOutputVertices = */ 256,
|
||||||
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||||
/* .MaxGeometryUniformComponents = */ 1024,
|
/* .MaxGeometryUniformComponents = */ 1024,
|
||||||
/* .MaxGeometryVaryingComponents = */ 64,
|
/* .MaxGeometryVaryingComponents = */ 64,
|
||||||
/* .MaxTessControlInputComponents = */ 128,
|
/* .MaxTessControlInputComponents = */ 128,
|
||||||
/* .MaxTessControlOutputComponents = */ 128,
|
/* .MaxTessControlOutputComponents = */ 128,
|
||||||
/* .MaxTessControlTextureImageUnits = */ 16,
|
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||||
/* .MaxTessControlUniformComponents = */ 1024,
|
/* .MaxTessControlUniformComponents = */ 1024,
|
||||||
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||||
/* .MaxTessEvaluationInputComponents = */ 128,
|
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||||
/* .MaxTessEvaluationOutputComponents = */ 128,
|
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||||
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||||
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||||
/* .MaxTessPatchComponents = */ 120,
|
/* .MaxTessPatchComponents = */ 120,
|
||||||
/* .MaxPatchVertices = */ 32,
|
/* .MaxPatchVertices = */ 32,
|
||||||
/* .MaxTessGenLevel = */ 64,
|
/* .MaxTessGenLevel = */ 64,
|
||||||
/* .MaxViewports = */ 16,
|
/* .MaxViewports = */ 16,
|
||||||
/* .MaxVertexAtomicCounters = */ 0,
|
/* .MaxVertexAtomicCounters = */ 0,
|
||||||
/* .MaxTessControlAtomicCounters = */ 0,
|
/* .MaxTessControlAtomicCounters = */ 0,
|
||||||
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||||
/* .MaxGeometryAtomicCounters = */ 0,
|
/* .MaxGeometryAtomicCounters = */ 0,
|
||||||
/* .MaxFragmentAtomicCounters = */ 8,
|
/* .MaxFragmentAtomicCounters = */ 8,
|
||||||
/* .MaxCombinedAtomicCounters = */ 8,
|
/* .MaxCombinedAtomicCounters = */ 8,
|
||||||
/* .MaxAtomicCounterBindings = */ 1,
|
/* .MaxAtomicCounterBindings = */ 1,
|
||||||
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||||
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||||
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||||
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||||
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||||
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||||
/* .MaxAtomicCounterBufferSize = */ 16384,
|
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||||
/* .MaxTransformFeedbackBuffers = */ 4,
|
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||||
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||||
/* .MaxCullDistances = */ 8,
|
/* .MaxCullDistances = */ 8,
|
||||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||||
/* .MaxSamples = */ 4,
|
/* .MaxSamples = */ 4,
|
||||||
/* .maxMeshOutputVerticesNV = */ 256,
|
/* .maxMeshOutputVerticesNV = */ 256,
|
||||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||||
/* .maxMeshViewCountNV = */ 4,
|
/* .maxMeshViewCountNV = */ 4,
|
||||||
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||||
|
|
||||||
/* .limits = */ {
|
/* .limits = */ {
|
||||||
/* .nonInductiveForLoops = */ 1,
|
/* .nonInductiveForLoops = */ 1,
|
||||||
/* .whileLoops = */ 1,
|
/* .whileLoops = */ 1,
|
||||||
/* .doWhileLoops = */ 1,
|
/* .doWhileLoops = */ 1,
|
||||||
/* .generalUniformIndexing = */ 1,
|
/* .generalUniformIndexing = */ 1,
|
||||||
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
||||||
/* .generalVaryingIndexing = */ 1,
|
/* .generalVaryingIndexing = */ 1,
|
||||||
/* .generalSamplerIndexing = */ 1,
|
/* .generalSamplerIndexing = */ 1,
|
||||||
/* .generalVariableIndexing = */ 1,
|
/* .generalVariableIndexing = */ 1,
|
||||||
/* .generalConstantMatrixVectorIndexing = */ 1,
|
/* .generalConstantMatrixVectorIndexing = */ 1,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderBuilder::ShaderBuilder()
|
ShaderBuilder::ShaderBuilder()
|
||||||
|
|
|
@ -352,7 +352,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||||
vec3 origin = pixelpos.xyz;
|
vec3 origin = pixelpos.xyz;
|
||||||
vec3 direction = normalize(lightpos.xyz - pixelpos.xyz);
|
vec3 direction = normalize(lightpos.xyz - pixelpos.xyz);
|
||||||
float lightDistance = distance(pixelpos.xyz, lightpos.xyz);
|
float lightDistance = distance(pixelpos.xyz, lightpos.xyz);
|
||||||
/*
|
/*
|
||||||
rayQueryEXT rayQuery;
|
rayQueryEXT rayQuery;
|
||||||
rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, lightDistance);
|
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 0.0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue