mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Update glslang
--HG-- branch : minor
This commit is contained in:
@@ -1297,9 +1297,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT_PREPROCESSOR
|
|||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpMemory.cpp
|
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
|
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h
|
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1095,12 +1095,8 @@
|
|||||||
FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
|
FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
|
||||||
FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
|
FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
|
||||||
FAF140901E20934C00F898D2 /* PpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FEE1E20934C00F898D2 /* PpContext.h */; };
|
FAF140901E20934C00F898D2 /* PpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FEE1E20934C00F898D2 /* PpContext.h */; };
|
||||||
FAF140911E20934C00F898D2 /* PpMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */; };
|
|
||||||
FAF140921E20934C00F898D2 /* PpMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */; };
|
|
||||||
FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
|
FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
|
||||||
FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
|
FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
|
||||||
FAF140951E20934C00F898D2 /* PpSymbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */; };
|
|
||||||
FAF140961E20934C00F898D2 /* PpSymbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */; };
|
|
||||||
FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
|
FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
|
||||||
FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
|
FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
|
||||||
FAF140991E20934C00F898D2 /* PpTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF31E20934C00F898D2 /* PpTokens.h */; };
|
FAF140991E20934C00F898D2 /* PpTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF31E20934C00F898D2 /* PpTokens.h */; };
|
||||||
@@ -1914,9 +1910,7 @@
|
|||||||
FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpAtom.cpp; sourceTree = "<group>"; };
|
FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpAtom.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FED1E20934C00F898D2 /* PpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpContext.cpp; sourceTree = "<group>"; };
|
FAF13FED1E20934C00F898D2 /* PpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpContext.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FEE1E20934C00F898D2 /* PpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpContext.h; sourceTree = "<group>"; };
|
FAF13FEE1E20934C00F898D2 /* PpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpContext.h; sourceTree = "<group>"; };
|
||||||
FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpMemory.cpp; sourceTree = "<group>"; };
|
|
||||||
FAF13FF01E20934C00F898D2 /* PpScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpScanner.cpp; sourceTree = "<group>"; };
|
FAF13FF01E20934C00F898D2 /* PpScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpScanner.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpSymbols.cpp; sourceTree = "<group>"; };
|
|
||||||
FAF13FF21E20934C00F898D2 /* PpTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpTokens.cpp; sourceTree = "<group>"; };
|
FAF13FF21E20934C00F898D2 /* PpTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpTokens.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FF31E20934C00F898D2 /* PpTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpTokens.h; sourceTree = "<group>"; };
|
FAF13FF31E20934C00F898D2 /* PpTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpTokens.h; sourceTree = "<group>"; };
|
||||||
FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propagateNoContraction.cpp; sourceTree = "<group>"; };
|
FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propagateNoContraction.cpp; sourceTree = "<group>"; };
|
||||||
@@ -3471,9 +3465,7 @@
|
|||||||
FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */,
|
FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */,
|
||||||
FAF13FED1E20934C00F898D2 /* PpContext.cpp */,
|
FAF13FED1E20934C00F898D2 /* PpContext.cpp */,
|
||||||
FAF13FEE1E20934C00F898D2 /* PpContext.h */,
|
FAF13FEE1E20934C00F898D2 /* PpContext.h */,
|
||||||
FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */,
|
|
||||||
FAF13FF01E20934C00F898D2 /* PpScanner.cpp */,
|
FAF13FF01E20934C00F898D2 /* PpScanner.cpp */,
|
||||||
FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */,
|
|
||||||
FAF13FF21E20934C00F898D2 /* PpTokens.cpp */,
|
FAF13FF21E20934C00F898D2 /* PpTokens.cpp */,
|
||||||
FAF13FF31E20934C00F898D2 /* PpTokens.h */,
|
FAF13FF31E20934C00F898D2 /* PpTokens.h */,
|
||||||
);
|
);
|
||||||
@@ -4079,7 +4071,6 @@
|
|||||||
FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
||||||
FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
|
FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
|
||||||
FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */,
|
FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */,
|
||||||
FAF140921E20934C00F898D2 /* PpMemory.cpp in Sources */,
|
|
||||||
FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
||||||
FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
||||||
FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
||||||
@@ -4256,7 +4247,6 @@
|
|||||||
FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */,
|
FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */,
|
||||||
FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */,
|
FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */,
|
||||||
FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */,
|
FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */,
|
||||||
FAF140961E20934C00F898D2 /* PpSymbols.cpp in Sources */,
|
|
||||||
FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */,
|
FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */,
|
||||||
FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
|
FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
|
||||||
FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
|
FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
|
||||||
@@ -4440,7 +4430,6 @@
|
|||||||
FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
||||||
FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
||||||
FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
||||||
FAF140911E20934C00F898D2 /* PpMemory.cpp in Sources */,
|
|
||||||
FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
|
FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
|
||||||
FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
||||||
FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
|
FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
|
||||||
@@ -4617,7 +4606,6 @@
|
|||||||
FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
|
FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
|
||||||
FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
|
FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
|
||||||
FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */,
|
FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */,
|
||||||
FAF140951E20934C00F898D2 /* PpSymbols.cpp in Sources */,
|
|
||||||
FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */,
|
FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */,
|
||||||
FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */,
|
FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */,
|
||||||
FA0B7E211A95902C000E1D17 /* PolygonShape.cpp in Sources */,
|
FA0B7E211A95902C000E1D17 /* PolygonShape.cpp in Sources */,
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ enum TBasicType {
|
|||||||
EbtUint,
|
EbtUint,
|
||||||
EbtInt64,
|
EbtInt64,
|
||||||
EbtUint64,
|
EbtUint64,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EbtInt16,
|
||||||
|
EbtUint16,
|
||||||
|
#endif
|
||||||
EbtBool,
|
EbtBool,
|
||||||
EbtAtomicUint,
|
EbtAtomicUint,
|
||||||
EbtSampler,
|
EbtSampler,
|
||||||
@@ -203,6 +207,9 @@ enum TBuiltInVariable {
|
|||||||
EbvBaryCoordPullModel,
|
EbvBaryCoordPullModel,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EbvViewIndex,
|
||||||
|
EbvDeviceIndex,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
EbvViewportMaskNV,
|
EbvViewportMaskNV,
|
||||||
EbvSecondaryPositionNV,
|
EbvSecondaryPositionNV,
|
||||||
@@ -210,10 +217,22 @@ enum TBuiltInVariable {
|
|||||||
EbvPositionPerViewNV,
|
EbvPositionPerViewNV,
|
||||||
EbvViewportMaskPerViewNV,
|
EbvViewportMaskPerViewNV,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// HLSL built-ins that live only temporarily, until they get remapped
|
// HLSL built-ins that live only temporarily, until they get remapped
|
||||||
// to one of the above.
|
// to one of the above.
|
||||||
EbvFragDepthGreater,
|
EbvFragDepthGreater,
|
||||||
EbvFragDepthLesser,
|
EbvFragDepthLesser,
|
||||||
|
EbvStencilRef,
|
||||||
|
EbvGsOutputStream,
|
||||||
|
EbvOutputPatch,
|
||||||
|
EbvInputPatch,
|
||||||
|
|
||||||
|
// structbuffer types
|
||||||
|
EbvAppendConsume, // no need to differentiate append and consume
|
||||||
|
EbvRWStructuredBuffer,
|
||||||
|
EbvStructuredBuffer,
|
||||||
|
EbvByteAddressBuffer,
|
||||||
|
EbvRWByteAddressBuffer,
|
||||||
|
|
||||||
EbvLast
|
EbvLast
|
||||||
};
|
};
|
||||||
@@ -323,6 +342,10 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
||||||
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case EbvViewIndex: return "ViewIndex";
|
||||||
|
case EbvDeviceIndex: return "DeviceIndex";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
|||||||
@@ -43,6 +43,8 @@
|
|||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
#include "arrays.h"
|
#include "arrays.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
|
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
|
||||||
@@ -396,11 +398,13 @@ public:
|
|||||||
invariant = false;
|
invariant = false;
|
||||||
noContraction = false;
|
noContraction = false;
|
||||||
makeTemporary();
|
makeTemporary();
|
||||||
|
declaredBuiltIn = EbvNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop qualifiers that don't belong in a temporary variable
|
// drop qualifiers that don't belong in a temporary variable
|
||||||
void makeTemporary()
|
void makeTemporary()
|
||||||
{
|
{
|
||||||
|
semanticName = nullptr;
|
||||||
storage = EvqTemporary;
|
storage = EvqTemporary;
|
||||||
builtIn = EbvNone;
|
builtIn = EbvNone;
|
||||||
clearInterstage();
|
clearInterstage();
|
||||||
@@ -449,8 +453,10 @@ public:
|
|||||||
specConstant = false;
|
specConstant = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* semanticName;
|
||||||
TStorageQualifier storage : 6;
|
TStorageQualifier storage : 6;
|
||||||
TBuiltInVariable builtIn : 8;
|
TBuiltInVariable builtIn : 8;
|
||||||
|
TBuiltInVariable declaredBuiltIn : 8;
|
||||||
TPrecisionQualifier precision : 3;
|
TPrecisionQualifier precision : 3;
|
||||||
bool invariant : 1; // require canonical treatment for cross-shader invariance
|
bool invariant : 1; // require canonical treatment for cross-shader invariance
|
||||||
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
|
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
|
||||||
@@ -1302,6 +1308,7 @@ public:
|
|||||||
|
|
||||||
virtual TBasicType getBasicType() const { return basicType; }
|
virtual TBasicType getBasicType() const { return basicType; }
|
||||||
virtual const TSampler& getSampler() const { return sampler; }
|
virtual const TSampler& getSampler() const { return sampler; }
|
||||||
|
virtual TSampler& getSampler() { return sampler; }
|
||||||
|
|
||||||
virtual TQualifier& getQualifier() { return qualifier; }
|
virtual TQualifier& getQualifier() { return qualifier; }
|
||||||
virtual const TQualifier& getQualifier() const { return qualifier; }
|
virtual const TQualifier& getQualifier() const { return qualifier; }
|
||||||
@@ -1378,127 +1385,84 @@ public:
|
|||||||
return !isPerVertexAndBuiltIn(language);
|
return !isPerVertexAndBuiltIn(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if this type contains any subtype which satisfies the given predicate.
|
||||||
|
template <typename P>
|
||||||
|
bool contains(P predicate) const
|
||||||
|
{
|
||||||
|
if (predicate(this))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
|
||||||
|
|
||||||
|
return structure && std::any_of(structure->begin(), structure->end(), hasa);
|
||||||
|
}
|
||||||
|
|
||||||
// Recursively checks if the type contains the given basic type
|
// Recursively checks if the type contains the given basic type
|
||||||
virtual bool containsBasicType(TBasicType checkType) const
|
virtual bool containsBasicType(TBasicType checkType) const
|
||||||
{
|
{
|
||||||
if (basicType == checkType)
|
return contains([checkType](const TType* t) { return t->basicType == checkType; } );
|
||||||
return true;
|
|
||||||
if (! structure)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsBasicType(checkType))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively check the structure for any arrays, needed for some error checks
|
// Recursively check the structure for any arrays, needed for some error checks
|
||||||
virtual bool containsArray() const
|
virtual bool containsArray() const
|
||||||
{
|
{
|
||||||
if (isArray())
|
return contains([](const TType* t) { return t->isArray(); } );
|
||||||
return true;
|
|
||||||
if (structure == nullptr)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsArray())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the structure for any structures, needed for some error checks
|
// Check the structure for any structures, needed for some error checks
|
||||||
virtual bool containsStructure() const
|
virtual bool containsStructure() const
|
||||||
{
|
{
|
||||||
if (structure == nullptr)
|
return contains([this](const TType* t) { return t != this && t->isStruct(); } );
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->structure)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
|
// Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
|
||||||
virtual bool containsImplicitlySizedArray() const
|
virtual bool containsImplicitlySizedArray() const
|
||||||
{
|
{
|
||||||
if (isImplicitlySizedArray())
|
return contains([](const TType* t) { return t->isImplicitlySizedArray(); } );
|
||||||
return true;
|
|
||||||
if (structure == nullptr)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsImplicitlySizedArray())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool containsOpaque() const
|
virtual bool containsOpaque() const
|
||||||
{
|
{
|
||||||
if (isOpaque())
|
return contains([](const TType* t) { return t->isOpaque(); } );
|
||||||
return true;
|
|
||||||
if (! structure)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsOpaque())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively checks if the type contains an interstage IO builtin
|
// Recursively checks if the type contains an interstage IO builtin
|
||||||
virtual bool containsBuiltInInterstageIO(EShLanguage language) const
|
virtual bool containsBuiltInInterstageIO(EShLanguage language) const
|
||||||
{
|
{
|
||||||
if (isBuiltInInterstageIO(language))
|
return contains([language](const TType* t) { return t->isBuiltInInterstageIO(language); } );
|
||||||
return true;
|
|
||||||
|
|
||||||
if (! structure)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsBuiltInInterstageIO(language))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool containsNonOpaque() const
|
virtual bool containsNonOpaque() const
|
||||||
{
|
{
|
||||||
// list all non-opaque types
|
const auto nonOpaque = [](const TType* t) {
|
||||||
switch (basicType) {
|
switch (t->basicType) {
|
||||||
case EbtVoid:
|
case EbtVoid:
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
#endif
|
#endif
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
case EbtBool:
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
|
case EbtBool:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (! structure)
|
|
||||||
return false;
|
return false;
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
}
|
||||||
if ((*structure)[i].type->containsNonOpaque())
|
};
|
||||||
return true;
|
|
||||||
}
|
return contains(nonOpaque);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool containsSpecializationSize() const
|
virtual bool containsSpecializationSize() const
|
||||||
{
|
{
|
||||||
if (isArray() && arraySizes->containsNode())
|
return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
|
||||||
return true;
|
|
||||||
if (! structure)
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
|
||||||
if ((*structure)[i].type->containsSpecializationSize())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array editing methods. Array descriptors can be shared across
|
// Array editing methods. Array descriptors can be shared across
|
||||||
@@ -1569,6 +1533,10 @@ public:
|
|||||||
case EbtUint: return "uint";
|
case EbtUint: return "uint";
|
||||||
case EbtInt64: return "int64_t";
|
case EbtInt64: return "int64_t";
|
||||||
case EbtUint64: return "uint64_t";
|
case EbtUint64: return "uint64_t";
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: return "int16_t";
|
||||||
|
case EbtUint16: return "uint16_t";
|
||||||
|
#endif
|
||||||
case EbtBool: return "bool";
|
case EbtBool: return "bool";
|
||||||
case EbtAtomicUint: return "atomic_uint";
|
case EbtAtomicUint: return "atomic_uint";
|
||||||
case EbtSampler: return "sampler/image";
|
case EbtSampler: return "sampler/image";
|
||||||
@@ -1580,10 +1548,11 @@ public:
|
|||||||
|
|
||||||
TString getCompleteString() const
|
TString getCompleteString() const
|
||||||
{
|
{
|
||||||
const int maxSize = GlslangMaxTypeLength;
|
TString typeString;
|
||||||
char buf[maxSize];
|
|
||||||
char* p = &buf[0];
|
const auto appendStr = [&](const char* s) { typeString.append(s); };
|
||||||
char* end = &buf[maxSize];
|
const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
|
||||||
|
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
|
||||||
|
|
||||||
if (qualifier.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
|
||||||
@@ -1591,137 +1560,175 @@ public:
|
|||||||
TQualifier noXfbBuffer = qualifier;
|
TQualifier noXfbBuffer = qualifier;
|
||||||
noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
|
noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
|
||||||
if (noXfbBuffer.hasLayout()) {
|
if (noXfbBuffer.hasLayout()) {
|
||||||
p += snprintf(p, end - p, "layout(");
|
appendStr("layout(");
|
||||||
if (qualifier.hasAnyLocation()) {
|
if (qualifier.hasAnyLocation()) {
|
||||||
p += snprintf(p, end - p, "location=%d ", qualifier.layoutLocation);
|
appendStr(" location=");
|
||||||
if (qualifier.hasComponent())
|
appendUint(qualifier.layoutLocation);
|
||||||
p += snprintf(p, end - p, "component=%d ", qualifier.layoutComponent);
|
if (qualifier.hasComponent()) {
|
||||||
if (qualifier.hasIndex())
|
appendStr(" component=");
|
||||||
p += snprintf(p, end - p, "index=%d ", qualifier.layoutIndex);
|
appendUint(qualifier.layoutComponent);
|
||||||
|
}
|
||||||
|
if (qualifier.hasIndex()) {
|
||||||
|
appendStr(" index=");
|
||||||
|
appendUint(qualifier.layoutIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (qualifier.hasSet()) {
|
||||||
|
appendStr(" set=");
|
||||||
|
appendUint(qualifier.layoutSet);
|
||||||
|
}
|
||||||
|
if (qualifier.hasBinding()) {
|
||||||
|
appendStr(" binding=");
|
||||||
|
appendUint(qualifier.layoutBinding);
|
||||||
|
}
|
||||||
|
if (qualifier.hasStream()) {
|
||||||
|
appendStr(" stream=");
|
||||||
|
appendUint(qualifier.layoutStream);
|
||||||
|
}
|
||||||
|
if (qualifier.hasMatrix()) {
|
||||||
|
appendStr(" ");
|
||||||
|
appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
|
||||||
|
}
|
||||||
|
if (qualifier.hasPacking()) {
|
||||||
|
appendStr(" ");
|
||||||
|
appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking));
|
||||||
|
}
|
||||||
|
if (qualifier.hasOffset()) {
|
||||||
|
appendStr(" offset=");
|
||||||
|
appendInt(qualifier.layoutOffset);
|
||||||
|
}
|
||||||
|
if (qualifier.hasAlign()) {
|
||||||
|
appendStr(" align=");
|
||||||
|
appendInt(qualifier.layoutAlign);
|
||||||
|
}
|
||||||
|
if (qualifier.hasFormat()) {
|
||||||
|
appendStr(" ");
|
||||||
|
appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat));
|
||||||
|
}
|
||||||
|
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) {
|
||||||
|
appendStr(" xfb_buffer=");
|
||||||
|
appendUint(qualifier.layoutXfbBuffer);
|
||||||
|
}
|
||||||
|
if (qualifier.hasXfbOffset()) {
|
||||||
|
appendStr(" xfb_offset=");
|
||||||
|
appendUint(qualifier.layoutXfbOffset);
|
||||||
|
}
|
||||||
|
if (qualifier.hasXfbStride()) {
|
||||||
|
appendStr(" xfb_stride=");
|
||||||
|
appendUint(qualifier.layoutXfbStride);
|
||||||
|
}
|
||||||
|
if (qualifier.hasAttachment()) {
|
||||||
|
appendStr(" input_attachment_index=");
|
||||||
|
appendUint(qualifier.layoutAttachment);
|
||||||
|
}
|
||||||
|
if (qualifier.hasSpecConstantId()) {
|
||||||
|
appendStr(" constant_id=");
|
||||||
|
appendUint(qualifier.layoutSpecConstantId);
|
||||||
}
|
}
|
||||||
if (qualifier.hasSet())
|
|
||||||
p += snprintf(p, end - p, "set=%d ", qualifier.layoutSet);
|
|
||||||
if (qualifier.hasBinding())
|
|
||||||
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
|
|
||||||
if (qualifier.hasStream())
|
|
||||||
p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream);
|
|
||||||
if (qualifier.hasMatrix())
|
|
||||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
|
|
||||||
if (qualifier.hasPacking())
|
|
||||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking));
|
|
||||||
if (qualifier.hasOffset())
|
|
||||||
p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
|
|
||||||
if (qualifier.hasAlign())
|
|
||||||
p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
|
|
||||||
if (qualifier.hasFormat())
|
|
||||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutFormatString(qualifier.layoutFormat));
|
|
||||||
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset())
|
|
||||||
p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer);
|
|
||||||
if (qualifier.hasXfbOffset())
|
|
||||||
p += snprintf(p, end - p, "xfb_offset=%d ", qualifier.layoutXfbOffset);
|
|
||||||
if (qualifier.hasXfbStride())
|
|
||||||
p += snprintf(p, end - p, "xfb_stride=%d ", qualifier.layoutXfbStride);
|
|
||||||
if (qualifier.hasAttachment())
|
|
||||||
p += snprintf(p, end - p, "input_attachment_index=%d ", qualifier.layoutAttachment);
|
|
||||||
if (qualifier.hasSpecConstantId())
|
|
||||||
p += snprintf(p, end - p, "constant_id=%d ", qualifier.layoutSpecConstantId);
|
|
||||||
if (qualifier.layoutPushConstant)
|
if (qualifier.layoutPushConstant)
|
||||||
p += snprintf(p, end - p, "push_constant ");
|
appendStr(" push_constant");
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (qualifier.layoutPassthrough)
|
if (qualifier.layoutPassthrough)
|
||||||
p += snprintf(p, end - p, "passthrough ");
|
appendStr(" passthrough");
|
||||||
if (qualifier.layoutViewportRelative)
|
if (qualifier.layoutViewportRelative)
|
||||||
p += snprintf(p, end - p, "layoutViewportRelative ");
|
appendStr(" layoutViewportRelative");
|
||||||
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048)
|
if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
|
||||||
p += snprintf(p, end - p, "layoutSecondaryViewportRelativeOffset=%d ", qualifier.layoutSecondaryViewportRelativeOffset);
|
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
||||||
|
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p += snprintf(p, end - p, ") ");
|
appendStr(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qualifier.invariant)
|
if (qualifier.invariant)
|
||||||
p += snprintf(p, end - p, "invariant ");
|
appendStr(" invariant");
|
||||||
if (qualifier.noContraction)
|
if (qualifier.noContraction)
|
||||||
p += snprintf(p, end - p, "noContraction ");
|
appendStr(" noContraction");
|
||||||
if (qualifier.centroid)
|
if (qualifier.centroid)
|
||||||
p += snprintf(p, end - p, "centroid ");
|
appendStr(" centroid");
|
||||||
if (qualifier.smooth)
|
if (qualifier.smooth)
|
||||||
p += snprintf(p, end - p, "smooth ");
|
appendStr(" smooth");
|
||||||
if (qualifier.flat)
|
if (qualifier.flat)
|
||||||
p += snprintf(p, end - p, "flat ");
|
appendStr(" flat");
|
||||||
if (qualifier.nopersp)
|
if (qualifier.nopersp)
|
||||||
p += snprintf(p, end - p, "noperspective ");
|
appendStr(" noperspective");
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
if (qualifier.explicitInterp)
|
if (qualifier.explicitInterp)
|
||||||
p += snprintf(p, end - p, "__explicitInterpAMD ");
|
appendStr(" __explicitInterpAMD");
|
||||||
#endif
|
#endif
|
||||||
if (qualifier.patch)
|
if (qualifier.patch)
|
||||||
p += snprintf(p, end - p, "patch ");
|
appendStr(" patch");
|
||||||
if (qualifier.sample)
|
if (qualifier.sample)
|
||||||
p += snprintf(p, end - p, "sample ");
|
appendStr(" sample");
|
||||||
if (qualifier.coherent)
|
if (qualifier.coherent)
|
||||||
p += snprintf(p, end - p, "coherent ");
|
appendStr(" coherent");
|
||||||
if (qualifier.volatil)
|
if (qualifier.volatil)
|
||||||
p += snprintf(p, end - p, "volatile ");
|
appendStr(" volatile");
|
||||||
if (qualifier.restrict)
|
if (qualifier.restrict)
|
||||||
p += snprintf(p, end - p, "restrict ");
|
appendStr(" restrict");
|
||||||
if (qualifier.readonly)
|
if (qualifier.readonly)
|
||||||
p += snprintf(p, end - p, "readonly ");
|
appendStr(" readonly");
|
||||||
if (qualifier.writeonly)
|
if (qualifier.writeonly)
|
||||||
p += snprintf(p, end - p, "writeonly ");
|
appendStr(" writeonly");
|
||||||
if (qualifier.specConstant)
|
if (qualifier.specConstant)
|
||||||
p += snprintf(p, end - p, "specialization-constant ");
|
appendStr(" specialization-constant");
|
||||||
p += snprintf(p, end - p, "%s ", getStorageQualifierString());
|
appendStr(" ");
|
||||||
|
appendStr(getStorageQualifierString());
|
||||||
if (isArray()) {
|
if (isArray()) {
|
||||||
for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
|
for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
|
||||||
int size = arraySizes->getDimSize(i);
|
int size = arraySizes->getDimSize(i);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
p += snprintf(p, end - p, "implicitly-sized array of ");
|
appendStr(" implicitly-sized array of");
|
||||||
else
|
else {
|
||||||
p += snprintf(p, end - p, "%d-element array of ", arraySizes->getDimSize(i));
|
appendStr(" ");
|
||||||
|
appendInt(arraySizes->getDimSize(i));
|
||||||
|
appendStr("-element array of");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (qualifier.precision != EpqNone)
|
if (qualifier.precision != EpqNone) {
|
||||||
p += snprintf(p, end - p, "%s ", getPrecisionQualifierString());
|
appendStr(" ");
|
||||||
if (isMatrix())
|
appendStr(getPrecisionQualifierString());
|
||||||
p += snprintf(p, end - p, "%dX%d matrix of ", matrixCols, matrixRows);
|
}
|
||||||
else if (isVector())
|
if (isMatrix()) {
|
||||||
p += snprintf(p, end - p, "%d-component vector of ", vectorSize);
|
appendStr(" ");
|
||||||
|
appendInt(matrixCols);
|
||||||
|
appendStr("X");
|
||||||
|
appendInt(matrixRows);
|
||||||
|
appendStr(" matrix of");
|
||||||
|
} else if (isVector()) {
|
||||||
|
appendStr(" ");
|
||||||
|
appendInt(vectorSize);
|
||||||
|
appendStr("-component vector of");
|
||||||
|
}
|
||||||
|
|
||||||
*p = 0;
|
appendStr(" ");
|
||||||
TString s(buf);
|
typeString.append(getBasicTypeString());
|
||||||
s.append(getBasicTypeString());
|
|
||||||
|
|
||||||
if (qualifier.builtIn != EbvNone) {
|
if (qualifier.builtIn != EbvNone) {
|
||||||
s.append(" ");
|
appendStr(" ");
|
||||||
s.append(getBuiltInVariableString());
|
appendStr(getBuiltInVariableString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add struct/block members
|
// Add struct/block members
|
||||||
if (structure) {
|
if (structure) {
|
||||||
s.append("{");
|
appendStr("{");
|
||||||
for (size_t i = 0; i < structure->size(); ++i) {
|
for (size_t i = 0; i < structure->size(); ++i) {
|
||||||
if (s.size() > 3 * GlslangMaxTypeLength) {
|
|
||||||
// If we are getting too long, cut it short,
|
|
||||||
// just need to draw the line somewhere, as there is no limit to
|
|
||||||
// how large a struct/block type can get.
|
|
||||||
s.append("...");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (! (*structure)[i].type->hiddenMember()) {
|
if (! (*structure)[i].type->hiddenMember()) {
|
||||||
s.append((*structure)[i].type->getCompleteString());
|
typeString.append((*structure)[i].type->getCompleteString());
|
||||||
s.append(" ");
|
typeString.append(" ");
|
||||||
s.append((*structure)[i].type->getFieldName());
|
typeString.append((*structure)[i].type->getFieldName());
|
||||||
if (i < structure->size() - 1)
|
if (i < structure->size() - 1)
|
||||||
s.append(", ");
|
appendStr(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.append("}");
|
appendStr("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return typeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
TString getBasicTypeString() const
|
TString getBasicTypeString() const
|
||||||
@@ -1759,7 +1766,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append this type's mangled name to the passed in 'name'
|
// append this type's mangled name to the passed in 'name'
|
||||||
void appendMangledName(TString& name)
|
void appendMangledName(TString& name) const
|
||||||
{
|
{
|
||||||
buildMangledName(name);
|
buildMangledName(name);
|
||||||
name += ';' ;
|
name += ';' ;
|
||||||
@@ -1883,7 +1890,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void buildMangledName(TString&);
|
void buildMangledName(TString&) const;
|
||||||
|
|
||||||
TBasicType basicType : 8;
|
TBasicType basicType : 8;
|
||||||
int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
|
int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
|
||||||
|
|||||||
@@ -264,6 +264,20 @@ struct TArraySizes {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool isInnerSpecialization() const
|
||||||
|
{
|
||||||
|
for (int d = 1; d < sizes.size(); ++d) {
|
||||||
|
if (sizes.getDimNode(d) != nullptr)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isOuterSpecialization()
|
||||||
|
{
|
||||||
|
return sizes.getDimNode(0) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
|
bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
|
||||||
void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
|
void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
|
||||||
void dereference() { sizes.pop_front(); }
|
void dereference() { sizes.pop_front(); }
|
||||||
@@ -288,18 +302,6 @@ struct TArraySizes {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if any of the dimensions of the array is sized with a node
|
|
||||||
// instead of a front-end compile-time constant.
|
|
||||||
bool containsNode()
|
|
||||||
{
|
|
||||||
for (int d = 0; d < sizes.size(); ++d) {
|
|
||||||
if (sizes.getDimNode(d) != nullptr)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
||||||
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,42 @@ enum TOperator {
|
|||||||
EOpConvFloat16ToDouble,
|
EOpConvFloat16ToDouble,
|
||||||
EOpConvFloat16ToInt64,
|
EOpConvFloat16ToInt64,
|
||||||
EOpConvFloat16ToUint64,
|
EOpConvFloat16ToUint64,
|
||||||
|
|
||||||
|
EOpConvBoolToInt16,
|
||||||
|
EOpConvIntToInt16,
|
||||||
|
EOpConvUintToInt16,
|
||||||
|
EOpConvFloatToInt16,
|
||||||
|
EOpConvDoubleToInt16,
|
||||||
|
EOpConvFloat16ToInt16,
|
||||||
|
EOpConvInt64ToInt16,
|
||||||
|
EOpConvUint64ToInt16,
|
||||||
|
EOpConvUint16ToInt16,
|
||||||
|
EOpConvInt16ToBool,
|
||||||
|
EOpConvInt16ToInt,
|
||||||
|
EOpConvInt16ToUint,
|
||||||
|
EOpConvInt16ToFloat,
|
||||||
|
EOpConvInt16ToDouble,
|
||||||
|
EOpConvInt16ToFloat16,
|
||||||
|
EOpConvInt16ToInt64,
|
||||||
|
EOpConvInt16ToUint64,
|
||||||
|
|
||||||
|
EOpConvBoolToUint16,
|
||||||
|
EOpConvIntToUint16,
|
||||||
|
EOpConvUintToUint16,
|
||||||
|
EOpConvFloatToUint16,
|
||||||
|
EOpConvDoubleToUint16,
|
||||||
|
EOpConvFloat16ToUint16,
|
||||||
|
EOpConvInt64ToUint16,
|
||||||
|
EOpConvUint64ToUint16,
|
||||||
|
EOpConvInt16ToUint16,
|
||||||
|
EOpConvUint16ToBool,
|
||||||
|
EOpConvUint16ToInt,
|
||||||
|
EOpConvUint16ToUint,
|
||||||
|
EOpConvUint16ToFloat,
|
||||||
|
EOpConvUint16ToDouble,
|
||||||
|
EOpConvUint16ToFloat16,
|
||||||
|
EOpConvUint16ToInt64,
|
||||||
|
EOpConvUint16ToUint64,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -183,6 +219,7 @@ enum TOperator {
|
|||||||
EOpVectorSwizzle,
|
EOpVectorSwizzle,
|
||||||
|
|
||||||
EOpMethod,
|
EOpMethod,
|
||||||
|
EOpScoping,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Built-in functions mapped to operators
|
// Built-in functions mapped to operators
|
||||||
@@ -243,6 +280,12 @@ enum TOperator {
|
|||||||
EOpDoubleBitsToUint64,
|
EOpDoubleBitsToUint64,
|
||||||
EOpInt64BitsToDouble,
|
EOpInt64BitsToDouble,
|
||||||
EOpUint64BitsToDouble,
|
EOpUint64BitsToDouble,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpFloat16BitsToInt16,
|
||||||
|
EOpFloat16BitsToUint16,
|
||||||
|
EOpInt16BitsToFloat16,
|
||||||
|
EOpUint16BitsToFloat16,
|
||||||
|
#endif
|
||||||
EOpPackSnorm2x16,
|
EOpPackSnorm2x16,
|
||||||
EOpUnpackSnorm2x16,
|
EOpUnpackSnorm2x16,
|
||||||
EOpPackUnorm2x16,
|
EOpPackUnorm2x16,
|
||||||
@@ -262,6 +305,14 @@ enum TOperator {
|
|||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
EOpPackFloat2x16,
|
EOpPackFloat2x16,
|
||||||
EOpUnpackFloat2x16,
|
EOpUnpackFloat2x16,
|
||||||
|
EOpPackInt2x16,
|
||||||
|
EOpUnpackInt2x16,
|
||||||
|
EOpPackUint2x16,
|
||||||
|
EOpUnpackUint2x16,
|
||||||
|
EOpPackInt4x16,
|
||||||
|
EOpUnpackInt4x16,
|
||||||
|
EOpPackUint4x16,
|
||||||
|
EOpUnpackUint4x16,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EOpLength,
|
EOpLength,
|
||||||
@@ -393,15 +444,27 @@ enum TOperator {
|
|||||||
EOpConstructUint,
|
EOpConstructUint,
|
||||||
EOpConstructInt64,
|
EOpConstructInt64,
|
||||||
EOpConstructUint64,
|
EOpConstructUint64,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpConstructInt16,
|
||||||
|
EOpConstructUint16,
|
||||||
|
#endif
|
||||||
EOpConstructBool,
|
EOpConstructBool,
|
||||||
EOpConstructFloat,
|
EOpConstructFloat,
|
||||||
EOpConstructDouble,
|
EOpConstructDouble,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpConstructFloat16,
|
||||||
|
#endif
|
||||||
EOpConstructVec2,
|
EOpConstructVec2,
|
||||||
EOpConstructVec3,
|
EOpConstructVec3,
|
||||||
EOpConstructVec4,
|
EOpConstructVec4,
|
||||||
EOpConstructDVec2,
|
EOpConstructDVec2,
|
||||||
EOpConstructDVec3,
|
EOpConstructDVec3,
|
||||||
EOpConstructDVec4,
|
EOpConstructDVec4,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpConstructF16Vec2,
|
||||||
|
EOpConstructF16Vec3,
|
||||||
|
EOpConstructF16Vec4,
|
||||||
|
#endif
|
||||||
EOpConstructBVec2,
|
EOpConstructBVec2,
|
||||||
EOpConstructBVec3,
|
EOpConstructBVec3,
|
||||||
EOpConstructBVec4,
|
EOpConstructBVec4,
|
||||||
@@ -417,6 +480,14 @@ enum TOperator {
|
|||||||
EOpConstructU64Vec2,
|
EOpConstructU64Vec2,
|
||||||
EOpConstructU64Vec3,
|
EOpConstructU64Vec3,
|
||||||
EOpConstructU64Vec4,
|
EOpConstructU64Vec4,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpConstructI16Vec2,
|
||||||
|
EOpConstructI16Vec3,
|
||||||
|
EOpConstructI16Vec4,
|
||||||
|
EOpConstructU16Vec2,
|
||||||
|
EOpConstructU16Vec3,
|
||||||
|
EOpConstructU16Vec4,
|
||||||
|
#endif
|
||||||
EOpConstructMat2x2,
|
EOpConstructMat2x2,
|
||||||
EOpConstructMat2x3,
|
EOpConstructMat2x3,
|
||||||
EOpConstructMat2x4,
|
EOpConstructMat2x4,
|
||||||
@@ -435,11 +506,34 @@ enum TOperator {
|
|||||||
EOpConstructDMat4x2,
|
EOpConstructDMat4x2,
|
||||||
EOpConstructDMat4x3,
|
EOpConstructDMat4x3,
|
||||||
EOpConstructDMat4x4,
|
EOpConstructDMat4x4,
|
||||||
|
EOpConstructIMat2x2,
|
||||||
|
EOpConstructIMat2x3,
|
||||||
|
EOpConstructIMat2x4,
|
||||||
|
EOpConstructIMat3x2,
|
||||||
|
EOpConstructIMat3x3,
|
||||||
|
EOpConstructIMat3x4,
|
||||||
|
EOpConstructIMat4x2,
|
||||||
|
EOpConstructIMat4x3,
|
||||||
|
EOpConstructIMat4x4,
|
||||||
|
EOpConstructUMat2x2,
|
||||||
|
EOpConstructUMat2x3,
|
||||||
|
EOpConstructUMat2x4,
|
||||||
|
EOpConstructUMat3x2,
|
||||||
|
EOpConstructUMat3x3,
|
||||||
|
EOpConstructUMat3x4,
|
||||||
|
EOpConstructUMat4x2,
|
||||||
|
EOpConstructUMat4x3,
|
||||||
|
EOpConstructUMat4x4,
|
||||||
|
EOpConstructBMat2x2,
|
||||||
|
EOpConstructBMat2x3,
|
||||||
|
EOpConstructBMat2x4,
|
||||||
|
EOpConstructBMat3x2,
|
||||||
|
EOpConstructBMat3x3,
|
||||||
|
EOpConstructBMat3x4,
|
||||||
|
EOpConstructBMat4x2,
|
||||||
|
EOpConstructBMat4x3,
|
||||||
|
EOpConstructBMat4x4,
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
EOpConstructFloat16,
|
|
||||||
EOpConstructF16Vec2,
|
|
||||||
EOpConstructF16Vec3,
|
|
||||||
EOpConstructF16Vec4,
|
|
||||||
EOpConstructF16Mat2x2,
|
EOpConstructF16Mat2x2,
|
||||||
EOpConstructF16Mat2x3,
|
EOpConstructF16Mat2x3,
|
||||||
EOpConstructF16Mat2x4,
|
EOpConstructF16Mat2x4,
|
||||||
@@ -539,6 +633,11 @@ enum TOperator {
|
|||||||
EOpTextureOffsetClamp,
|
EOpTextureOffsetClamp,
|
||||||
EOpTextureGradClamp,
|
EOpTextureGradClamp,
|
||||||
EOpTextureGradOffsetClamp,
|
EOpTextureGradOffsetClamp,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpTextureGatherLod,
|
||||||
|
EOpTextureGatherLodOffset,
|
||||||
|
EOpTextureGatherLodOffsets,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpSparseTextureGuardBegin,
|
EOpSparseTextureGuardBegin,
|
||||||
|
|
||||||
@@ -558,6 +657,11 @@ enum TOperator {
|
|||||||
EOpSparseTextureOffsetClamp,
|
EOpSparseTextureOffsetClamp,
|
||||||
EOpSparseTextureGradClamp,
|
EOpSparseTextureGradClamp,
|
||||||
EOpSparseTextureGradOffsetClamp,
|
EOpSparseTextureGradOffsetClamp,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpSparseTextureGatherLod,
|
||||||
|
EOpSparseTextureGatherLodOffset,
|
||||||
|
EOpSparseTextureGatherLodOffsets,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpSparseTextureGuardEnd,
|
EOpSparseTextureGuardEnd,
|
||||||
EOpSamplingGuardEnd,
|
EOpSamplingGuardEnd,
|
||||||
@@ -624,6 +728,19 @@ enum TOperator {
|
|||||||
EOpMethodCalculateLevelOfDetail, // ...
|
EOpMethodCalculateLevelOfDetail, // ...
|
||||||
EOpMethodCalculateLevelOfDetailUnclamped, // ...
|
EOpMethodCalculateLevelOfDetailUnclamped, // ...
|
||||||
|
|
||||||
|
// Load already defined above for textures
|
||||||
|
EOpMethodLoad2, // Structure buffer object methods. These are translated to existing
|
||||||
|
EOpMethodLoad3, // AST methods, and exist to represent HLSL semantics until that
|
||||||
|
EOpMethodLoad4, // translation is performed. See HlslParseContext::decomposeSampleMethods().
|
||||||
|
EOpMethodStore, // ...
|
||||||
|
EOpMethodStore2, // ...
|
||||||
|
EOpMethodStore3, // ...
|
||||||
|
EOpMethodStore4, // ...
|
||||||
|
EOpMethodIncrementCounter, // ...
|
||||||
|
EOpMethodDecrementCounter, // ...
|
||||||
|
// EOpMethodAppend is defined for geo shaders below
|
||||||
|
EOpMethodConsume,
|
||||||
|
|
||||||
// SM5 texture methods
|
// SM5 texture methods
|
||||||
EOpMethodGatherRed, // These are covered under the above EOpMethodSample comment about
|
EOpMethodGatherRed, // These are covered under the above EOpMethodSample comment about
|
||||||
EOpMethodGatherGreen, // translation to existing AST opcodes. They exist temporarily
|
EOpMethodGatherGreen, // translation to existing AST opcodes. They exist temporarily
|
||||||
@@ -744,6 +861,15 @@ protected:
|
|||||||
TType type;
|
TType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Loop control hints
|
||||||
|
//
|
||||||
|
enum TLoopControl {
|
||||||
|
ELoopControlNone,
|
||||||
|
ELoopControlUnroll,
|
||||||
|
ELoopControlDontUnroll,
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Handle for, do-while, and while loops.
|
// Handle for, do-while, and while loops.
|
||||||
//
|
//
|
||||||
@@ -753,17 +879,25 @@ public:
|
|||||||
body(aBody),
|
body(aBody),
|
||||||
test(aTest),
|
test(aTest),
|
||||||
terminal(aTerminal),
|
terminal(aTerminal),
|
||||||
first(testFirst) { }
|
first(testFirst),
|
||||||
|
control(ELoopControlNone)
|
||||||
|
{ }
|
||||||
|
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
TIntermNode* getBody() const { return body; }
|
TIntermNode* getBody() const { return body; }
|
||||||
TIntermTyped* getTest() const { return test; }
|
TIntermTyped* getTest() const { return test; }
|
||||||
TIntermTyped* getTerminal() const { return terminal; }
|
TIntermTyped* getTerminal() const { return terminal; }
|
||||||
bool testFirst() const { return first; }
|
bool testFirst() const { return first; }
|
||||||
|
|
||||||
|
void setLoopControl(TLoopControl c) { control = c; }
|
||||||
|
TLoopControl getLoopControl() const { return control; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermNode* body; // code to loop over
|
TIntermNode* body; // code to loop over
|
||||||
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
||||||
TIntermTyped* terminal; // exists for for-loops
|
TIntermTyped* terminal; // exists for for-loops
|
||||||
bool first; // true for while and for, not for do-while
|
bool first; // true for while and for, not for do-while
|
||||||
|
TLoopControl control; // loop control hint
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1017,6 +1151,25 @@ public:
|
|||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
cracked.offsets = true;
|
cracked.offsets = true;
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpTextureGatherLod:
|
||||||
|
case EOpSparseTextureGatherLod:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureGatherLodOffset:
|
||||||
|
case EOpSparseTextureGatherLodOffset:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.offset = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureGatherLodOffsets:
|
||||||
|
case EOpSparseTextureGatherLodOffsets:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.offsets = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case EOpSubpassLoad:
|
case EOpSubpassLoad:
|
||||||
case EOpSubpassLoadMS:
|
case EOpSubpassLoadMS:
|
||||||
cracked.subpass = true;
|
cracked.subpass = true;
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
// For the version, it uses the latest git tag followed by the number of commits.
|
||||||
// For the date, it uses the current date (when then script is run).
|
// For the date, it uses the current date (when then script is run).
|
||||||
|
|
||||||
#define GLSLANG_REVISION "Overload400-PrecQual.1843"
|
#define GLSLANG_REVISION "Overload400-PrecQual.2000"
|
||||||
#define GLSLANG_DATE "18-Feb-2017"
|
#define GLSLANG_DATE "12-Apr-2017"
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
|
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
if (rightUnionArray[i] == 0) {
|
if (rightUnionArray[i] == 0) {
|
||||||
newConstArray[i].setUConst(0xFFFFFFFF);
|
newConstArray[i].setUConst(0xFFFFFFFFu);
|
||||||
} else
|
} else
|
||||||
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
||||||
break;
|
break;
|
||||||
@@ -213,6 +213,23 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
} else
|
} else
|
||||||
newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
|
newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
if (rightUnionArray[i] == 0)
|
||||||
|
newConstArray[i].setIConst(0x7FFF);
|
||||||
|
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x8000)
|
||||||
|
newConstArray[i].setIConst(0x8000);
|
||||||
|
else
|
||||||
|
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EbtUint16:
|
||||||
|
if (rightUnionArray[i] == 0) {
|
||||||
|
newConstArray[i].setUConst(0xFFFFu);
|
||||||
|
} else
|
||||||
|
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -457,10 +474,16 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
#endif
|
#endif
|
||||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
#endif
|
||||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||||
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
||||||
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getU64Const()))); break;
|
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -610,6 +633,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
case EOpUintBitsToFloat:
|
case EOpUintBitsToFloat:
|
||||||
case EOpDoubleBitsToInt64:
|
case EOpDoubleBitsToInt64:
|
||||||
case EOpDoubleBitsToUint64:
|
case EOpDoubleBitsToUint64:
|
||||||
|
case EOpInt64BitsToDouble:
|
||||||
|
case EOpUint64BitsToDouble:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpFloat16BitsToInt16:
|
||||||
|
case EOpFloat16BitsToUint16:
|
||||||
|
case EOpInt16BitsToFloat16:
|
||||||
|
case EOpUint16BitsToFloat16:
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -702,6 +733,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
#endif
|
#endif
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtDouble;
|
children[0]->getAsTyped()->getBasicType() == EbtDouble;
|
||||||
bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
|
bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
children[0]->getAsTyped()->getBasicType() == EbtInt16 ||
|
||||||
|
#endif
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtInt64;
|
children[0]->getAsTyped()->getBasicType() == EbtInt64;
|
||||||
bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
|
bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtUint64;
|
children[0]->getAsTyped()->getBasicType() == EbtUint64;
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ TBuiltIns::~TBuiltIns()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add all context-independent built-in functions and variables that are present
|
// Add all context-independent built-in functions and variables that are present
|
||||||
// for the given version and profile. Share common ones across stages, otherwise
|
// for the given version and profile. Share common ones across stages, otherwise
|
||||||
@@ -2615,6 +2616,157 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
|
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GL_AMD_gpu_shader_int16
|
||||||
|
if (profile != EEsProfile && version >= 450) {
|
||||||
|
commonBuiltins.append(
|
||||||
|
"int16_t abs(int16_t);"
|
||||||
|
"i16vec2 abs(i16vec2);"
|
||||||
|
"i16vec3 abs(i16vec3);"
|
||||||
|
"i16vec4 abs(i16vec4);"
|
||||||
|
|
||||||
|
"int16_t sign(int16_t);"
|
||||||
|
"i16vec2 sign(i16vec2);"
|
||||||
|
"i16vec3 sign(i16vec3);"
|
||||||
|
"i16vec4 sign(i16vec4);"
|
||||||
|
|
||||||
|
"int16_t min(int16_t, int16_t);"
|
||||||
|
"i16vec2 min(i16vec2, int16_t);"
|
||||||
|
"i16vec3 min(i16vec3, int16_t);"
|
||||||
|
"i16vec4 min(i16vec4, int16_t);"
|
||||||
|
"i16vec2 min(i16vec2, i16vec2);"
|
||||||
|
"i16vec3 min(i16vec3, i16vec3);"
|
||||||
|
"i16vec4 min(i16vec4, i16vec4);"
|
||||||
|
"uint16_t min(uint16_t, uint16_t);"
|
||||||
|
"u16vec2 min(u16vec2, uint16_t);"
|
||||||
|
"u16vec3 min(u16vec3, uint16_t);"
|
||||||
|
"u16vec4 min(u16vec4, uint16_t);"
|
||||||
|
"u16vec2 min(u16vec2, u16vec2);"
|
||||||
|
"u16vec3 min(u16vec3, u16vec3);"
|
||||||
|
"u16vec4 min(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"int16_t max(int16_t, int16_t);"
|
||||||
|
"i16vec2 max(i16vec2, int16_t);"
|
||||||
|
"i16vec3 max(i16vec3, int16_t);"
|
||||||
|
"i16vec4 max(i16vec4, int16_t);"
|
||||||
|
"i16vec2 max(i16vec2, i16vec2);"
|
||||||
|
"i16vec3 max(i16vec3, i16vec3);"
|
||||||
|
"i16vec4 max(i16vec4, i16vec4);"
|
||||||
|
"uint16_t max(uint16_t, uint16_t);"
|
||||||
|
"u16vec2 max(u16vec2, uint16_t);"
|
||||||
|
"u16vec3 max(u16vec3, uint16_t);"
|
||||||
|
"u16vec4 max(u16vec4, uint16_t);"
|
||||||
|
"u16vec2 max(u16vec2, u16vec2);"
|
||||||
|
"u16vec3 max(u16vec3, u16vec3);"
|
||||||
|
"u16vec4 max(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"int16_t clamp(int16_t, int16_t, int16_t);"
|
||||||
|
"i16vec2 clamp(i16vec2, int16_t, int16_t);"
|
||||||
|
"i16vec3 clamp(i16vec3, int16_t, int16_t);"
|
||||||
|
"i16vec4 clamp(i16vec4, int16_t, int16_t);"
|
||||||
|
"i16vec2 clamp(i16vec2, i16vec2, i16vec2);"
|
||||||
|
"i16vec3 clamp(i16vec3, i16vec3, i16vec3);"
|
||||||
|
"i16vec4 clamp(i16vec4, i16vec4, i16vec4);"
|
||||||
|
"uint16_t clamp(uint16_t, uint16_t, uint16_t);"
|
||||||
|
"u16vec2 clamp(u16vec2, uint16_t, uint16_t);"
|
||||||
|
"u16vec3 clamp(u16vec3, uint16_t, uint16_t);"
|
||||||
|
"u16vec4 clamp(u16vec4, uint16_t, uint16_t);"
|
||||||
|
"u16vec2 clamp(u16vec2, u16vec2, u16vec2);"
|
||||||
|
"u16vec3 clamp(u16vec3, u16vec3, u16vec3);"
|
||||||
|
"u16vec4 clamp(u16vec4, u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"int16_t mix(int16_t, int16_t, bool);"
|
||||||
|
"i16vec2 mix(i16vec2, i16vec2, bvec2);"
|
||||||
|
"i16vec3 mix(i16vec3, i16vec3, bvec3);"
|
||||||
|
"i16vec4 mix(i16vec4, i16vec4, bvec4);"
|
||||||
|
"uint16_t mix(uint16_t, uint16_t, bool);"
|
||||||
|
"u16vec2 mix(u16vec2, u16vec2, bvec2);"
|
||||||
|
"u16vec3 mix(u16vec3, u16vec3, bvec3);"
|
||||||
|
"u16vec4 mix(u16vec4, u16vec4, bvec4);"
|
||||||
|
|
||||||
|
"float16_t frexp(float16_t, out int16_t);"
|
||||||
|
"f16vec2 frexp(f16vec2, out i16vec2);"
|
||||||
|
"f16vec3 frexp(f16vec3, out i16vec3);"
|
||||||
|
"f16vec4 frexp(f16vec4, out i16vec4);"
|
||||||
|
|
||||||
|
"float16_t ldexp(float16_t, int16_t);"
|
||||||
|
"f16vec2 ldexp(f16vec2, i16vec2);"
|
||||||
|
"f16vec3 ldexp(f16vec3, i16vec3);"
|
||||||
|
"f16vec4 ldexp(f16vec4, i16vec4);"
|
||||||
|
|
||||||
|
"int16_t float16BitsToInt16(float16_t);"
|
||||||
|
"i16vec2 float16BitsToInt16(f16vec2);"
|
||||||
|
"i16vec3 float16BitsToInt16(f16vec3);"
|
||||||
|
"i16vec4 float16BitsToInt16(f16vec4);"
|
||||||
|
|
||||||
|
"uint16_t float16BitsToUint16(float16_t);"
|
||||||
|
"u16vec2 float16BitsToUint16(f16vec2);"
|
||||||
|
"u16vec3 float16BitsToUint16(f16vec3);"
|
||||||
|
"u16vec4 float16BitsToUint16(f16vec4);"
|
||||||
|
|
||||||
|
"float16_t int16BitsToFloat16(int16_t);"
|
||||||
|
"f16vec2 int16BitsToFloat16(i16vec2);"
|
||||||
|
"f16vec3 int16BitsToFloat16(i16vec3);"
|
||||||
|
"f16vec4 int16BitsToFloat16(i16vec4);"
|
||||||
|
|
||||||
|
"float16_t uint16BitsToFloat16(uint16_t);"
|
||||||
|
"f16vec2 uint16BitsToFloat16(u16vec2);"
|
||||||
|
"f16vec3 uint16BitsToFloat16(u16vec3);"
|
||||||
|
"f16vec4 uint16BitsToFloat16(u16vec4);"
|
||||||
|
|
||||||
|
"int packInt2x16(i16vec2);"
|
||||||
|
"uint packUint2x16(u16vec2);"
|
||||||
|
"int64_t packInt4x16(i16vec4);"
|
||||||
|
"uint64_t packUint4x16(u16vec4);"
|
||||||
|
"i16vec2 unpackInt2x16(int);"
|
||||||
|
"u16vec2 unpackUint2x16(uint);"
|
||||||
|
"i16vec4 unpackInt4x16(int64_t);"
|
||||||
|
"u16vec4 unpackUint4x16(uint64_t);"
|
||||||
|
|
||||||
|
"bvec2 lessThan(i16vec2, i16vec2);"
|
||||||
|
"bvec3 lessThan(i16vec3, i16vec3);"
|
||||||
|
"bvec4 lessThan(i16vec4, i16vec4);"
|
||||||
|
"bvec2 lessThan(u16vec2, u16vec2);"
|
||||||
|
"bvec3 lessThan(u16vec3, u16vec3);"
|
||||||
|
"bvec4 lessThan(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"bvec2 lessThanEqual(i16vec2, i16vec2);"
|
||||||
|
"bvec3 lessThanEqual(i16vec3, i16vec3);"
|
||||||
|
"bvec4 lessThanEqual(i16vec4, i16vec4);"
|
||||||
|
"bvec2 lessThanEqual(u16vec2, u16vec2);"
|
||||||
|
"bvec3 lessThanEqual(u16vec3, u16vec3);"
|
||||||
|
"bvec4 lessThanEqual(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"bvec2 greaterThan(i16vec2, i16vec2);"
|
||||||
|
"bvec3 greaterThan(i16vec3, i16vec3);"
|
||||||
|
"bvec4 greaterThan(i16vec4, i16vec4);"
|
||||||
|
"bvec2 greaterThan(u16vec2, u16vec2);"
|
||||||
|
"bvec3 greaterThan(u16vec3, u16vec3);"
|
||||||
|
"bvec4 greaterThan(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"bvec2 greaterThanEqual(i16vec2, i16vec2);"
|
||||||
|
"bvec3 greaterThanEqual(i16vec3, i16vec3);"
|
||||||
|
"bvec4 greaterThanEqual(i16vec4, i16vec4);"
|
||||||
|
"bvec2 greaterThanEqual(u16vec2, u16vec2);"
|
||||||
|
"bvec3 greaterThanEqual(u16vec3, u16vec3);"
|
||||||
|
"bvec4 greaterThanEqual(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"bvec2 equal(i16vec2, i16vec2);"
|
||||||
|
"bvec3 equal(i16vec3, i16vec3);"
|
||||||
|
"bvec4 equal(i16vec4, i16vec4);"
|
||||||
|
"bvec2 equal(u16vec2, u16vec2);"
|
||||||
|
"bvec3 equal(u16vec3, u16vec3);"
|
||||||
|
"bvec4 equal(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"bvec2 notEqual(i16vec2, i16vec2);"
|
||||||
|
"bvec3 notEqual(i16vec3, i16vec3);"
|
||||||
|
"bvec4 notEqual(i16vec4, i16vec4);"
|
||||||
|
"bvec2 notEqual(u16vec2, u16vec2);"
|
||||||
|
"bvec3 notEqual(u16vec3, u16vec3);"
|
||||||
|
"bvec4 notEqual(u16vec4, u16vec4);"
|
||||||
|
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@@ -3137,6 +3289,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangCompute].append(
|
||||||
|
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Define the interface to the vertex shader.
|
// Define the interface to the vertex shader.
|
||||||
@@ -3261,11 +3420,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
stageBuiltins[EShLangVertex].append(
|
stageBuiltins[EShLangVertex].append(
|
||||||
"out int gl_ViewportIndex;"
|
"out int gl_ViewportIndex;"
|
||||||
"out int gl_Layer;"
|
"out int gl_Layer;"
|
||||||
"out int gl_ViewportMask[];"
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
"out int gl_SecondaryViewportMaskNV[];"
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_SecondaryPositionNV;"
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];"
|
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
"out int gl_ViewportMaskPerViewNV[];"
|
"out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3302,6 +3461,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangVertex].append(
|
||||||
|
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"in highp int gl_ViewIndex;" // GL_EXT_multiview
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Define the interface to the geometry shader.
|
// Define the interface to the geometry shader.
|
||||||
@@ -3329,8 +3497,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
stageBuiltins[EShLangGeometry].append(
|
stageBuiltins[EShLangGeometry].append(
|
||||||
"float gl_CullDistance[];"
|
"float gl_CullDistance[];"
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
"vec4 gl_SecondaryPositionNV;"
|
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"vec4 gl_PositionPerViewNV[];"
|
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
stageBuiltins[EShLangGeometry].append(
|
stageBuiltins[EShLangGeometry].append(
|
||||||
@@ -3380,11 +3548,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (version >= 450)
|
if (version >= 450)
|
||||||
stageBuiltins[EShLangGeometry].append(
|
stageBuiltins[EShLangGeometry].append(
|
||||||
"out int gl_ViewportMask[];"
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
"out int gl_SecondaryViewportMaskNV[];"
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_SecondaryPositionNV;"
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];"
|
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
"out int gl_ViewportMaskPerViewNV[];"
|
"out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3410,6 +3578,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangGeometry].append(
|
||||||
|
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"in highp int gl_ViewIndex;" // GL_EXT_multiview
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Define the interface to the tessellation control shader.
|
// Define the interface to the tessellation control shader.
|
||||||
@@ -3446,11 +3622,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
"int gl_ViewportIndex;"
|
"int gl_ViewportIndex;"
|
||||||
"int gl_Layer;"
|
"int gl_Layer;"
|
||||||
"int gl_ViewportMask[];"
|
"int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
"vec4 gl_SecondaryPositionNV;"
|
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"int gl_SecondaryViewportMaskNV[];"
|
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"vec4 gl_PositionPerViewNV[];"
|
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
"int gl_ViewportMaskPerViewNV[];"
|
"int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
stageBuiltins[EShLangTessControl].append(
|
stageBuiltins[EShLangTessControl].append(
|
||||||
@@ -3481,6 +3657,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangTessControl].append(
|
||||||
|
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"in highp int gl_ViewIndex;" // GL_EXT_multiview
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Define the interface to the tessellation evaluation shader.
|
// Define the interface to the tessellation evaluation shader.
|
||||||
@@ -3527,11 +3711,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
stageBuiltins[EShLangTessEvaluation].append(
|
stageBuiltins[EShLangTessEvaluation].append(
|
||||||
"out int gl_ViewportIndex;"
|
"out int gl_ViewportIndex;"
|
||||||
"out int gl_Layer;"
|
"out int gl_Layer;"
|
||||||
"out int gl_ViewportMask[];"
|
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||||
"out vec4 gl_SecondaryPositionNV;"
|
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"out int gl_SecondaryViewportMaskNV[];"
|
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||||
"out vec4 gl_PositionPerViewNV[];"
|
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
"out int gl_ViewportMaskPerViewNV[];"
|
"out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3556,6 +3740,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangTessEvaluation].append(
|
||||||
|
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"in highp int gl_ViewIndex;" // GL_EXT_multiview
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Define the interface to the fragment shader.
|
// Define the interface to the fragment shader.
|
||||||
@@ -3713,6 +3905,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
stageBuiltins[EShLangFragment].append(
|
||||||
|
"flat in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||||
|
"flat in highp int gl_ViewIndex;" // GL_EXT_multiview
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
// printf("%s\n", commonBuiltins.c_str());
|
// printf("%s\n", commonBuiltins.c_str());
|
||||||
// printf("%s\n", stageBuiltins[EShLangFragment].c_str());
|
// printf("%s\n", stageBuiltins[EShLangFragment].c_str());
|
||||||
}
|
}
|
||||||
@@ -3808,6 +4008,17 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
|
|||||||
else {
|
else {
|
||||||
addSamplingFunctions(sampler, typeName, version, profile);
|
addSamplingFunctions(sampler, typeName, version, profile);
|
||||||
addGatherFunctions(sampler, typeName, version, profile);
|
addGatherFunctions(sampler, typeName, version, profile);
|
||||||
|
|
||||||
|
if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) {
|
||||||
|
// Vulkan wants a textureBuffer to allow texelFetch() --
|
||||||
|
// a sampled image with no sampler.
|
||||||
|
// So, add sampling functions for both the
|
||||||
|
// samplerBuffer and textureBuffer types.
|
||||||
|
sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow,
|
||||||
|
sampler.ms);
|
||||||
|
TString textureTypeName = sampler.getString();
|
||||||
|
addSamplingFunctions(sampler, textureTypeName, version, profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3831,7 +4042,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
|
|||||||
//
|
//
|
||||||
// Add all the query functions for the given type.
|
// Add all the query functions for the given type.
|
||||||
//
|
//
|
||||||
void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430)))
|
if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430)))
|
||||||
return;
|
return;
|
||||||
@@ -3908,7 +4119,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
|
|||||||
//
|
//
|
||||||
// Add all the image access functions for the given type.
|
// Add all the image access functions for the given type.
|
||||||
//
|
//
|
||||||
void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
int dims = dimMap[sampler.dim];
|
int dims = dimMap[sampler.dim];
|
||||||
// most things with an array add a dimension, except for cubemaps
|
// most things with an array add a dimension, except for cubemaps
|
||||||
@@ -4001,7 +4212,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
|
|||||||
//
|
//
|
||||||
// Add all the subpass access functions for the given type.
|
// Add all the subpass access functions for the given type.
|
||||||
//
|
//
|
||||||
void TBuiltIns::addSubpassSampling(TSampler sampler, TString& typeName, int /*version*/, EProfile /*profile*/)
|
void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, int /*version*/, EProfile /*profile*/)
|
||||||
{
|
{
|
||||||
stageBuiltins[EShLangFragment].append(prefixes[sampler.type]);
|
stageBuiltins[EShLangFragment].append(prefixes[sampler.type]);
|
||||||
stageBuiltins[EShLangFragment].append("vec4 subpassLoad");
|
stageBuiltins[EShLangFragment].append("vec4 subpassLoad");
|
||||||
@@ -4018,7 +4229,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, TString& typeName, int /*ve
|
|||||||
//
|
//
|
||||||
// Add all the texture lookup functions for the given type.
|
// Add all the texture lookup functions for the given type.
|
||||||
//
|
//
|
||||||
void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// texturing
|
// texturing
|
||||||
@@ -4248,7 +4459,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int ve
|
|||||||
//
|
//
|
||||||
// Add all the texture gather functions for the given type.
|
// Add all the texture gather functions for the given type.
|
||||||
//
|
//
|
||||||
void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
switch (sampler.dim) {
|
switch (sampler.dim) {
|
||||||
case Esd2D:
|
case Esd2D:
|
||||||
@@ -4303,6 +4514,7 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sparse)
|
if (sparse)
|
||||||
s.append("ARB");
|
s.append("ARB");
|
||||||
s.append("(");
|
s.append("(");
|
||||||
@@ -4342,6 +4554,116 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (sampler.dim == EsdRect || sampler.shadow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (profile == EEsProfile || version < 450)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int bias = 0; bias < 2; ++bias) { // loop over presence of bias argument
|
||||||
|
|
||||||
|
for (int lod = 0; lod < 2; ++lod) { // loop over presence of lod argument
|
||||||
|
|
||||||
|
if ((lod && bias) || (lod == 0 && bias == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets
|
||||||
|
|
||||||
|
for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument
|
||||||
|
|
||||||
|
if (comp == 0 && bias)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (offset > 0 && sampler.dim == EsdCube)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not
|
||||||
|
if (sparse && (profile == EEsProfile || version < 450))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TString s;
|
||||||
|
|
||||||
|
// return type
|
||||||
|
if (sparse)
|
||||||
|
s.append("int ");
|
||||||
|
else {
|
||||||
|
s.append(prefixes[sampler.type]);
|
||||||
|
s.append("vec4 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// name
|
||||||
|
if (sparse)
|
||||||
|
s.append("sparseTextureGather");
|
||||||
|
else
|
||||||
|
s.append("textureGather");
|
||||||
|
|
||||||
|
if (lod)
|
||||||
|
s.append("Lod");
|
||||||
|
|
||||||
|
switch (offset) {
|
||||||
|
case 1:
|
||||||
|
s.append("Offset");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
s.append("Offsets");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lod)
|
||||||
|
s.append("AMD");
|
||||||
|
else if (sparse)
|
||||||
|
s.append("ARB");
|
||||||
|
|
||||||
|
s.append("(");
|
||||||
|
|
||||||
|
// sampler type argument
|
||||||
|
s.append(typeName);
|
||||||
|
|
||||||
|
// P coordinate argument
|
||||||
|
s.append(",vec");
|
||||||
|
int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0);
|
||||||
|
s.append(postfixes[totalDims]);
|
||||||
|
|
||||||
|
// lod argument
|
||||||
|
if (lod)
|
||||||
|
s.append(",float");
|
||||||
|
|
||||||
|
// offset argument
|
||||||
|
if (offset > 0) {
|
||||||
|
s.append(",ivec2");
|
||||||
|
if (offset == 2)
|
||||||
|
s.append("[4]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// texel out (for sparse texture)
|
||||||
|
if (sparse) {
|
||||||
|
s.append(",out ");
|
||||||
|
s.append(prefixes[sampler.type]);
|
||||||
|
s.append("vec4 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// comp argument
|
||||||
|
if (comp)
|
||||||
|
s.append(",int");
|
||||||
|
|
||||||
|
// bias argument
|
||||||
|
if (bias)
|
||||||
|
s.append(",float");
|
||||||
|
|
||||||
|
s.append(");\n");
|
||||||
|
if (bias)
|
||||||
|
stageBuiltins[EShLangFragment].append(s);
|
||||||
|
else
|
||||||
|
commonBuiltins.append(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -4469,8 +4791,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||||||
"highp vec4 gl_Position;"
|
"highp vec4 gl_Position;"
|
||||||
"highp float gl_PointSize;"
|
"highp float gl_PointSize;"
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
"highp vec4 gl_SecondaryPositionNV;"
|
"highp vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"highp vec4 gl_PositionPerViewNV[];"
|
"highp vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
#endif
|
#endif
|
||||||
"} gl_in[gl_MaxPatchVertices];"
|
"} gl_in[gl_MaxPatchVertices];"
|
||||||
"\n");
|
"\n");
|
||||||
@@ -4659,8 +4981,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||||||
s.append(
|
s.append(
|
||||||
"float gl_CullDistance[];"
|
"float gl_CullDistance[];"
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
"vec4 gl_SecondaryPositionNV;"
|
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||||
"vec4 gl_PositionPerViewNV[];"
|
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
s.append(
|
s.append(
|
||||||
@@ -5127,13 +5449,29 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
// symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size);
|
// symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||||
|
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||||
|
symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
|
||||||
|
BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
SpecialQualifier("gl_FrontFacing", EvqFace, EbvFace, symbolTable);
|
SpecialQualifier("gl_FrontFacing", EvqFace, EbvFace, symbolTable);
|
||||||
SpecialQualifier("gl_FragCoord", EvqFragCoord, EbvFragCoord, symbolTable);
|
SpecialQualifier("gl_FragCoord", EvqFragCoord, EbvFragCoord, symbolTable);
|
||||||
SpecialQualifier("gl_PointCoord", EvqPointCoord, EbvPointCoord, symbolTable);
|
SpecialQualifier("gl_PointCoord", EvqPointCoord, EbvPointCoord, symbolTable);
|
||||||
SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable);
|
if (spvVersion.spv == 0)
|
||||||
|
SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable);
|
||||||
|
else {
|
||||||
|
TSymbol* symbol = symbolTable.find("gl_FragColor");
|
||||||
|
if (symbol) {
|
||||||
|
symbol->getWritableType().getQualifier().storage = EvqVaryingOut;
|
||||||
|
symbol->getWritableType().getQualifier().layoutLocation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
|
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
|
||||||
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
|
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
|
||||||
SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable);
|
SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable);
|
||||||
@@ -5325,6 +5663,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
BuiltInVariable("gl_BaryCoordSmoothSampleAMD", EbvBaryCoordSmoothSample, symbolTable);
|
BuiltInVariable("gl_BaryCoordSmoothSampleAMD", EbvBaryCoordSmoothSample, symbolTable);
|
||||||
BuiltInVariable("gl_BaryCoordPullModelAMD", EbvBaryCoordPullModel, symbolTable);
|
BuiltInVariable("gl_BaryCoordPullModelAMD", EbvBaryCoordPullModel, symbolTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// E_GL_AMD_texture_gather_bias_lod
|
||||||
|
if (profile != EEsProfile) {
|
||||||
|
symbolTable.setFunctionExtensions("textureGatherLodAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
symbolTable.setFunctionExtensions("textureGatherLodOffsetAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
symbolTable.setFunctionExtensions("textureGatherLodOffsetsAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
symbolTable.setFunctionExtensions("sparseTextureGatherLodAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetsAMD", 1, &E_GL_AMD_texture_gather_bias_lod);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
|
symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
|
||||||
@@ -5344,6 +5692,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
|
symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
|
||||||
symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
|
symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||||
|
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||||
|
symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
|
||||||
|
BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
@@ -5377,6 +5730,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_ARB_compute_shader);
|
symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_ARB_compute_shader);
|
||||||
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader);
|
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||||
|
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||||
|
symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
|
||||||
|
BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -5462,6 +5824,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
|
symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
|
||||||
symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble);
|
symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble);
|
||||||
symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble);
|
symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
symbolTable.relateToOperator("float16BitsToInt16", EOpFloat16BitsToInt16);
|
||||||
|
symbolTable.relateToOperator("float16BitsToUint16", EOpFloat16BitsToUint16);
|
||||||
|
symbolTable.relateToOperator("int16BitsToFloat16", EOpInt16BitsToFloat16);
|
||||||
|
symbolTable.relateToOperator("uint16BitsToFloat16", EOpUint16BitsToFloat16);
|
||||||
|
#endif
|
||||||
|
|
||||||
symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16);
|
symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16);
|
||||||
symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
|
symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
|
||||||
@@ -5485,6 +5853,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("unpackUint2x32", EOpUnpackUint2x32);
|
symbolTable.relateToOperator("unpackUint2x32", EOpUnpackUint2x32);
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
symbolTable.relateToOperator("packInt2x16", EOpPackInt2x16);
|
||||||
|
symbolTable.relateToOperator("unpackInt2x16", EOpUnpackInt2x16);
|
||||||
|
symbolTable.relateToOperator("packUint2x16", EOpPackUint2x16);
|
||||||
|
symbolTable.relateToOperator("unpackUint2x16", EOpUnpackUint2x16);
|
||||||
|
|
||||||
|
symbolTable.relateToOperator("packInt4x16", EOpPackInt4x16);
|
||||||
|
symbolTable.relateToOperator("unpackInt4x16", EOpUnpackInt4x16);
|
||||||
|
symbolTable.relateToOperator("packUint4x16", EOpPackUint4x16);
|
||||||
|
symbolTable.relateToOperator("unpackUint4x16", EOpUnpackUint4x16);
|
||||||
|
|
||||||
symbolTable.relateToOperator("packFloat2x16", EOpPackFloat2x16);
|
symbolTable.relateToOperator("packFloat2x16", EOpPackFloat2x16);
|
||||||
symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16);
|
symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16);
|
||||||
#endif
|
#endif
|
||||||
@@ -5706,6 +6084,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("cubeFaceIndexAMD", EOpCubeFaceIndex);
|
symbolTable.relateToOperator("cubeFaceIndexAMD", EOpCubeFaceIndex);
|
||||||
symbolTable.relateToOperator("cubeFaceCoordAMD", EOpCubeFaceCoord);
|
symbolTable.relateToOperator("cubeFaceCoordAMD", EOpCubeFaceCoord);
|
||||||
symbolTable.relateToOperator("timeAMD", EOpTime);
|
symbolTable.relateToOperator("timeAMD", EOpTime);
|
||||||
|
|
||||||
|
symbolTable.relateToOperator("textureGatherLodAMD", EOpTextureGatherLod);
|
||||||
|
symbolTable.relateToOperator("textureGatherLodOffsetAMD", EOpTextureGatherLodOffset);
|
||||||
|
symbolTable.relateToOperator("textureGatherLodOffsetsAMD", EOpTextureGatherLodOffsets);
|
||||||
|
symbolTable.relateToOperator("sparseTextureGatherLodAMD", EOpSparseTextureGatherLod);
|
||||||
|
symbolTable.relateToOperator("sparseTextureGatherLodOffsetAMD", EOpSparseTextureGatherLodOffset);
|
||||||
|
symbolTable.relateToOperator("sparseTextureGatherLodOffsetsAMD", EOpSparseTextureGatherLodOffsets);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,11 +94,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
||||||
void addSubpassSampling(TSampler, TString& typeName, int version, EProfile profile);
|
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addQueryFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addImageFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addImageFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addSamplingFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addSamplingFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addGatherFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addGatherFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
|
|
||||||
// Helpers for making textual representations of the permutations
|
// Helpers for making textual representations of the permutations
|
||||||
// of texturing/imaging functions.
|
// of texturing/imaging functions.
|
||||||
|
|||||||
@@ -130,8 +130,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert the children's type shape to be compatible.
|
// Convert the children's type shape to be compatible.
|
||||||
right = addShapeConversion(op, left->getType(), right);
|
addBiShapeConversion(op, left, right);
|
||||||
left = addShapeConversion(op, right->getType(), left);
|
if (left == nullptr || right == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Need a new node holding things together. Make
|
// Need a new node holding things together. Make
|
||||||
@@ -147,8 +148,8 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||||||
// If they are both (non-specialization) constants, they must be folded.
|
// If they are both (non-specialization) constants, they must be folded.
|
||||||
// (Unless it's the sequence (comma) operator, but that's handled in addComma().)
|
// (Unless it's the sequence (comma) operator, but that's handled in addComma().)
|
||||||
//
|
//
|
||||||
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
|
TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion();
|
||||||
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
|
TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion();
|
||||||
if (leftTempConstant && rightTempConstant) {
|
if (leftTempConstant && rightTempConstant) {
|
||||||
TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
|
TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
|
||||||
if (folded)
|
if (folded)
|
||||||
@@ -157,7 +158,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||||||
|
|
||||||
// If can propagate spec-constantness and if the operation is an allowed
|
// If can propagate spec-constantness and if the operation is an allowed
|
||||||
// specialization-constant operation, make a spec-constant.
|
// specialization-constant operation, make a spec-constant.
|
||||||
if (specConstantPropagates(*left, *right) && isSpecializationOperation(*node))
|
if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
|
||||||
node->getWritableType().getQualifier().makeSpecConstant();
|
node->getWritableType().getQualifier().makeSpecConstant();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -238,7 +239,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// convert shape
|
// convert shape
|
||||||
right = addShapeConversion(op, left->getType(), right);
|
right = addUniShapeConversion(op, left->getType(), right);
|
||||||
|
|
||||||
// build the node
|
// build the node
|
||||||
TIntermBinary* node = addBinaryNode(op, left, right, loc);
|
TIntermBinary* node = addBinaryNode(op, left, right, loc);
|
||||||
@@ -307,6 +308,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
|
|||||||
case EOpConstructUint: newType = EbtUint; break;
|
case EOpConstructUint: newType = EbtUint; break;
|
||||||
case EOpConstructInt64: newType = EbtInt64; break;
|
case EOpConstructInt64: newType = EbtInt64; break;
|
||||||
case EOpConstructUint64: newType = EbtUint64; break;
|
case EOpConstructUint64: newType = EbtUint64; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructInt16: newType = EbtInt16; break;
|
||||||
|
case EOpConstructUint16: newType = EbtUint16; break;
|
||||||
|
#endif
|
||||||
case EOpConstructBool: newType = EbtBool; break;
|
case EOpConstructBool: newType = EbtBool; break;
|
||||||
case EOpConstructFloat: newType = EbtFloat; break;
|
case EOpConstructFloat: newType = EbtFloat; break;
|
||||||
case EOpConstructDouble: newType = EbtDouble; break;
|
case EOpConstructDouble: newType = EbtDouble; break;
|
||||||
@@ -335,6 +340,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
|
|||||||
case EOpConstructUint:
|
case EOpConstructUint:
|
||||||
case EOpConstructInt64:
|
case EOpConstructInt64:
|
||||||
case EOpConstructUint64:
|
case EOpConstructUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructInt16:
|
||||||
|
case EOpConstructUint16:
|
||||||
|
#endif
|
||||||
case EOpConstructBool:
|
case EOpConstructBool:
|
||||||
case EOpConstructFloat:
|
case EOpConstructFloat:
|
||||||
case EOpConstructDouble:
|
case EOpConstructDouble:
|
||||||
@@ -356,12 +365,12 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
|
|||||||
node->updatePrecision();
|
node->updatePrecision();
|
||||||
|
|
||||||
// If it's a (non-specialization) constant, it must be folded.
|
// If it's a (non-specialization) constant, it must be folded.
|
||||||
if (child->getAsConstantUnion())
|
if (node->getOperand()->getAsConstantUnion())
|
||||||
return child->getAsConstantUnion()->fold(op, node->getType());
|
return node->getOperand()->getAsConstantUnion()->fold(op, node->getType());
|
||||||
|
|
||||||
// If it's a specialization constant, the result is too,
|
// If it's a specialization constant, the result is too,
|
||||||
// if the operation is allowed for specialization constants.
|
// if the operation is allowed for specialization constants.
|
||||||
if (child->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
|
if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
|
||||||
node->getWritableType().getQualifier().makeSpecConstant();
|
node->getWritableType().getQualifier().makeSpecConstant();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -527,6 +536,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EOpConstructUint64:
|
case EOpConstructUint64:
|
||||||
promoteTo = EbtUint64;
|
promoteTo = EbtUint64;
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructInt16:
|
||||||
|
promoteTo = EbtInt16;
|
||||||
|
break;
|
||||||
|
case EOpConstructUint16:
|
||||||
|
promoteTo = EbtUint16;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// List all the binary ops that can implicitly convert one operand to the other's type;
|
// List all the binary ops that can implicitly convert one operand to the other's type;
|
||||||
@@ -615,15 +632,26 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EOpRightShiftAssign:
|
case EOpRightShiftAssign:
|
||||||
if ((type.getBasicType() == EbtInt ||
|
if ((type.getBasicType() == EbtInt ||
|
||||||
type.getBasicType() == EbtUint ||
|
type.getBasicType() == EbtUint ||
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
type.getBasicType() == EbtInt16 ||
|
||||||
|
type.getBasicType() == EbtUint16 ||
|
||||||
|
#endif
|
||||||
type.getBasicType() == EbtInt64 ||
|
type.getBasicType() == EbtInt64 ||
|
||||||
type.getBasicType() == EbtUint64) &&
|
type.getBasicType() == EbtUint64) &&
|
||||||
(node->getType().getBasicType() == EbtInt ||
|
(node->getType().getBasicType() == EbtInt ||
|
||||||
node->getType().getBasicType() == EbtUint ||
|
node->getType().getBasicType() == EbtUint ||
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
node->getType().getBasicType() == EbtInt16 ||
|
||||||
|
node->getType().getBasicType() == EbtUint16 ||
|
||||||
|
#endif
|
||||||
node->getType().getBasicType() == EbtInt64 ||
|
node->getType().getBasicType() == EbtInt64 ||
|
||||||
node->getType().getBasicType() == EbtUint64))
|
node->getType().getBasicType() == EbtUint64))
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
else
|
else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) {
|
||||||
|
promoteTo = type.getBasicType();
|
||||||
|
break;
|
||||||
|
} else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -659,6 +687,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToDouble; break;
|
case EbtInt64: newOp = EOpConvInt64ToDouble; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToDouble; break;
|
case EbtUint64: newOp = EOpConvUint64ToDouble; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToDouble; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToDouble; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -674,6 +706,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToFloat; break;
|
case EbtInt64: newOp = EOpConvInt64ToFloat; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToFloat; break;
|
case EbtUint64: newOp = EOpConvUint64ToFloat; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToFloat; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToFloat; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -688,6 +724,8 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
|
case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
|
||||||
case EbtInt64: newOp = EOpConvInt64ToFloat16; break;
|
case EbtInt64: newOp = EOpConvInt64ToFloat16; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
|
case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToFloat16; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -704,6 +742,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToBool; break;
|
case EbtInt64: newOp = EOpConvInt64ToBool; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToBool; break;
|
case EbtUint64: newOp = EOpConvUint64ToBool; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToBool; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToBool; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -719,6 +761,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToInt; break;
|
case EbtInt64: newOp = EOpConvInt64ToInt; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToInt; break;
|
case EbtUint64: newOp = EOpConvUint64ToInt; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToInt; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToInt; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -734,6 +780,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToUint; break;
|
case EbtInt64: newOp = EOpConvInt64ToUint; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToUint; break;
|
case EbtUint64: newOp = EOpConvUint64ToUint; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToUint; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToUint; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -749,6 +799,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
|
case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtUint64: newOp = EOpConvUint64ToInt64; break;
|
case EbtUint64: newOp = EOpConvUint64ToInt64; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToInt64; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToInt64; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -764,10 +818,46 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
|
case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtInt64: newOp = EOpConvInt64ToUint64; break;
|
case EbtInt64: newOp = EOpConvInt64ToUint64; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToUint64; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToUint64; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
switch (node->getBasicType()) {
|
||||||
|
case EbtInt: newOp = EOpConvIntToInt16; break;
|
||||||
|
case EbtUint: newOp = EOpConvUintToInt16; break;
|
||||||
|
case EbtBool: newOp = EOpConvBoolToInt16; break;
|
||||||
|
case EbtFloat: newOp = EOpConvFloatToInt16; break;
|
||||||
|
case EbtDouble: newOp = EOpConvDoubleToInt16; break;
|
||||||
|
case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
|
||||||
|
case EbtInt64: newOp = EOpConvInt64ToInt16; break;
|
||||||
|
case EbtUint64: newOp = EOpConvUint64ToInt16; break;
|
||||||
|
case EbtUint16: newOp = EOpConvUint16ToInt16; break;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
switch (node->getBasicType()) {
|
||||||
|
case EbtInt: newOp = EOpConvIntToUint16; break;
|
||||||
|
case EbtUint: newOp = EOpConvUintToUint16; break;
|
||||||
|
case EbtBool: newOp = EOpConvBoolToUint16; break;
|
||||||
|
case EbtFloat: newOp = EOpConvFloatToUint16; break;
|
||||||
|
case EbtDouble: newOp = EOpConvDoubleToUint16; break;
|
||||||
|
case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
|
||||||
|
case EbtInt64: newOp = EOpConvInt64ToUint16; break;
|
||||||
|
case EbtUint64: newOp = EOpConvUint64ToUint16; break;
|
||||||
|
case EbtInt16: newOp = EOpConvInt16ToUint16; break;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -785,7 +875,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert the node's shape of type for the given type, as allowed by the
|
// Convert the node's shape of type for the given type, as allowed by the
|
||||||
// operation involved: 'op'.
|
// operation involved: 'op'. This is for situations where there is only one
|
||||||
|
// direction to consider doing the shape conversion.
|
||||||
|
//
|
||||||
|
// This implements policy, it call addShapeConversion() for the mechanism.
|
||||||
//
|
//
|
||||||
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
|
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
|
||||||
// for GLSL. Bad shapes are caught in conversion or promotion.
|
// for GLSL. Bad shapes are caught in conversion or promotion.
|
||||||
@@ -793,7 +886,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
// Return 'node' if no conversion was done. Promotion handles final shape
|
// Return 'node' if no conversion was done. Promotion handles final shape
|
||||||
// checking.
|
// checking.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
|
TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
|
||||||
{
|
{
|
||||||
// some source languages don't do this
|
// some source languages don't do this
|
||||||
switch (source) {
|
switch (source) {
|
||||||
@@ -806,23 +899,142 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
|
|||||||
|
|
||||||
// some operations don't do this
|
// some operations don't do this
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
case EOpFunctionCall:
|
||||||
|
case EOpReturn:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpMulAssign:
|
||||||
|
// want to support vector *= scalar native ops in AST and lower, not smear, similarly for
|
||||||
|
// matrix *= scalar, etc.
|
||||||
|
|
||||||
|
case EOpAddAssign:
|
||||||
|
case EOpSubAssign:
|
||||||
|
case EOpDivAssign:
|
||||||
|
case EOpAndAssign:
|
||||||
|
case EOpInclusiveOrAssign:
|
||||||
|
case EOpExclusiveOrAssign:
|
||||||
|
case EOpRightShiftAssign:
|
||||||
|
case EOpLeftShiftAssign:
|
||||||
|
if (node->getVectorSize() == 1)
|
||||||
|
return node;
|
||||||
|
break;
|
||||||
|
|
||||||
case EOpAssign:
|
case EOpAssign:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpMix:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addShapeConversion(type, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the nodes' shapes to be compatible for the operation 'op'.
|
||||||
|
//
|
||||||
|
// This implements policy, it call addShapeConversion() for the mechanism.
|
||||||
|
//
|
||||||
|
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
|
||||||
|
// for GLSL. Bad shapes are caught in conversion or promotion.
|
||||||
|
//
|
||||||
|
void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
|
||||||
|
{
|
||||||
|
// some source languages don't do this
|
||||||
|
switch (source) {
|
||||||
|
case EShSourceHlsl:
|
||||||
|
break;
|
||||||
|
case EShSourceGlsl:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// some operations don't do this
|
||||||
|
// 'break' will mean attempt bidirectional conversion
|
||||||
|
switch (op) {
|
||||||
|
case EOpMulAssign:
|
||||||
|
case EOpAssign:
|
||||||
|
case EOpAddAssign:
|
||||||
|
case EOpSubAssign:
|
||||||
|
case EOpDivAssign:
|
||||||
|
case EOpAndAssign:
|
||||||
|
case EOpInclusiveOrAssign:
|
||||||
|
case EOpExclusiveOrAssign:
|
||||||
|
case EOpRightShiftAssign:
|
||||||
|
case EOpLeftShiftAssign:
|
||||||
|
// switch to unidirectional conversion (the lhs can't change)
|
||||||
|
rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EOpAdd:
|
||||||
|
case EOpSub:
|
||||||
|
case EOpMul:
|
||||||
|
case EOpDiv:
|
||||||
|
// want to support vector * scalar native ops in AST and lower, not smear, similarly for
|
||||||
|
// matrix * vector, etc.
|
||||||
|
if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpRightShift:
|
||||||
|
case EOpLeftShift:
|
||||||
|
// can natively support the right operand being a scalar and the left a vector,
|
||||||
|
// but not the reverse
|
||||||
|
if (rhsNode->getVectorSize() == 1)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
case EOpLessThan:
|
case EOpLessThan:
|
||||||
case EOpGreaterThan:
|
case EOpGreaterThan:
|
||||||
case EOpLessThanEqual:
|
case EOpLessThanEqual:
|
||||||
case EOpGreaterThanEqual:
|
case EOpGreaterThanEqual:
|
||||||
|
|
||||||
case EOpEqual:
|
case EOpEqual:
|
||||||
case EOpNotEqual:
|
case EOpNotEqual:
|
||||||
case EOpFunctionCall:
|
|
||||||
case EOpReturn:
|
|
||||||
case EOpLogicalAnd:
|
case EOpLogicalAnd:
|
||||||
case EOpLogicalOr:
|
case EOpLogicalOr:
|
||||||
case EOpLogicalXor:
|
case EOpLogicalXor:
|
||||||
|
|
||||||
|
case EOpAnd:
|
||||||
|
case EOpInclusiveOr:
|
||||||
|
case EOpExclusiveOr:
|
||||||
|
|
||||||
|
case EOpMix:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return node;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do bidirectional conversions
|
||||||
|
if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
|
||||||
|
if (lhsNode->getType().isScalarOrVec1())
|
||||||
|
lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
|
||||||
|
else
|
||||||
|
rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
|
||||||
|
}
|
||||||
|
lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
|
||||||
|
rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the node's shape of type for the given type. It's not necessarily
|
||||||
|
// an error if they are different and not converted, as some operations accept
|
||||||
|
// mixed types. Promotion will do final shape checking.
|
||||||
|
//
|
||||||
|
// If there is a chance of two nodes, with conversions possible in each direction,
|
||||||
|
// the policy for what to ask for must be in the caller; this will do what is asked.
|
||||||
|
//
|
||||||
|
// Return 'node' if no conversion was done. Promotion handles final shape
|
||||||
|
// checking.
|
||||||
|
//
|
||||||
|
TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
|
||||||
|
{
|
||||||
|
// no conversion needed
|
||||||
|
if (node->getType() == type)
|
||||||
|
return node;
|
||||||
|
|
||||||
// structures and arrays don't change shape, either to or from
|
// structures and arrays don't change shape, either to or from
|
||||||
if (node->getType().isStruct() || node->getType().isArray() ||
|
if (node->getType().isStruct() || node->getType().isArray() ||
|
||||||
type.isStruct() || type.isArray())
|
type.isStruct() || type.isArray())
|
||||||
@@ -831,12 +1043,12 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
|
|||||||
// The new node that handles the conversion
|
// The new node that handles the conversion
|
||||||
TOperator constructorOp = mapTypeToConstructorOp(type);
|
TOperator constructorOp = mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
// scalar -> smeared -> vector, or
|
// scalar -> vector or vec1 -> vector or
|
||||||
// vec1 -> scalar, or
|
// vector -> scalar or
|
||||||
// bigger vector -> smaller vector or scalar
|
// bigger vector -> smaller vector
|
||||||
if ((type.isVector() && node->getType().isScalar()) ||
|
if ((node->getType().isScalarOrVec1() && type.isVector()) ||
|
||||||
(node->getType().isVector() && node->getVectorSize() == 1 && type.isScalar()) ||
|
(node->getType().isVector() && type.isScalar()) ||
|
||||||
(node->getVectorSize() > type.getVectorSize() && type.isVector()))
|
(node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
|
||||||
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -894,6 +1106,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
@@ -907,6 +1123,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
@@ -920,8 +1140,12 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
return version >= 400;
|
return version >= 400 || (source == EShSourceHlsl);
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
return (source == EShSourceHlsl);
|
return (source == EShSourceHlsl);
|
||||||
@@ -931,6 +1155,9 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
return (source == EShSourceHlsl);
|
return (source == EShSourceHlsl);
|
||||||
@@ -943,6 +1170,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -951,10 +1182,32 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtFloat16:
|
||||||
|
switch (from) {
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
case EbtFloat16:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case EbtUint16:
|
||||||
|
switch (from) {
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1094,21 +1347,79 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch(type.getVectorSize()) {
|
if (type.getMatrixCols()) {
|
||||||
case 1: op = EOpConstructInt; break;
|
switch (type.getMatrixCols()) {
|
||||||
case 2: op = EOpConstructIVec2; break;
|
case 2:
|
||||||
case 3: op = EOpConstructIVec3; break;
|
switch (type.getMatrixRows()) {
|
||||||
case 4: op = EOpConstructIVec4; break;
|
case 2: op = EOpConstructIMat2x2; break;
|
||||||
default: break; // some compilers want this
|
case 3: op = EOpConstructIMat2x3; break;
|
||||||
|
case 4: op = EOpConstructIMat2x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructIMat3x2; break;
|
||||||
|
case 3: op = EOpConstructIMat3x3; break;
|
||||||
|
case 4: op = EOpConstructIMat3x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructIMat4x2; break;
|
||||||
|
case 3: op = EOpConstructIMat4x3; break;
|
||||||
|
case 4: op = EOpConstructIMat4x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(type.getVectorSize()) {
|
||||||
|
case 1: op = EOpConstructInt; break;
|
||||||
|
case 2: op = EOpConstructIVec2; break;
|
||||||
|
case 3: op = EOpConstructIVec3; break;
|
||||||
|
case 4: op = EOpConstructIVec4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch(type.getVectorSize()) {
|
if (type.getMatrixCols()) {
|
||||||
case 1: op = EOpConstructUint; break;
|
switch (type.getMatrixCols()) {
|
||||||
case 2: op = EOpConstructUVec2; break;
|
case 2:
|
||||||
case 3: op = EOpConstructUVec3; break;
|
switch (type.getMatrixRows()) {
|
||||||
case 4: op = EOpConstructUVec4; break;
|
case 2: op = EOpConstructUMat2x2; break;
|
||||||
default: break; // some compilers want this
|
case 3: op = EOpConstructUMat2x3; break;
|
||||||
|
case 4: op = EOpConstructUMat2x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructUMat3x2; break;
|
||||||
|
case 3: op = EOpConstructUMat3x3; break;
|
||||||
|
case 4: op = EOpConstructUMat3x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructUMat4x2; break;
|
||||||
|
case 3: op = EOpConstructUMat4x3; break;
|
||||||
|
case 4: op = EOpConstructUMat4x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(type.getVectorSize()) {
|
||||||
|
case 1: op = EOpConstructUint; break;
|
||||||
|
case 2: op = EOpConstructUVec2; break;
|
||||||
|
case 3: op = EOpConstructUVec3; break;
|
||||||
|
case 4: op = EOpConstructUVec4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
@@ -1129,15 +1440,64 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
|
|||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtBool:
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
switch(type.getVectorSize()) {
|
switch(type.getVectorSize()) {
|
||||||
case 1: op = EOpConstructBool; break;
|
case 1: op = EOpConstructInt16; break;
|
||||||
case 2: op = EOpConstructBVec2; break;
|
case 2: op = EOpConstructI16Vec2; break;
|
||||||
case 3: op = EOpConstructBVec3; break;
|
case 3: op = EOpConstructI16Vec3; break;
|
||||||
case 4: op = EOpConstructBVec4; break;
|
case 4: op = EOpConstructI16Vec4; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
switch(type.getVectorSize()) {
|
||||||
|
case 1: op = EOpConstructUint16; break;
|
||||||
|
case 2: op = EOpConstructU16Vec2; break;
|
||||||
|
case 3: op = EOpConstructU16Vec3; break;
|
||||||
|
case 4: op = EOpConstructU16Vec4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case EbtBool:
|
||||||
|
if (type.getMatrixCols()) {
|
||||||
|
switch (type.getMatrixCols()) {
|
||||||
|
case 2:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructBMat2x2; break;
|
||||||
|
case 3: op = EOpConstructBMat2x3; break;
|
||||||
|
case 4: op = EOpConstructBMat2x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructBMat3x2; break;
|
||||||
|
case 3: op = EOpConstructBMat3x3; break;
|
||||||
|
case 4: op = EOpConstructBMat3x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
switch (type.getMatrixRows()) {
|
||||||
|
case 2: op = EOpConstructBMat4x2; break;
|
||||||
|
case 3: op = EOpConstructBMat4x3; break;
|
||||||
|
case 4: op = EOpConstructBMat4x4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(type.getVectorSize()) {
|
||||||
|
case 1: op = EOpConstructBool; break;
|
||||||
|
case 2: op = EOpConstructBVec2; break;
|
||||||
|
case 3: op = EOpConstructBVec3; break;
|
||||||
|
case 4: op = EOpConstructBVec4; break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1158,15 +1518,15 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
TIntermAggregate* aggNode = nullptr;
|
TIntermAggregate* aggNode = nullptr;
|
||||||
if (left)
|
if (left != nullptr)
|
||||||
aggNode = left->getAsAggregate();
|
aggNode = left->getAsAggregate();
|
||||||
if (! aggNode || aggNode->getOp() != EOpNull) {
|
if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
|
||||||
aggNode = new TIntermAggregate;
|
aggNode = new TIntermAggregate;
|
||||||
if (left)
|
if (left != nullptr)
|
||||||
aggNode->getSequence().push_back(left);
|
aggNode->getSequence().push_back(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right)
|
if (right != nullptr)
|
||||||
aggNode->getSequence().push_back(right);
|
aggNode->getSequence().push_back(right);
|
||||||
|
|
||||||
return aggNode;
|
return aggNode;
|
||||||
@@ -1271,7 +1631,8 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
|
|||||||
//
|
//
|
||||||
// For "?:" test nodes. There are three children; a condition,
|
// For "?:" test nodes. There are three children; a condition,
|
||||||
// a true path, and a false path. The two paths are specified
|
// a true path, and a false path. The two paths are specified
|
||||||
// as separate parameters.
|
// as separate parameters. For vector 'cond', the true and false
|
||||||
|
// are not paths, but vectors to mix.
|
||||||
//
|
//
|
||||||
// Specialization constant operations include
|
// Specialization constant operations include
|
||||||
// - The ternary operator ( ? : )
|
// - The ternary operator ( ? : )
|
||||||
@@ -1300,14 +1661,39 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle a vector condition as a mix
|
||||||
|
if (!cond->getType().isScalarOrVec1()) {
|
||||||
|
TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
|
||||||
|
cond->getType().getVectorSize());
|
||||||
|
// smear true/false operands as needed
|
||||||
|
trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
|
||||||
|
falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);
|
||||||
|
|
||||||
|
// After conversion, types have to match.
|
||||||
|
if (falseBlock->getType() != trueBlock->getType())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// make the mix operation
|
||||||
|
TIntermAggregate* mix = makeAggregate(loc);
|
||||||
|
mix = growAggregate(mix, falseBlock);
|
||||||
|
mix = growAggregate(mix, trueBlock);
|
||||||
|
mix = growAggregate(mix, cond);
|
||||||
|
mix->setType(targetVectorType);
|
||||||
|
mix->setOp(EOpMix);
|
||||||
|
|
||||||
|
return mix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now have a scalar condition...
|
||||||
|
|
||||||
|
// Convert true and false expressions to matching types
|
||||||
|
addBiShapeConversion(EOpMix, trueBlock, falseBlock);
|
||||||
|
|
||||||
// After conversion, types have to match.
|
// After conversion, types have to match.
|
||||||
if (falseBlock->getType() != trueBlock->getType())
|
if (falseBlock->getType() != trueBlock->getType())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
//
|
// Eliminate the selection when the condition is a scalar and all operands are constant.
|
||||||
// See if all the operands are constant, then fold it otherwise not.
|
|
||||||
//
|
|
||||||
|
|
||||||
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
|
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
|
||||||
if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
|
if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
|
||||||
return trueBlock;
|
return trueBlock;
|
||||||
@@ -1381,6 +1767,24 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, co
|
|||||||
return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
|
return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const
|
||||||
|
{
|
||||||
|
TConstUnionArray unionArray(1);
|
||||||
|
unionArray[0].setIConst(i16);
|
||||||
|
|
||||||
|
return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const
|
||||||
|
{
|
||||||
|
TConstUnionArray unionArray(1);
|
||||||
|
unionArray[0].setUConst(u16);
|
||||||
|
|
||||||
|
return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
|
TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
|
||||||
{
|
{
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
@@ -1478,10 +1882,11 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
|
|||||||
//
|
//
|
||||||
// Create while and do-while loop nodes.
|
// Create while and do-while loop nodes.
|
||||||
//
|
//
|
||||||
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
|
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
|
||||||
{
|
{
|
||||||
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
||||||
node->setLoc(loc);
|
node->setLoc(loc);
|
||||||
|
node->setLoopControl(control);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -1489,13 +1894,19 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
|
|||||||
//
|
//
|
||||||
// Create a for-loop sequence.
|
// Create a for-loop sequence.
|
||||||
//
|
//
|
||||||
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
|
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
|
||||||
{
|
{
|
||||||
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
||||||
node->setLoc(loc);
|
node->setLoc(loc);
|
||||||
|
node->setLoopControl(control);
|
||||||
|
|
||||||
// make a sequence of the initializer and statement
|
// make a sequence of the initializer and statement, but try to reuse the
|
||||||
TIntermAggregate* loopSequence = makeAggregate(initializer, loc);
|
// aggregate already created for whatever is in the initializer, if there is one
|
||||||
|
TIntermAggregate* loopSequence = (initializer == nullptr ||
|
||||||
|
initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
|
||||||
|
: initializer->getAsAggregate();
|
||||||
|
if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
|
||||||
|
loopSequence->setOp(EOpNull);
|
||||||
loopSequence = growAggregate(loopSequence, node);
|
loopSequence = growAggregate(loopSequence, node);
|
||||||
loopSequence->setOperator(EOpSequence);
|
loopSequence->setOperator(EOpSequence);
|
||||||
|
|
||||||
@@ -1535,6 +1946,14 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
|
|||||||
// Propagate 'noContraction' label in backward from 'precise' variables.
|
// Propagate 'noContraction' label in backward from 'precise' variables.
|
||||||
glslang::PropagateNoContraction(*this);
|
glslang::PropagateNoContraction(*this);
|
||||||
|
|
||||||
|
switch (textureSamplerTransformMode) {
|
||||||
|
case EShTexSampTransKeep:
|
||||||
|
break;
|
||||||
|
case EShTexSampTransUpgradeTextureRemoveSampler:
|
||||||
|
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1725,6 +2144,30 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
|
|||||||
case EOpConvUintToInt64:
|
case EOpConvUintToInt64:
|
||||||
case EOpConvUint64ToInt:
|
case EOpConvUint64ToInt:
|
||||||
case EOpConvIntToUint64:
|
case EOpConvIntToUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConvInt16ToBool:
|
||||||
|
case EOpConvBoolToInt16:
|
||||||
|
case EOpConvInt16ToInt:
|
||||||
|
case EOpConvIntToInt16:
|
||||||
|
case EOpConvInt16ToUint:
|
||||||
|
case EOpConvUintToInt16:
|
||||||
|
case EOpConvInt16ToInt64:
|
||||||
|
case EOpConvInt64ToInt16:
|
||||||
|
case EOpConvInt16ToUint64:
|
||||||
|
case EOpConvUint64ToInt16:
|
||||||
|
case EOpConvUint16ToBool:
|
||||||
|
case EOpConvBoolToUint16:
|
||||||
|
case EOpConvUint16ToInt:
|
||||||
|
case EOpConvIntToUint16:
|
||||||
|
case EOpConvUint16ToUint:
|
||||||
|
case EOpConvUintToUint16:
|
||||||
|
case EOpConvUint16ToInt64:
|
||||||
|
case EOpConvInt64ToUint16:
|
||||||
|
case EOpConvUint16ToUint64:
|
||||||
|
case EOpConvUint64ToUint16:
|
||||||
|
case EOpConvInt16ToUint16:
|
||||||
|
case EOpConvUint16ToInt16:
|
||||||
|
#endif
|
||||||
|
|
||||||
// unary operations
|
// unary operations
|
||||||
case EOpNegative:
|
case EOpNegative:
|
||||||
@@ -1853,6 +2296,10 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
|||||||
case EOpBitwiseNot:
|
case EOpBitwiseNot:
|
||||||
if (operand->getBasicType() != EbtInt &&
|
if (operand->getBasicType() != EbtInt &&
|
||||||
operand->getBasicType() != EbtUint &&
|
operand->getBasicType() != EbtUint &&
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
operand->getBasicType() != EbtInt16 &&
|
||||||
|
operand->getBasicType() != EbtUint16 &&
|
||||||
|
#endif
|
||||||
operand->getBasicType() != EbtInt64 &&
|
operand->getBasicType() != EbtInt64 &&
|
||||||
operand->getBasicType() != EbtUint64)
|
operand->getBasicType() != EbtUint64)
|
||||||
|
|
||||||
@@ -1867,6 +2314,10 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
|||||||
operand->getBasicType() != EbtUint &&
|
operand->getBasicType() != EbtUint &&
|
||||||
operand->getBasicType() != EbtInt64 &&
|
operand->getBasicType() != EbtInt64 &&
|
||||||
operand->getBasicType() != EbtUint64 &&
|
operand->getBasicType() != EbtUint64 &&
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
operand->getBasicType() != EbtInt16 &&
|
||||||
|
operand->getBasicType() != EbtUint16 &&
|
||||||
|
#endif
|
||||||
operand->getBasicType() != EbtFloat &&
|
operand->getBasicType() != EbtFloat &&
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
operand->getBasicType() != EbtFloat16 &&
|
operand->getBasicType() != EbtFloat16 &&
|
||||||
@@ -1967,6 +2418,42 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
|||||||
// We now have only scalars, vectors, and matrices to worry about.
|
// We now have only scalars, vectors, and matrices to worry about.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// HLSL implicitly promotes bool -> int for numeric operations.
|
||||||
|
// (Implicit conversions to make the operands match each other's types were already done.)
|
||||||
|
if (getSource() == EShSourceHlsl &&
|
||||||
|
(left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) {
|
||||||
|
switch (op) {
|
||||||
|
case EOpLessThan:
|
||||||
|
case EOpGreaterThan:
|
||||||
|
case EOpLessThanEqual:
|
||||||
|
case EOpGreaterThanEqual:
|
||||||
|
|
||||||
|
case EOpRightShift:
|
||||||
|
case EOpLeftShift:
|
||||||
|
|
||||||
|
case EOpMod:
|
||||||
|
|
||||||
|
case EOpAnd:
|
||||||
|
case EOpInclusiveOr:
|
||||||
|
case EOpExclusiveOr:
|
||||||
|
|
||||||
|
case EOpAdd:
|
||||||
|
case EOpSub:
|
||||||
|
case EOpDiv:
|
||||||
|
case EOpMul:
|
||||||
|
left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left);
|
||||||
|
right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right);
|
||||||
|
if (left == nullptr || right == nullptr)
|
||||||
|
return false;
|
||||||
|
node.setLeft(left);
|
||||||
|
node.setRight(right);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
|
// Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpLessThan:
|
case EOpLessThan:
|
||||||
@@ -2037,8 +2524,14 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
|||||||
|
|
||||||
// Check for integer-only operands.
|
// Check for integer-only operands.
|
||||||
if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint &&
|
if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint &&
|
||||||
left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) ||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 &&
|
||||||
|
#endif
|
||||||
|
left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) ||
|
||||||
(right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
|
(right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 &&
|
||||||
|
#endif
|
||||||
right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
|
right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
|
||||||
return false;
|
return false;
|
||||||
if (left->isMatrix() || right->isMatrix())
|
if (left->isMatrix() || right->isMatrix())
|
||||||
@@ -2079,8 +2572,6 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
|||||||
case EOpLogicalXor:
|
case EOpLogicalXor:
|
||||||
return left->getType() == right->getType();
|
return left->getType() == right->getType();
|
||||||
|
|
||||||
// no shifts: they can mix types (scalar int can shift a vector uint, etc.)
|
|
||||||
|
|
||||||
case EOpMod:
|
case EOpMod:
|
||||||
case EOpModAssign:
|
case EOpModAssign:
|
||||||
|
|
||||||
@@ -2094,6 +2585,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
|||||||
case EOpAdd:
|
case EOpAdd:
|
||||||
case EOpSub:
|
case EOpSub:
|
||||||
case EOpDiv:
|
case EOpDiv:
|
||||||
|
|
||||||
case EOpAddAssign:
|
case EOpAddAssign:
|
||||||
case EOpSubAssign:
|
case EOpSubAssign:
|
||||||
case EOpDivAssign:
|
case EOpDivAssign:
|
||||||
@@ -2118,7 +2610,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Finish handling the case, for all ops, where there are two vectors of different sizes
|
// Finish handling the case, for all ops, where there are two vectors of different sizes
|
||||||
if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
|
if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -2667,4 +3159,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
|
|||||||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
|
||||||
|
bool visitAggregate(TVisit, TIntermAggregate* ag) override {
|
||||||
|
using namespace std;
|
||||||
|
TIntermSequence& seq = ag->getSequence();
|
||||||
|
// remove pure sampler variables
|
||||||
|
TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
|
||||||
|
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||||
|
if (!symbol)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
|
||||||
|
});
|
||||||
|
seq.erase(newEnd, seq.end());
|
||||||
|
// replace constructors with sampler/textures
|
||||||
|
// update textures into sampled textures
|
||||||
|
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
|
||||||
|
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||||
|
if (!symbol) {
|
||||||
|
TIntermAggregate *constructor = node->getAsAggregate();
|
||||||
|
if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
|
||||||
|
if (!constructor->getSequence().empty())
|
||||||
|
node = constructor->getSequence()[0];
|
||||||
|
}
|
||||||
|
} else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
|
||||||
|
symbol->getWritableType().getSampler().combined = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
|
||||||
|
{
|
||||||
|
TextureUpgradeAndSamplerRemovalTransform transform;
|
||||||
|
root->traverse(&transform);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
|
|||||||
@@ -226,7 +226,8 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
// Add 'symbol' to the list of deferred linkage symbols, which
|
// Add 'symbol' to the list of deferred linkage symbols, which
|
||||||
// are later processed in finish(), at which point the symbol
|
// are later processed in finish(), at which point the symbol
|
||||||
// must still be valid.
|
// must still be valid.
|
||||||
// It is okay if the symbol's type will be subsequently edited.
|
// It is okay if the symbol's type will be subsequently edited;
|
||||||
|
// the modifications will be tracked.
|
||||||
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||||
{
|
{
|
||||||
if (!parsingBuiltins)
|
if (!parsingBuiltins)
|
||||||
@@ -530,21 +531,20 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
|
|||||||
// Make the passed-in variable information become a member of the
|
// Make the passed-in variable information become a member of the
|
||||||
// global uniform block. If this doesn't exist yet, make it.
|
// global uniform block. If this doesn't exist yet, make it.
|
||||||
//
|
//
|
||||||
void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName, TTypeList* typeList)
|
void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList)
|
||||||
{
|
{
|
||||||
// make the global block, if not yet made
|
// Make the global block, if not yet made.
|
||||||
if (globalUniformBlock == nullptr) {
|
if (globalUniformBlock == nullptr) {
|
||||||
TString& blockName = *NewPoolTString(getGlobalUniformBlockName());
|
|
||||||
TQualifier blockQualifier;
|
TQualifier blockQualifier;
|
||||||
blockQualifier.clear();
|
blockQualifier.clear();
|
||||||
blockQualifier.storage = EvqUniform;
|
blockQualifier.storage = EvqUniform;
|
||||||
TType blockType(new TTypeList, blockName, blockQualifier);
|
TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
|
||||||
TString* instanceName = NewPoolTString("");
|
setUniformBlockDefaults(blockType);
|
||||||
globalUniformBlock = new TVariable(instanceName, blockType, true);
|
globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
|
||||||
firstNewMember = 0;
|
firstNewMember = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the requested member as a member to the 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);
|
||||||
type->setFieldName(memberName);
|
type->setFieldName(memberName);
|
||||||
@@ -552,36 +552,20 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp
|
|||||||
type->setStruct(typeList);
|
type->setStruct(typeList);
|
||||||
TTypeLoc typeLoc = {type, loc};
|
TTypeLoc typeLoc = {type, loc};
|
||||||
globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
|
globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
|
||||||
}
|
|
||||||
|
|
||||||
//
|
// Insert into the symbol table.
|
||||||
// Insert into the symbol table the global uniform block created in
|
|
||||||
// growGlobalUniformBlock(). The variables added as members won't be
|
|
||||||
// found unless this is done.
|
|
||||||
//
|
|
||||||
bool TParseContextBase::insertGlobalUniformBlock()
|
|
||||||
{
|
|
||||||
if (globalUniformBlock == nullptr)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
int numMembers = (int)globalUniformBlock->getType().getStruct()->size();
|
|
||||||
bool inserted = false;
|
|
||||||
if (firstNewMember == 0) {
|
if (firstNewMember == 0) {
|
||||||
// This is the first request; we need a normal symbol table insert
|
// This is the first request; we need a normal symbol table insert
|
||||||
inserted = symbolTable.insert(*globalUniformBlock);
|
if (symbolTable.insert(*globalUniformBlock))
|
||||||
if (inserted)
|
|
||||||
trackLinkage(*globalUniformBlock);
|
trackLinkage(*globalUniformBlock);
|
||||||
} else if (firstNewMember <= numMembers) {
|
else
|
||||||
|
error(loc, "failed to insert the global constant buffer", "uniform", "");
|
||||||
|
} else {
|
||||||
// This is a follow-on request; we need to amend the first insert
|
// This is a follow-on request; we need to amend the first insert
|
||||||
inserted = symbolTable.amend(*globalUniformBlock, firstNewMember);
|
symbolTable.amend(*globalUniformBlock, firstNewMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inserted) {
|
++firstNewMember;
|
||||||
finalizeGlobalUniformBlockLayout(*globalUniformBlock);
|
|
||||||
firstNewMember = numMembers;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inserted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContextBase::finish()
|
void TParseContextBase::finish()
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
|
|||||||
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
||||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
||||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
|
inMain(false),
|
||||||
inMain(false), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
|
blockName(nullptr),
|
||||||
limits(resources.limits),
|
limits(resources.limits),
|
||||||
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
||||||
{
|
{
|
||||||
@@ -255,6 +255,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||||||
error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
|
error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
|
||||||
|
if (tokens.size() != 1)
|
||||||
|
error(loc, "extra tokens", "#pragma", "");
|
||||||
|
intermediate.setUseStorageBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,10 +346,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
|
|||||||
TIntermTyped* result = nullptr;
|
TIntermTyped* result = nullptr;
|
||||||
|
|
||||||
int indexValue = 0;
|
int indexValue = 0;
|
||||||
if (index->getQualifier().isFrontEndConstant()) {
|
if (index->getQualifier().isFrontEndConstant())
|
||||||
indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
|
indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
checkIndex(loc, base->getType(), indexValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
variableCheck(base);
|
variableCheck(base);
|
||||||
if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
|
if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
|
||||||
@@ -353,10 +355,12 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
|
|||||||
error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
|
error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
|
||||||
else
|
else
|
||||||
error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
|
error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
|
||||||
} else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant())
|
} else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
|
||||||
|
// both base and index are front-end constants
|
||||||
|
checkIndex(loc, base->getType(), indexValue);
|
||||||
return intermediate.foldDereference(base, indexValue, loc);
|
return intermediate.foldDereference(base, indexValue, loc);
|
||||||
else {
|
} else {
|
||||||
// at least one of base and index is variable...
|
// at least one of base and index is not a front-end constant variable...
|
||||||
|
|
||||||
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
|
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
|
||||||
handleIoResizeArrayAccess(loc, base);
|
handleIoResizeArrayAccess(loc, base);
|
||||||
@@ -364,6 +368,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
|
|||||||
if (index->getQualifier().isFrontEndConstant()) {
|
if (index->getQualifier().isFrontEndConstant()) {
|
||||||
if (base->getType().isImplicitlySizedArray())
|
if (base->getType().isImplicitlySizedArray())
|
||||||
updateImplicitArraySize(loc, base, indexValue);
|
updateImplicitArraySize(loc, base, indexValue);
|
||||||
|
else
|
||||||
|
checkIndex(loc, base->getType(), indexValue);
|
||||||
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
|
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
|
||||||
} else {
|
} else {
|
||||||
if (base->getType().isImplicitlySizedArray()) {
|
if (base->getType().isImplicitlySizedArray()) {
|
||||||
@@ -906,7 +912,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
|
|||||||
loopNestingLevel = 0;
|
loopNestingLevel = 0;
|
||||||
statementNestingLevel = 0;
|
statementNestingLevel = 0;
|
||||||
controlFlowNestingLevel = 0;
|
controlFlowNestingLevel = 0;
|
||||||
postMainReturn = false;
|
postEntryPointReturn = false;
|
||||||
|
|
||||||
return paramNodes;
|
return paramNodes;
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1193,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
|
|||||||
error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
|
error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
|
||||||
if (! inMain)
|
if (! inMain)
|
||||||
error(loc, "tessellation control barrier() must be in main()", "", "");
|
error(loc, "tessellation control barrier() must be in main()", "", "");
|
||||||
else if (postMainReturn)
|
else if (postEntryPointReturn)
|
||||||
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
|
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1436,9 +1442,56 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
error(loc, "must be a compile-time constant:", feature, "component argument");
|
error(loc, "must be a compile-time constant:", feature, "component argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool bias = false;
|
||||||
|
if (callNode.getOp() == EOpTextureGather)
|
||||||
|
bias = fnCandidate.getParamCount() > 3;
|
||||||
|
else if (callNode.getOp() == EOpTextureGatherOffset ||
|
||||||
|
callNode.getOp() == EOpTextureGatherOffsets)
|
||||||
|
bias = fnCandidate.getParamCount() > 4;
|
||||||
|
|
||||||
|
if (bias) {
|
||||||
|
TString biasFeatureString = fnCandidate.getName() + "with bias argument";
|
||||||
|
const char* feature = biasFeatureString.c_str();
|
||||||
|
profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
|
||||||
|
requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpSparseTextureGather:
|
||||||
|
case EOpSparseTextureGatherOffset:
|
||||||
|
case EOpSparseTextureGatherOffsets:
|
||||||
|
{
|
||||||
|
bool bias = false;
|
||||||
|
if (callNode.getOp() == EOpSparseTextureGather)
|
||||||
|
bias = fnCandidate.getParamCount() > 4;
|
||||||
|
else if (callNode.getOp() == EOpSparseTextureGatherOffset ||
|
||||||
|
callNode.getOp() == EOpSparseTextureGatherOffsets)
|
||||||
|
bias = fnCandidate.getParamCount() > 5;
|
||||||
|
|
||||||
|
if (bias) {
|
||||||
|
TString featureString = fnCandidate.getName() + "with bias argument";
|
||||||
|
const char* feature = featureString.c_str();
|
||||||
|
profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
|
||||||
|
requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EOpSparseTextureGatherLod:
|
||||||
|
case EOpSparseTextureGatherLodOffset:
|
||||||
|
case EOpSparseTextureGatherLodOffsets:
|
||||||
|
{
|
||||||
|
requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpTextureOffset:
|
case EOpTextureOffset:
|
||||||
case EOpTextureFetchOffset:
|
case EOpTextureFetchOffset:
|
||||||
case EOpTextureProjOffset:
|
case EOpTextureProjOffset:
|
||||||
@@ -2096,6 +2149,17 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||||||
case EOpConstructDMat4x2:
|
case EOpConstructDMat4x2:
|
||||||
case EOpConstructDMat4x3:
|
case EOpConstructDMat4x3:
|
||||||
case EOpConstructDMat4x4:
|
case EOpConstructDMat4x4:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructF16Mat2x2:
|
||||||
|
case EOpConstructF16Mat2x3:
|
||||||
|
case EOpConstructF16Mat2x4:
|
||||||
|
case EOpConstructF16Mat3x2:
|
||||||
|
case EOpConstructF16Mat3x3:
|
||||||
|
case EOpConstructF16Mat3x4:
|
||||||
|
case EOpConstructF16Mat4x2:
|
||||||
|
case EOpConstructF16Mat4x3:
|
||||||
|
case EOpConstructF16Mat4x4:
|
||||||
|
#endif
|
||||||
constructingMatrix = true;
|
constructingMatrix = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -2156,6 +2220,10 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||||||
case EOpConstructUint:
|
case EOpConstructUint:
|
||||||
case EOpConstructInt64:
|
case EOpConstructInt64:
|
||||||
case EOpConstructUint64:
|
case EOpConstructUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructInt16:
|
||||||
|
case EOpConstructUint16:
|
||||||
|
#endif
|
||||||
case EOpConstructBool:
|
case EOpConstructBool:
|
||||||
case EOpConstructBVec2:
|
case EOpConstructBVec2:
|
||||||
case EOpConstructBVec3:
|
case EOpConstructBVec3:
|
||||||
@@ -2172,6 +2240,14 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||||||
case EOpConstructU64Vec2:
|
case EOpConstructU64Vec2:
|
||||||
case EOpConstructU64Vec3:
|
case EOpConstructU64Vec3:
|
||||||
case EOpConstructU64Vec4:
|
case EOpConstructU64Vec4:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructI16Vec2:
|
||||||
|
case EOpConstructI16Vec3:
|
||||||
|
case EOpConstructI16Vec4:
|
||||||
|
case EOpConstructU16Vec2:
|
||||||
|
case EOpConstructU16Vec3:
|
||||||
|
case EOpConstructU16Vec4:
|
||||||
|
#endif
|
||||||
// This was the list of valid ones, if they aren't converting from float
|
// This was the list of valid ones, if they aren't converting from float
|
||||||
// and aren't making an array.
|
// and aren't making an array.
|
||||||
makeSpecConst = ! floatArgument && ! type.isArray();
|
makeSpecConst = ! floatArgument && ! type.isArray();
|
||||||
@@ -2464,6 +2540,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
|
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 ||
|
||||||
|
#endif
|
||||||
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
|
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
|
||||||
publicType.basicType == EbtDouble)
|
publicType.basicType == EbtDouble)
|
||||||
profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
|
profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
|
||||||
@@ -2474,6 +2553,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
if (!qualifier.flat) {
|
if (!qualifier.flat) {
|
||||||
#endif
|
#endif
|
||||||
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
|
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 ||
|
||||||
|
#endif
|
||||||
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
|
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
|
||||||
publicType.basicType == EbtDouble ||
|
publicType.basicType == EbtDouble ||
|
||||||
(publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) ||
|
(publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) ||
|
||||||
@@ -2894,7 +2976,7 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
|
void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
|
||||||
{
|
{
|
||||||
assert(arraySizes);
|
assert(arraySizes);
|
||||||
|
|
||||||
@@ -2906,10 +2988,13 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
if (initializer)
|
if (initializer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// No environment lets any non-outer-dimension that's to be implicitly sized
|
// No environment allows any non-outer-dimension to be implicitly sized
|
||||||
if (arraySizes->isInnerImplicit())
|
if (arraySizes->isInnerImplicit())
|
||||||
error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
|
error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
|
||||||
|
|
||||||
|
if (arraySizes->isInnerSpecialization())
|
||||||
|
error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
|
||||||
|
|
||||||
// desktop always allows outer-dimension-unsized variable arrays,
|
// desktop always allows outer-dimension-unsized variable arrays,
|
||||||
if (profile != EEsProfile)
|
if (profile != EEsProfile)
|
||||||
return;
|
return;
|
||||||
@@ -2990,7 +3075,7 @@ void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
|
|||||||
// Do all the semantic checking for declaring or redeclaring an array, with and
|
// Do all the semantic checking for declaring or redeclaring an array, with and
|
||||||
// without a size, and make the right changes to the symbol table.
|
// without a size, and make the right changes to the symbol table.
|
||||||
//
|
//
|
||||||
void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol)
|
void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol)
|
||||||
{
|
{
|
||||||
if (symbol == nullptr) {
|
if (symbol == nullptr) {
|
||||||
bool currentScope;
|
bool currentScope;
|
||||||
@@ -4196,6 +4281,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
if (id.compare(0, 11, "local_size_") == 0) {
|
if (id.compare(0, 11, "local_size_") == 0) {
|
||||||
profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
|
profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
|
||||||
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
|
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
|
||||||
|
if (id.size() == 12 && value == 0) {
|
||||||
|
error(loc, "must be at least 1", id.c_str(), "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (id == "local_size_x") {
|
if (id == "local_size_x") {
|
||||||
publicType.shaderQualifiers.localSize[0] = value;
|
publicType.shaderQualifiers.localSize[0] = value;
|
||||||
return;
|
return;
|
||||||
@@ -4246,7 +4335,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
// This is also true for overriding layout-qualifier-names, where one
|
// This is also true for overriding layout-qualifier-names, where one
|
||||||
// overrides the other (e.g., row_major vs. column_major); only the last
|
// overrides the other (e.g., row_major vs. column_major); only the last
|
||||||
// occurrence has any effect."
|
// occurrence has any effect."
|
||||||
//
|
|
||||||
void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
|
void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
|
||||||
{
|
{
|
||||||
if (src.hasMatrix())
|
if (src.hasMatrix())
|
||||||
@@ -4328,6 +4416,25 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// user-variable location check, which are required for SPIR-V in/out:
|
||||||
|
// - variables have it directly,
|
||||||
|
// - blocks have it on each member (already enforced), so check first one
|
||||||
|
if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
|
||||||
|
!qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
|
||||||
|
|
||||||
|
switch (qualifier.storage) {
|
||||||
|
case EvqVaryingIn:
|
||||||
|
case EvqVaryingOut:
|
||||||
|
if (type.getBasicType() != EbtBlock ||
|
||||||
|
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
|
||||||
|
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))
|
||||||
|
error(loc, "SPIR-V requires location for user input/output", "location", "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check packing and matrix
|
// Check packing and matrix
|
||||||
if (qualifier.hasUniformLayout()) {
|
if (qualifier.hasUniformLayout()) {
|
||||||
switch (qualifier.storage) {
|
switch (qualifier.storage) {
|
||||||
@@ -4355,6 +4462,22 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "For some blocks declared as arrays, the location can only be applied at the block level:
|
||||||
|
// When a block is declared as an array where additional locations are needed for each member
|
||||||
|
// for each block array element, it is a compile-time error to specify locations on the block
|
||||||
|
// members. That is, when locations would be under specified by applying them on block members,
|
||||||
|
// they are not allowed on block members. For arrayed interfaces (those generally having an
|
||||||
|
// extra level of arrayness due to interface expansion), the outer array is stripped before
|
||||||
|
// applying this rule."
|
||||||
|
void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, TArraySizes* arraySizes)
|
||||||
|
{
|
||||||
|
if (memberWithLocation && arraySizes != nullptr) {
|
||||||
|
if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0))
|
||||||
|
error(loc, "cannot use in a block array where new locations are needed for each block element",
|
||||||
|
"location", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do layout error checking with respect to a type.
|
// Do layout error checking with respect to a type.
|
||||||
void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||||
{
|
{
|
||||||
@@ -4500,7 +4623,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type.isImage() && ! qualifier.writeonly) {
|
} else if (type.isImage() && ! qualifier.writeonly) {
|
||||||
const char *explanation = "image variables declared 'writeonly' without a format layout qualifier";
|
const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -4529,6 +4652,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
#endif
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
@@ -4692,12 +4819,8 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
|
|||||||
if (symbol.getType().isExplicitlySizedArray())
|
if (symbol.getType().isExplicitlySizedArray())
|
||||||
numOffsets *= symbol.getType().getCumulativeArraySize();
|
numOffsets *= symbol.getType().getCumulativeArraySize();
|
||||||
else {
|
else {
|
||||||
// TODO: functionality: implicitly-sized atomic_uint arrays.
|
// "It is a compile-time error to declare an unsized array of atomic_uint."
|
||||||
// We don't know the full size until later. This might
|
error(loc, "array must be explicitly sized", "atomic_uint", "");
|
||||||
// be a specification problem, will report to Khronos. For the
|
|
||||||
// cases that is not true, the rest of the checking would need
|
|
||||||
// to be done at link time instead of compile time.
|
|
||||||
warn(loc, "implicitly sized atomic_uint array treated as having one element for tracking the default offset", "atomic_uint", "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
|
int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
|
||||||
@@ -4983,7 +5106,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||||||
arrayDimMerge(type, arraySizes);
|
arrayDimMerge(type, arraySizes);
|
||||||
|
|
||||||
// Check that implicit sizing is only where allowed.
|
// Check that implicit sizing is only where allowed.
|
||||||
arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
|
arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
|
||||||
|
|
||||||
if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
|
if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
|
||||||
declareArray(loc, identifier, type, symbol);
|
declareArray(loc, identifier, type, symbol);
|
||||||
@@ -5016,6 +5139,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||||||
|
|
||||||
// look for errors in layout qualifier use
|
// look for errors in layout qualifier use
|
||||||
layoutObjectCheck(loc, *symbol);
|
layoutObjectCheck(loc, *symbol);
|
||||||
|
|
||||||
|
// fix up
|
||||||
fixOffset(loc, *symbol);
|
fixOffset(loc, *symbol);
|
||||||
|
|
||||||
return initNode;
|
return initNode;
|
||||||
@@ -5053,7 +5178,7 @@ TVariable* TParseContext::makeInternalVariable(const char* name, const TType& ty
|
|||||||
//
|
//
|
||||||
// Return the successfully declared variable.
|
// Return the successfully declared variable.
|
||||||
//
|
//
|
||||||
TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, TString& identifier, TType& type)
|
TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type)
|
||||||
{
|
{
|
||||||
// make a new variable
|
// make a new variable
|
||||||
TVariable* variable = new TVariable(&identifier, type);
|
TVariable* variable = new TVariable(&identifier, type);
|
||||||
@@ -5477,6 +5602,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
|||||||
basicOp = EOpConstructUint64;
|
basicOp = EOpConstructUint64;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructI16Vec2:
|
||||||
|
case EOpConstructI16Vec3:
|
||||||
|
case EOpConstructI16Vec4:
|
||||||
|
case EOpConstructInt16:
|
||||||
|
basicOp = EOpConstructInt16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpConstructU16Vec2:
|
||||||
|
case EOpConstructU16Vec3:
|
||||||
|
case EOpConstructU16Vec4:
|
||||||
|
case EOpConstructUint16:
|
||||||
|
basicOp = EOpConstructUint16;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpConstructBVec2:
|
case EOpConstructBVec2:
|
||||||
case EOpConstructBVec3:
|
case EOpConstructBVec3:
|
||||||
case EOpConstructBVec4:
|
case EOpConstructBVec4:
|
||||||
@@ -5533,7 +5674,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
blockStageIoCheck(loc, currentBlockQualifier);
|
blockStageIoCheck(loc, currentBlockQualifier);
|
||||||
blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
|
blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
|
||||||
if (arraySizes) {
|
if (arraySizes) {
|
||||||
arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false, false);
|
arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false);
|
||||||
arrayDimCheck(loc, arraySizes, 0);
|
arrayDimCheck(loc, arraySizes, 0);
|
||||||
if (arraySizes->getNumDims() > 1)
|
if (arraySizes->getNumDims() > 1)
|
||||||
requireProfile(loc, ~EEsProfile, "array-of-array of block");
|
requireProfile(loc, ~EEsProfile, "array-of-array of block");
|
||||||
@@ -5551,7 +5692,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
||||||
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
||||||
if (memberType.isArray())
|
if (memberType.isArray())
|
||||||
arrayUnsizedCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
|
arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
if (spvVersion.spv == 0) {
|
if (spvVersion.spv == 0) {
|
||||||
requireProfile(memberLoc, ~EEsProfile, "offset on block member");
|
requireProfile(memberLoc, ~EEsProfile, "offset on block member");
|
||||||
@@ -5597,11 +5738,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
|
|
||||||
mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
|
mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
|
||||||
|
|
||||||
// "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
|
|
||||||
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||||
if (currentBlockQualifier.hasAlign() || currentBlockQualifier.hasAlign()) {
|
if (currentBlockQualifier.hasAlign()) {
|
||||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
|
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
|
||||||
error(loc, "can only be used with std140 or std430 layout packing", "offset/align", "");
|
error(loc, "can only be used with std140 or std430 layout packing", "align", "");
|
||||||
defaultQualification.layoutAlign = -1;
|
defaultQualification.layoutAlign = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5643,9 +5783,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
memberWithoutLocation = true;
|
memberWithoutLocation = true;
|
||||||
if (memberQualifier.hasAlign()) {
|
|
||||||
|
// "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
|
||||||
|
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||||
|
if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
|
||||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
|
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
|
||||||
error(memberLoc, "can only be used with std140 or std430 layout packing", "align", "");
|
error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TQualifier newMemberQualification = defaultQualification;
|
TQualifier newMemberQualification = defaultQualification;
|
||||||
@@ -5653,6 +5796,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
memberQualifier = newMemberQualification;
|
memberQualifier = newMemberQualification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
|
||||||
|
|
||||||
// Process the members
|
// Process the members
|
||||||
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
|
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
|
||||||
fixBlockXfbOffsets(currentBlockQualifier, typeList);
|
fixBlockXfbOffsets(currentBlockQualifier, typeList);
|
||||||
@@ -5720,6 +5865,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
// Check for general layout qualifier errors
|
// Check for general layout qualifier errors
|
||||||
layoutObjectCheck(loc, variable);
|
layoutObjectCheck(loc, variable);
|
||||||
|
|
||||||
|
// fix up
|
||||||
if (isIoResizeArray(blockType)) {
|
if (isIoResizeArray(blockType)) {
|
||||||
ioArraySymbolResizeList.push_back(&variable);
|
ioArraySymbolResizeList.push_back(&variable);
|
||||||
checkIoArraysConsistency(loc, true);
|
checkIoArraysConsistency(loc, true);
|
||||||
@@ -5768,7 +5914,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do all block-declaration checking regarding its qualifiers.
|
// Do all block-declaration checking regarding its qualifiers.
|
||||||
void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool instanceName)
|
void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/)
|
||||||
{
|
{
|
||||||
// The 4.5 specification says:
|
// The 4.5 specification says:
|
||||||
//
|
//
|
||||||
@@ -5795,11 +5941,8 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
|
|||||||
error(loc, "cannot use sample qualifier on an interface block", "sample", "");
|
error(loc, "cannot use sample qualifier on an interface block", "sample", "");
|
||||||
if (qualifier.invariant)
|
if (qualifier.invariant)
|
||||||
error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
|
error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
|
||||||
if (qualifier.layoutPushConstant) {
|
if (qualifier.layoutPushConstant)
|
||||||
intermediate.addPushConstantCount();
|
intermediate.addPushConstantCount();
|
||||||
if (! instanceName)
|
|
||||||
error(loc, "requires an instance name", "push_constant", "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -5837,7 +5980,7 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi
|
|||||||
if (nextLocation >= (int)TQualifier::layoutLocationEnd)
|
if (nextLocation >= (int)TQualifier::layoutLocationEnd)
|
||||||
error(memberLoc, "location is too large", "location", "");
|
error(memberLoc, "location is too large", "location", "");
|
||||||
memberQualifier.layoutLocation = nextLocation;
|
memberQualifier.layoutLocation = nextLocation;
|
||||||
memberQualifier.layoutComponent = 0;
|
memberQualifier.layoutComponent = TQualifier::layoutComponentEnd;
|
||||||
}
|
}
|
||||||
nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
|
nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ public:
|
|||||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
||||||
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
symbolTable(symbolTable),
|
symbolTable(symbolTable),
|
||||||
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
|
postEntryPointReturn(false),
|
||||||
|
contextPragma(true, false),
|
||||||
|
limits(resources.limits),
|
||||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||||
globalUniformBlock(nullptr)
|
globalUniformBlock(nullptr)
|
||||||
{ }
|
{ }
|
||||||
@@ -133,18 +137,31 @@ public:
|
|||||||
extensionCallback(line, extension, behavior);
|
extensionCallback(line, extension, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
|
||||||
|
|
||||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
// TODO: This could perhaps get its own object, but the current design doesn't work
|
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
||||||
// yet when new uniform variables are declared between function definitions, so
|
|
||||||
// this is pending getting a fully functional design.
|
|
||||||
virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName, TTypeList* typeList = nullptr);
|
|
||||||
virtual bool insertGlobalUniformBlock();
|
|
||||||
|
|
||||||
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
|
|
||||||
|
const char* const scopeMangler = "::";
|
||||||
|
|
||||||
|
// Basic parsing state, easily accessible to the grammar
|
||||||
|
|
||||||
|
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||||
|
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
||||||
|
int loopNestingLevel; // 0 if outside all loops
|
||||||
|
int structNestingLevel; // 0 if outside blocks and structures
|
||||||
|
int controlFlowNestingLevel; // 0 if outside all flow control
|
||||||
|
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||||
|
bool functionReturnsValue; // true if a non-void function has a return
|
||||||
|
// if inside a function, true if the function is the entry point and this is after a return statement
|
||||||
|
bool postEntryPointReturn;
|
||||||
|
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
||||||
|
TList<TIntermSequence*> switchSequenceStack;
|
||||||
|
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
|
TList<int> switchLevel;
|
||||||
|
struct TPragma contextPragma;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
TParseContextBase& operator=(TParseContextBase&);
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
@@ -153,6 +170,8 @@ protected:
|
|||||||
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
||||||
TScanContext* scanContext;
|
TScanContext* scanContext;
|
||||||
TPpContext* ppContext;
|
TPpContext* ppContext;
|
||||||
|
TBuiltInResource resources;
|
||||||
|
TLimits& limits;
|
||||||
|
|
||||||
// These, if set, will be called when a line, pragma ... is preprocessed.
|
// These, if set, will be called when a line, pragma ... is preprocessed.
|
||||||
// They will be called with any parameters to the original directive.
|
// They will be called with any parameters to the original directive.
|
||||||
@@ -175,7 +194,8 @@ protected:
|
|||||||
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
|
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
|
||||||
int firstNewMember; // the index of the first member not yet inserted into the symbol table
|
int firstNewMember; // the index of the first member not yet inserted into the symbol table
|
||||||
// override this to set the language-specific name
|
// override this to set the language-specific name
|
||||||
virtual const char* getGlobalUniformBlockName() { return ""; }
|
virtual const char* getGlobalUniformBlockName() const { return ""; }
|
||||||
|
virtual void setUniformBlockDefaults(TType&) const { }
|
||||||
virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
|
virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
|
||||||
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, TPrefixType prefix,
|
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||||
@@ -297,7 +317,7 @@ public:
|
|||||||
bool arrayError(const TSourceLoc&, const TType&);
|
bool arrayError(const TSourceLoc&, const TType&);
|
||||||
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
||||||
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
||||||
void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
|
void arraySizesCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
|
||||||
void arrayOfArrayVersionCheck(const TSourceLoc&);
|
void arrayOfArrayVersionCheck(const TSourceLoc&);
|
||||||
void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
|
void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
|
||||||
void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
|
void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
|
||||||
@@ -339,6 +359,7 @@ public:
|
|||||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
||||||
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||||
void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
|
void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
|
||||||
|
void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
|
||||||
void layoutTypeCheck(const TSourceLoc&, const TType&);
|
void layoutTypeCheck(const TSourceLoc&, const TType&);
|
||||||
void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
|
void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||||
@@ -372,8 +393,8 @@ protected:
|
|||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
void inheritGlobalDefaults(TQualifier& dst) const;
|
void inheritGlobalDefaults(TQualifier& dst) const;
|
||||||
TVariable* makeInternalVariable(const char* name, const TType&) const;
|
TVariable* makeInternalVariable(const char* name, const TType&) const;
|
||||||
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&);
|
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
|
||||||
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&);
|
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
|
||||||
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
void finish() override;
|
void finish() override;
|
||||||
@@ -384,17 +405,7 @@ public:
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Current state of parsing
|
// Current state of parsing
|
||||||
struct TPragma contextPragma;
|
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
|
||||||
int structNestingLevel; // 0 if outside blocks and structures
|
|
||||||
int controlFlowNestingLevel; // 0 if outside all flow control
|
|
||||||
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
|
||||||
TList<TIntermSequence*> switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
|
||||||
TList<int> switchLevel; // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
|
||||||
bool inMain; // if inside a function, true if the function is main
|
bool inMain; // if inside a function, true if the function is main
|
||||||
bool postMainReturn; // if inside a function, true if the function is main and this is after a return statement
|
|
||||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
|
||||||
bool functionReturnsValue; // true if a non-void function has a return
|
|
||||||
const TString* blockName;
|
const TString* blockName;
|
||||||
TQualifier currentBlockQualifier;
|
TQualifier currentBlockQualifier;
|
||||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void RemoveAllTreeNodes(TIntermNode*);
|
void RemoveAllTreeNodes(TIntermNode*);
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
|
|||||||
|
|
||||||
bool versionNotFirst = false; // means not first WRT comments and white space, nothing more
|
bool versionNotFirst = false; // means not first WRT comments and white space, nothing more
|
||||||
notFirstToken = false; // means not first WRT to real tokens
|
notFirstToken = false; // means not first WRT to real tokens
|
||||||
version = 0; // means not found
|
version = 0; // means not found
|
||||||
profile = ENoProfile;
|
profile = ENoProfile;
|
||||||
|
|
||||||
bool foundNonSpaceTab = false;
|
bool foundNonSpaceTab = false;
|
||||||
@@ -464,6 +464,15 @@ void TScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["u64vec4"] = U64VEC4;
|
(*KeywordMap)["u64vec4"] = U64VEC4;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
(*KeywordMap)["int16_t"] = INT16_T;
|
||||||
|
(*KeywordMap)["uint16_t"] = UINT16_T;
|
||||||
|
(*KeywordMap)["i16vec2"] = I16VEC2;
|
||||||
|
(*KeywordMap)["i16vec3"] = I16VEC3;
|
||||||
|
(*KeywordMap)["i16vec4"] = I16VEC4;
|
||||||
|
(*KeywordMap)["u16vec2"] = U16VEC2;
|
||||||
|
(*KeywordMap)["u16vec3"] = U16VEC3;
|
||||||
|
(*KeywordMap)["u16vec4"] = U16VEC4;
|
||||||
|
|
||||||
(*KeywordMap)["float16_t"] = FLOAT16_T;
|
(*KeywordMap)["float16_t"] = FLOAT16_T;
|
||||||
(*KeywordMap)["f16vec2"] = F16VEC2;
|
(*KeywordMap)["f16vec2"] = F16VEC2;
|
||||||
(*KeywordMap)["f16vec3"] = F16VEC3;
|
(*KeywordMap)["f16vec3"] = F16VEC3;
|
||||||
@@ -701,10 +710,18 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
|||||||
case PpAtomDecrement: return DEC_OP;
|
case PpAtomDecrement: return DEC_OP;
|
||||||
case PpAtomIncrement: return INC_OP;
|
case PpAtomIncrement: return INC_OP;
|
||||||
|
|
||||||
|
case PpAtomColonColon:
|
||||||
|
parseContext.error(loc, "not supported", "::", "");
|
||||||
|
break;
|
||||||
|
|
||||||
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
||||||
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
||||||
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
|
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
|
||||||
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
|
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT;
|
||||||
|
case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT;
|
||||||
|
#endif
|
||||||
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
||||||
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
|
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
@@ -969,6 +986,21 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case INT16_T:
|
||||||
|
case UINT16_T:
|
||||||
|
case I16VEC2:
|
||||||
|
case I16VEC3:
|
||||||
|
case I16VEC4:
|
||||||
|
case U16VEC2:
|
||||||
|
case U16VEC3:
|
||||||
|
case U16VEC4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
case FLOAT16_T:
|
case FLOAT16_T:
|
||||||
case F16VEC2:
|
case F16VEC2:
|
||||||
case F16VEC3:
|
case F16VEC3:
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
// sits between the preprocessor scanner and parser.
|
// sits between the preprocessor scanner and parser.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
bool correct = true;
|
bool correct = true;
|
||||||
|
|
||||||
if (source == EShSourceHlsl) {
|
if (source == EShSourceHlsl) {
|
||||||
version = 450; // TODO: GLSL parser is still used for builtins.
|
version = 500; // shader model; currently a characteristic of glslang, not the input
|
||||||
profile = ECoreProfile; // allow doubles in prototype parsing
|
profile = ECoreProfile; // allow doubles in prototype parsing
|
||||||
return correct;
|
return correct;
|
||||||
}
|
}
|
||||||
@@ -566,41 +566,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A meta check on the condition of the compiler itself...
|
|
||||||
switch (version) {
|
|
||||||
|
|
||||||
// ES versions
|
|
||||||
case 100:
|
|
||||||
case 300:
|
|
||||||
// versions are complete
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Desktop versions
|
|
||||||
case 110:
|
|
||||||
case 120:
|
|
||||||
case 130:
|
|
||||||
case 140:
|
|
||||||
case 150:
|
|
||||||
case 330:
|
|
||||||
// versions are complete
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 310:
|
|
||||||
case 400:
|
|
||||||
case 410:
|
|
||||||
case 420:
|
|
||||||
case 430:
|
|
||||||
case 440:
|
|
||||||
case 450:
|
|
||||||
infoSink.info << "Warning, version " << version << " is not yet complete; most version-specific features are present, but some are missing.\n";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
infoSink.info << "Warning, version " << version << " is unknown.\n";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return correct;
|
return correct;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,13 +644,13 @@ bool ProcessDeferred(
|
|||||||
// First, without using the preprocessor or parser, find the #version, so we know what
|
// First, without using the preprocessor or parser, find the #version, so we know what
|
||||||
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
||||||
// outlined above, just the user shader.
|
// outlined above, just the user shader.
|
||||||
int version;
|
|
||||||
EProfile profile;
|
|
||||||
glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]); // no preamble
|
glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]); // no preamble
|
||||||
bool versionNotFirstToken;
|
int version = 0;
|
||||||
bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken);
|
EProfile profile = ENoProfile;
|
||||||
|
bool versionNotFirstToken = false;
|
||||||
|
bool versionNotFirst = (messages & EShMsgReadHlsl) ? true : userInput.scanVersion(version, profile, versionNotFirstToken);
|
||||||
bool versionNotFound = version == 0;
|
bool versionNotFound = version == 0;
|
||||||
if (forceDefaultVersionAndProfile) {
|
if (forceDefaultVersionAndProfile && (messages & EShMsgReadHlsl) == 0) {
|
||||||
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
||||||
(version != defaultVersion || profile != defaultProfile)) {
|
(version != defaultVersion || profile != defaultProfile)) {
|
||||||
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
||||||
@@ -726,6 +691,13 @@ bool ProcessDeferred(
|
|||||||
intermediate.setSpv(spvVersion);
|
intermediate.setSpv(spvVersion);
|
||||||
if (spvVersion.vulkan >= 100)
|
if (spvVersion.vulkan >= 100)
|
||||||
intermediate.setOriginUpperLeft();
|
intermediate.setOriginUpperLeft();
|
||||||
|
if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
|
||||||
|
intermediate.setHlslOffsets();
|
||||||
|
if (messages & EShMsgDebugInfo) {
|
||||||
|
intermediate.setSourceFile(names[numPre]);
|
||||||
|
for (int s = 0; s < numStrings; ++s)
|
||||||
|
intermediate.addSourceText(strings[numPre]);
|
||||||
|
}
|
||||||
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
||||||
|
|
||||||
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
||||||
@@ -1553,13 +1525,30 @@ void TShader::setSourceEntryPoint(const char* name)
|
|||||||
sourceEntryPointName = name;
|
sourceEntryPointName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set binding base for sampler types
|
||||||
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
|
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
|
||||||
|
// Set binding base for texture types (SRV)
|
||||||
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
|
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
|
||||||
|
// Set binding base for image types
|
||||||
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
|
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
|
||||||
|
// Set binding base for uniform buffer objects (CBV)
|
||||||
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
||||||
|
// Synonym for setShiftUboBinding, to match HLSL language.
|
||||||
|
void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
||||||
|
// Set binding base for UAV (unordered access view)
|
||||||
|
void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShiftUavBinding(base); }
|
||||||
|
// Set binding base for SSBOs
|
||||||
|
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
|
||||||
|
// Enables binding automapping using TIoMapper
|
||||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||||
|
// Fragile: currently within one stage: simple auto-assignment of location
|
||||||
|
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
||||||
|
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
||||||
|
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
||||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||||
|
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
||||||
|
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
||||||
|
|
||||||
//
|
//
|
||||||
// Turn the shader strings into a parse tree in the TIntermediate.
|
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||||
@@ -1583,11 +1572,6 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
|||||||
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
|
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
|
|
||||||
{
|
|
||||||
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in a string with the result of preprocessing ShaderStrings
|
// Fill in a string with the result of preprocessing ShaderStrings
|
||||||
// Returns true if all extensions, pragmas and version strings were valid.
|
// Returns true if all extensions, pragmas and version strings were valid.
|
||||||
bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
||||||
@@ -1775,6 +1759,7 @@ const char* TProgram::getUniformBlockName(int index) const { return reflection
|
|||||||
int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; }
|
int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; }
|
||||||
int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); }
|
int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); }
|
||||||
int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; }
|
int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; }
|
||||||
|
int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; }
|
||||||
int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; }
|
int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; }
|
||||||
int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; }
|
int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; }
|
||||||
int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; }
|
int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; }
|
||||||
@@ -1784,6 +1769,7 @@ int TProgram::getAttributeType(int index) const { return reflection
|
|||||||
const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); }
|
const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); }
|
||||||
const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); }
|
const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); }
|
||||||
const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
|
const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
|
||||||
|
unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); }
|
||||||
|
|
||||||
void TProgram::dumpReflection() { reflection->dump(); }
|
void TProgram::dumpReflection() { reflection->dump(); }
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
// Recursively generate mangled names.
|
// Recursively generate mangled names.
|
||||||
//
|
//
|
||||||
void TType::buildMangledName(TString& mangledName)
|
void TType::buildMangledName(TString& mangledName) const
|
||||||
{
|
{
|
||||||
if (isMatrix())
|
if (isMatrix())
|
||||||
mangledName += 'm';
|
mangledName += 'm';
|
||||||
@@ -67,6 +67,10 @@ void TType::buildMangledName(TString& mangledName)
|
|||||||
case EbtUint: mangledName += 'u'; break;
|
case EbtUint: mangledName += 'u'; break;
|
||||||
case EbtInt64: mangledName += "i64"; break;
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16: mangledName += "i16"; break;
|
||||||
|
case EbtUint16: mangledName += "u16"; break;
|
||||||
|
#endif
|
||||||
case EbtBool: mangledName += 'b'; break;
|
case EbtBool: mangledName += 'b'; break;
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
@@ -99,11 +103,23 @@ void TType::buildMangledName(TString& mangledName)
|
|||||||
case EsdSubpass: mangledName += "P"; break;
|
case EsdSubpass: mangledName += "P"; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (sampler.vectorSize) {
|
||||||
|
case 1: mangledName += "1"; break;
|
||||||
|
case 2: mangledName += "2"; break;
|
||||||
|
case 3: mangledName += "3"; break;
|
||||||
|
case 4: break; // default to prior name mangle behavior
|
||||||
|
}
|
||||||
|
|
||||||
if (sampler.ms)
|
if (sampler.ms)
|
||||||
mangledName += "M";
|
mangledName += "M";
|
||||||
break;
|
break;
|
||||||
case EbtStruct:
|
case EbtStruct:
|
||||||
mangledName += "struct-";
|
case EbtBlock:
|
||||||
|
if (basicType == EbtStruct)
|
||||||
|
mangledName += "struct-";
|
||||||
|
else
|
||||||
|
mangledName += "block-";
|
||||||
if (typeName)
|
if (typeName)
|
||||||
mangledName += *typeName;
|
mangledName += *typeName;
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||||
@@ -295,6 +311,8 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
|||||||
op = copyOf.op;
|
op = copyOf.op;
|
||||||
defined = copyOf.defined;
|
defined = copyOf.defined;
|
||||||
prototyped = copyOf.prototyped;
|
prototyped = copyOf.prototyped;
|
||||||
|
implicitThis = copyOf.implicitThis;
|
||||||
|
illegalImplicitThis = copyOf.illegalImplicitThis;
|
||||||
defaultParamCount = copyOf.defaultParamCount;
|
defaultParamCount = copyOf.defaultParamCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +337,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||||||
{
|
{
|
||||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||||
symTableLevel->anonId = anonId;
|
symTableLevel->anonId = anonId;
|
||||||
|
symTableLevel->thisLevel = thisLevel;
|
||||||
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) {
|
||||||
|
|||||||
@@ -198,7 +198,6 @@ struct TParameter {
|
|||||||
TString *name;
|
TString *name;
|
||||||
TType* type;
|
TType* type;
|
||||||
TIntermTyped* defaultValue;
|
TIntermTyped* defaultValue;
|
||||||
TBuiltInVariable declaredBuiltIn;
|
|
||||||
void copyParam(const TParameter& param)
|
void copyParam(const TParameter& param)
|
||||||
{
|
{
|
||||||
if (param.name)
|
if (param.name)
|
||||||
@@ -207,8 +206,8 @@ struct TParameter {
|
|||||||
name = 0;
|
name = 0;
|
||||||
type = param.type->clone();
|
type = param.type->clone();
|
||||||
defaultValue = param.defaultValue;
|
defaultValue = param.defaultValue;
|
||||||
declaredBuiltIn = param.declaredBuiltIn;
|
|
||||||
}
|
}
|
||||||
|
TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -219,48 +218,70 @@ public:
|
|||||||
explicit TFunction(TOperator o) :
|
explicit TFunction(TOperator o) :
|
||||||
TSymbol(0),
|
TSymbol(0),
|
||||||
op(o),
|
op(o),
|
||||||
defined(false), prototyped(false), defaultParamCount(0) { }
|
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
|
||||||
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
||||||
TSymbol(name),
|
TSymbol(name),
|
||||||
mangledName(*name + '('),
|
mangledName(*name + '('),
|
||||||
op(tOp),
|
op(tOp),
|
||||||
defined(false), prototyped(false), defaultParamCount(0)
|
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
|
||||||
{
|
{
|
||||||
returnType.shallowCopy(retType);
|
returnType.shallowCopy(retType);
|
||||||
declaredBuiltIn = retType.getQualifier().builtIn;
|
declaredBuiltIn = retType.getQualifier().builtIn;
|
||||||
}
|
}
|
||||||
virtual TFunction* clone() const;
|
virtual TFunction* clone() const override;
|
||||||
virtual ~TFunction();
|
virtual ~TFunction();
|
||||||
|
|
||||||
virtual TFunction* getAsFunction() { return this; }
|
virtual TFunction* getAsFunction() override { return this; }
|
||||||
virtual const TFunction* getAsFunction() const { return this; }
|
virtual const TFunction* getAsFunction() const override { return this; }
|
||||||
|
|
||||||
|
// Install 'p' as the (non-'this') last parameter.
|
||||||
|
// Non-'this' parameters are reflected in both the list of parameters and the
|
||||||
|
// mangled name.
|
||||||
virtual void addParameter(TParameter& p)
|
virtual void addParameter(TParameter& p)
|
||||||
{
|
{
|
||||||
assert(writable);
|
assert(writable);
|
||||||
p.declaredBuiltIn = p.type->getQualifier().builtIn;
|
|
||||||
parameters.push_back(p);
|
parameters.push_back(p);
|
||||||
p.type->appendMangledName(mangledName);
|
p.type->appendMangledName(mangledName);
|
||||||
|
|
||||||
if (p.defaultValue != nullptr)
|
if (p.defaultValue != nullptr)
|
||||||
defaultParamCount++;
|
defaultParamCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Install 'this' as the first parameter.
|
||||||
|
// 'this' is reflected in the list of parameters, but not the mangled name.
|
||||||
|
virtual void addThisParameter(TType& type, const char* name)
|
||||||
|
{
|
||||||
|
TParameter p = { NewPoolTString(name), new TType, nullptr };
|
||||||
|
p.type->shallowCopy(type);
|
||||||
|
parameters.insert(parameters.begin(), p);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void addPrefix(const char* prefix) override
|
virtual void addPrefix(const char* prefix) override
|
||||||
{
|
{
|
||||||
TSymbol::addPrefix(prefix);
|
TSymbol::addPrefix(prefix);
|
||||||
mangledName.insert(0, prefix);
|
mangledName.insert(0, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const TString& getMangledName() const { return mangledName; }
|
virtual void removePrefix(const TString& prefix)
|
||||||
virtual const TType& getType() const { return returnType; }
|
{
|
||||||
|
assert(mangledName.compare(0, prefix.size(), prefix) == 0);
|
||||||
|
mangledName.erase(0, prefix.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const TString& getMangledName() const override { return mangledName; }
|
||||||
|
virtual const TType& getType() const override { return returnType; }
|
||||||
virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
|
virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
|
||||||
virtual TType& getWritableType() { return returnType; }
|
virtual TType& getWritableType() override { return returnType; }
|
||||||
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
|
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
|
||||||
virtual TOperator getBuiltInOp() const { return op; }
|
virtual TOperator getBuiltInOp() const { return op; }
|
||||||
virtual void setDefined() { assert(writable); defined = true; }
|
virtual void setDefined() { assert(writable); defined = true; }
|
||||||
virtual bool isDefined() const { return defined; }
|
virtual bool isDefined() const { return defined; }
|
||||||
virtual void setPrototyped() { assert(writable); prototyped = true; }
|
virtual void setPrototyped() { assert(writable); prototyped = true; }
|
||||||
virtual bool isPrototyped() const { return prototyped; }
|
virtual bool isPrototyped() const { return prototyped; }
|
||||||
|
virtual void setImplicitThis() { assert(writable); implicitThis = true; }
|
||||||
|
virtual bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
|
||||||
|
virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
|
||||||
|
|
||||||
// Return total number of parameters
|
// Return total number of parameters
|
||||||
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
|
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||||
@@ -272,7 +293,7 @@ public:
|
|||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||||
|
|
||||||
virtual void dump(TInfoSink &infoSink) const;
|
virtual void dump(TInfoSink &infoSink) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TFunction(const TFunction&);
|
explicit TFunction(const TFunction&);
|
||||||
@@ -287,6 +308,11 @@ protected:
|
|||||||
TOperator op;
|
TOperator op;
|
||||||
bool defined;
|
bool defined;
|
||||||
bool prototyped;
|
bool prototyped;
|
||||||
|
bool implicitThis; // True if this function is allowed to see all members of 'this'
|
||||||
|
bool illegalImplicitThis; // True if this function is not supposed to have access to dynamic members of 'this',
|
||||||
|
// even if it finds member variables in the symbol table.
|
||||||
|
// This is important for a static member function that has member variables in scope,
|
||||||
|
// but is not allowed to use them, or see hidden symbols instead.
|
||||||
int defaultParamCount;
|
int defaultParamCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -334,7 +360,7 @@ protected:
|
|||||||
class TSymbolTableLevel {
|
class TSymbolTableLevel {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
TSymbolTableLevel() : defaultPrecision(0), anonId(0) { }
|
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
|
||||||
~TSymbolTableLevel();
|
~TSymbolTableLevel();
|
||||||
|
|
||||||
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
||||||
@@ -492,6 +518,9 @@ public:
|
|||||||
TSymbolTableLevel* clone() const;
|
TSymbolTableLevel* clone() const;
|
||||||
void readOnly();
|
void readOnly();
|
||||||
|
|
||||||
|
void setThisLevel() { thisLevel = true; }
|
||||||
|
bool isThisLevel() const { return thisLevel; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TSymbolTableLevel(TSymbolTableLevel&);
|
explicit TSymbolTableLevel(TSymbolTableLevel&);
|
||||||
TSymbolTableLevel& operator=(TSymbolTableLevel&);
|
TSymbolTableLevel& operator=(TSymbolTableLevel&);
|
||||||
@@ -503,6 +532,8 @@ protected:
|
|||||||
tLevel level; // named mappings
|
tLevel level; // named mappings
|
||||||
TPrecisionQualifier *defaultPrecision;
|
TPrecisionQualifier *defaultPrecision;
|
||||||
int anonId;
|
int anonId;
|
||||||
|
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
|
||||||
|
// that are supposed to see anonymous access to member variables.
|
||||||
};
|
};
|
||||||
|
|
||||||
class TSymbolTable {
|
class TSymbolTable {
|
||||||
@@ -559,6 +590,20 @@ public:
|
|||||||
table.push_back(new TSymbolTableLevel);
|
table.push_back(new TSymbolTableLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make a new symbol-table level to represent the scope introduced by a structure
|
||||||
|
// containing member functions, such that the member functions can find anonymous
|
||||||
|
// references to member variables.
|
||||||
|
//
|
||||||
|
// 'thisSymbol' should have a name of "" to trigger anonymous structure-member
|
||||||
|
// symbol finds.
|
||||||
|
void pushThis(TSymbol& thisSymbol)
|
||||||
|
{
|
||||||
|
assert(thisSymbol.getName().size() == 0);
|
||||||
|
table.push_back(new TSymbolTableLevel);
|
||||||
|
table.back()->setThisLevel();
|
||||||
|
insert(thisSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
void pop(TPrecisionQualifier *p)
|
void pop(TPrecisionQualifier *p)
|
||||||
{
|
{
|
||||||
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
||||||
@@ -645,19 +690,50 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0)
|
// Normal find of a symbol, that can optionally say whether the symbol was found
|
||||||
|
// at a built-in level or the current top-scope level.
|
||||||
|
TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
|
||||||
{
|
{
|
||||||
int level = currentLevel();
|
int level = currentLevel();
|
||||||
TSymbol* symbol;
|
TSymbol* symbol;
|
||||||
|
int thisDepth = 0;
|
||||||
do {
|
do {
|
||||||
|
if (table[level]->isThisLevel())
|
||||||
|
++thisDepth;
|
||||||
symbol = table[level]->find(name);
|
symbol = table[level]->find(name);
|
||||||
--level;
|
--level;
|
||||||
} while (symbol == 0 && level >= 0);
|
} while (symbol == nullptr && level >= 0);
|
||||||
level++;
|
level++;
|
||||||
if (builtIn)
|
if (builtIn)
|
||||||
*builtIn = isBuiltInLevel(level);
|
*builtIn = isBuiltInLevel(level);
|
||||||
if (currentScope)
|
if (currentScope)
|
||||||
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
|
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
|
||||||
|
if (thisDepthP != nullptr) {
|
||||||
|
if (! table[level]->isThisLevel())
|
||||||
|
thisDepth = 0;
|
||||||
|
*thisDepthP = thisDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find of a symbol that returns how many layers deep of nested
|
||||||
|
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||||
|
// found in.
|
||||||
|
TSymbol* find(const TString& name, int& thisDepth)
|
||||||
|
{
|
||||||
|
int level = currentLevel();
|
||||||
|
TSymbol* symbol;
|
||||||
|
thisDepth = 0;
|
||||||
|
do {
|
||||||
|
if (table[level]->isThisLevel())
|
||||||
|
++thisDepth;
|
||||||
|
symbol = table[level]->find(name);
|
||||||
|
--level;
|
||||||
|
} while (symbol == 0 && level >= 0);
|
||||||
|
|
||||||
|
if (! table[level + 1]->isThisLevel())
|
||||||
|
thisDepth = 0;
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,6 +195,8 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_gcn_shader] = EBhDisable;
|
extensionBehavior[E_GL_AMD_gcn_shader] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
|
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_texture_gather_bias_lod] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_gpu_shader_int16] = EBhDisable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
@@ -233,6 +235,10 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
||||||
|
|
||||||
|
// EXT extensions
|
||||||
|
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
@@ -315,6 +321,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_AMD_shader_explicit_vertex_parameter 1\n"
|
"#define GL_AMD_shader_explicit_vertex_parameter 1\n"
|
||||||
"#define GL_AMD_gcn_shader 1\n"
|
"#define GL_AMD_gcn_shader 1\n"
|
||||||
"#define GL_AMD_gpu_shader_half_float 1\n"
|
"#define GL_AMD_gpu_shader_half_float 1\n"
|
||||||
|
"#define GL_AMD_texture_gather_bias_lod 1\n"
|
||||||
|
"#define GL_AMD_gpu_shader_int16 1\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
@@ -323,6 +331,22 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_NV_viewport_array2 1\n"
|
"#define GL_NV_viewport_array2 1\n"
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if (version >= 150) {
|
||||||
|
// define GL_core_profile and GL_compatibility_profile
|
||||||
|
preamble += "#define GL_core_profile 1\n";
|
||||||
|
|
||||||
|
if (profile == ECompatibilityProfile)
|
||||||
|
preamble += "#define GL_compatibility_profile 1\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
preamble +=
|
||||||
|
"#define GL_EXT_device_group 1\n"
|
||||||
|
"#define GL_EXT_multiview 1\n"
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
@@ -481,6 +505,11 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
|
||||||
|
{
|
||||||
|
error(loc, "feature not yet implemented", featureDesc, "");
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
||||||
// Warns appropriately if the requested behavior of an extension is "warn".
|
// Warns appropriately if the requested behavior of an extension is "warn".
|
||||||
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
@@ -686,10 +715,21 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
// Call for any operation needing GLSL 16-bit integer data-type support.
|
||||||
|
void TParseVersions::int16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (! builtIn) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_int16, "shader int16");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call for any operation needing GLSL float16 data-type support.
|
// Call for any operation needing GLSL float16 data-type support.
|
||||||
void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (!builtIn) {
|
if (! builtIn) {
|
||||||
requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float");
|
requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float");
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
|||||||
@@ -133,6 +133,10 @@ const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture
|
|||||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
||||||
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
||||||
|
|
||||||
|
// EXT extensions
|
||||||
|
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
|
||||||
|
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||||
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
||||||
@@ -143,7 +147,10 @@ const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader
|
|||||||
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
||||||
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
|
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
|
||||||
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
|
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
|
||||||
|
const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod";
|
||||||
|
const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
|
||||||
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#define GL_FLOAT 0x1406
|
#define GL_FLOAT 0x1406
|
||||||
#define GL_FLOAT_VEC2 0x8B50
|
#define GL_FLOAT_VEC2 0x8B50
|
||||||
#define GL_FLOAT_VEC3 0x8B51
|
#define GL_FLOAT_VEC3 0x8B51
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,19 @@
|
|||||||
/* A Bison parser, made by GNU Bison 2.7. */
|
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
@@ -26,13 +26,13 @@
|
|||||||
special exception, which will cause the skeleton and the resulting
|
special exception, which will cause the skeleton and the resulting
|
||||||
Bison output files to be licensed under the GNU General Public
|
Bison output files to be licensed under the GNU General Public
|
||||||
License without this special exception.
|
License without this special exception.
|
||||||
|
|
||||||
This special exception was added by the Free Software Foundation in
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
version 2.2 of Bison. */
|
||||||
|
|
||||||
#ifndef YY_YY_GLSLANG_TAB_CPP_H_INCLUDED
|
#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
|
||||||
# define YY_YY_GLSLANG_TAB_CPP_H_INCLUDED
|
# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
|
||||||
/* Enabling traces. */
|
/* Debug traces. */
|
||||||
#ifndef YYDEBUG
|
#ifndef YYDEBUG
|
||||||
# define YYDEBUG 1
|
# define YYDEBUG 1
|
||||||
#endif
|
#endif
|
||||||
@@ -40,306 +40,315 @@
|
|||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Tokens. */
|
/* Token type. */
|
||||||
#ifndef YYTOKENTYPE
|
#ifndef YYTOKENTYPE
|
||||||
# define YYTOKENTYPE
|
# define YYTOKENTYPE
|
||||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
enum yytokentype
|
||||||
know about them. */
|
{
|
||||||
enum yytokentype {
|
ATTRIBUTE = 258,
|
||||||
ATTRIBUTE = 258,
|
VARYING = 259,
|
||||||
VARYING = 259,
|
CONST = 260,
|
||||||
CONST = 260,
|
BOOL = 261,
|
||||||
BOOL = 261,
|
FLOAT = 262,
|
||||||
FLOAT = 262,
|
DOUBLE = 263,
|
||||||
DOUBLE = 263,
|
INT = 264,
|
||||||
INT = 264,
|
UINT = 265,
|
||||||
UINT = 265,
|
INT64_T = 266,
|
||||||
INT64_T = 266,
|
UINT64_T = 267,
|
||||||
UINT64_T = 267,
|
INT16_T = 268,
|
||||||
FLOAT16_T = 268,
|
UINT16_T = 269,
|
||||||
BREAK = 269,
|
FLOAT16_T = 270,
|
||||||
CONTINUE = 270,
|
BREAK = 271,
|
||||||
DO = 271,
|
CONTINUE = 272,
|
||||||
ELSE = 272,
|
DO = 273,
|
||||||
FOR = 273,
|
ELSE = 274,
|
||||||
IF = 274,
|
FOR = 275,
|
||||||
DISCARD = 275,
|
IF = 276,
|
||||||
RETURN = 276,
|
DISCARD = 277,
|
||||||
SWITCH = 277,
|
RETURN = 278,
|
||||||
CASE = 278,
|
SWITCH = 279,
|
||||||
DEFAULT = 279,
|
CASE = 280,
|
||||||
SUBROUTINE = 280,
|
DEFAULT = 281,
|
||||||
BVEC2 = 281,
|
SUBROUTINE = 282,
|
||||||
BVEC3 = 282,
|
BVEC2 = 283,
|
||||||
BVEC4 = 283,
|
BVEC3 = 284,
|
||||||
IVEC2 = 284,
|
BVEC4 = 285,
|
||||||
IVEC3 = 285,
|
IVEC2 = 286,
|
||||||
IVEC4 = 286,
|
IVEC3 = 287,
|
||||||
I64VEC2 = 287,
|
IVEC4 = 288,
|
||||||
I64VEC3 = 288,
|
I64VEC2 = 289,
|
||||||
I64VEC4 = 289,
|
I64VEC3 = 290,
|
||||||
UVEC2 = 290,
|
I64VEC4 = 291,
|
||||||
UVEC3 = 291,
|
UVEC2 = 292,
|
||||||
UVEC4 = 292,
|
UVEC3 = 293,
|
||||||
U64VEC2 = 293,
|
UVEC4 = 294,
|
||||||
U64VEC3 = 294,
|
U64VEC2 = 295,
|
||||||
U64VEC4 = 295,
|
U64VEC3 = 296,
|
||||||
VEC2 = 296,
|
U64VEC4 = 297,
|
||||||
VEC3 = 297,
|
VEC2 = 298,
|
||||||
VEC4 = 298,
|
VEC3 = 299,
|
||||||
MAT2 = 299,
|
VEC4 = 300,
|
||||||
MAT3 = 300,
|
MAT2 = 301,
|
||||||
MAT4 = 301,
|
MAT3 = 302,
|
||||||
CENTROID = 302,
|
MAT4 = 303,
|
||||||
IN = 303,
|
CENTROID = 304,
|
||||||
OUT = 304,
|
IN = 305,
|
||||||
INOUT = 305,
|
OUT = 306,
|
||||||
UNIFORM = 306,
|
INOUT = 307,
|
||||||
PATCH = 307,
|
UNIFORM = 308,
|
||||||
SAMPLE = 308,
|
PATCH = 309,
|
||||||
BUFFER = 309,
|
SAMPLE = 310,
|
||||||
SHARED = 310,
|
BUFFER = 311,
|
||||||
COHERENT = 311,
|
SHARED = 312,
|
||||||
VOLATILE = 312,
|
COHERENT = 313,
|
||||||
RESTRICT = 313,
|
VOLATILE = 314,
|
||||||
READONLY = 314,
|
RESTRICT = 315,
|
||||||
WRITEONLY = 315,
|
READONLY = 316,
|
||||||
DVEC2 = 316,
|
WRITEONLY = 317,
|
||||||
DVEC3 = 317,
|
DVEC2 = 318,
|
||||||
DVEC4 = 318,
|
DVEC3 = 319,
|
||||||
DMAT2 = 319,
|
DVEC4 = 320,
|
||||||
DMAT3 = 320,
|
DMAT2 = 321,
|
||||||
DMAT4 = 321,
|
DMAT3 = 322,
|
||||||
F16VEC2 = 322,
|
DMAT4 = 323,
|
||||||
F16VEC3 = 323,
|
F16VEC2 = 324,
|
||||||
F16VEC4 = 324,
|
F16VEC3 = 325,
|
||||||
F16MAT2 = 325,
|
F16VEC4 = 326,
|
||||||
F16MAT3 = 326,
|
F16MAT2 = 327,
|
||||||
F16MAT4 = 327,
|
F16MAT3 = 328,
|
||||||
NOPERSPECTIVE = 328,
|
F16MAT4 = 329,
|
||||||
FLAT = 329,
|
I16VEC2 = 330,
|
||||||
SMOOTH = 330,
|
I16VEC3 = 331,
|
||||||
LAYOUT = 331,
|
I16VEC4 = 332,
|
||||||
__EXPLICITINTERPAMD = 332,
|
U16VEC2 = 333,
|
||||||
MAT2X2 = 333,
|
U16VEC3 = 334,
|
||||||
MAT2X3 = 334,
|
U16VEC4 = 335,
|
||||||
MAT2X4 = 335,
|
NOPERSPECTIVE = 336,
|
||||||
MAT3X2 = 336,
|
FLAT = 337,
|
||||||
MAT3X3 = 337,
|
SMOOTH = 338,
|
||||||
MAT3X4 = 338,
|
LAYOUT = 339,
|
||||||
MAT4X2 = 339,
|
__EXPLICITINTERPAMD = 340,
|
||||||
MAT4X3 = 340,
|
MAT2X2 = 341,
|
||||||
MAT4X4 = 341,
|
MAT2X3 = 342,
|
||||||
DMAT2X2 = 342,
|
MAT2X4 = 343,
|
||||||
DMAT2X3 = 343,
|
MAT3X2 = 344,
|
||||||
DMAT2X4 = 344,
|
MAT3X3 = 345,
|
||||||
DMAT3X2 = 345,
|
MAT3X4 = 346,
|
||||||
DMAT3X3 = 346,
|
MAT4X2 = 347,
|
||||||
DMAT3X4 = 347,
|
MAT4X3 = 348,
|
||||||
DMAT4X2 = 348,
|
MAT4X4 = 349,
|
||||||
DMAT4X3 = 349,
|
DMAT2X2 = 350,
|
||||||
DMAT4X4 = 350,
|
DMAT2X3 = 351,
|
||||||
F16MAT2X2 = 351,
|
DMAT2X4 = 352,
|
||||||
F16MAT2X3 = 352,
|
DMAT3X2 = 353,
|
||||||
F16MAT2X4 = 353,
|
DMAT3X3 = 354,
|
||||||
F16MAT3X2 = 354,
|
DMAT3X4 = 355,
|
||||||
F16MAT3X3 = 355,
|
DMAT4X2 = 356,
|
||||||
F16MAT3X4 = 356,
|
DMAT4X3 = 357,
|
||||||
F16MAT4X2 = 357,
|
DMAT4X4 = 358,
|
||||||
F16MAT4X3 = 358,
|
F16MAT2X2 = 359,
|
||||||
F16MAT4X4 = 359,
|
F16MAT2X3 = 360,
|
||||||
ATOMIC_UINT = 360,
|
F16MAT2X4 = 361,
|
||||||
SAMPLER1D = 361,
|
F16MAT3X2 = 362,
|
||||||
SAMPLER2D = 362,
|
F16MAT3X3 = 363,
|
||||||
SAMPLER3D = 363,
|
F16MAT3X4 = 364,
|
||||||
SAMPLERCUBE = 364,
|
F16MAT4X2 = 365,
|
||||||
SAMPLER1DSHADOW = 365,
|
F16MAT4X3 = 366,
|
||||||
SAMPLER2DSHADOW = 366,
|
F16MAT4X4 = 367,
|
||||||
SAMPLERCUBESHADOW = 367,
|
ATOMIC_UINT = 368,
|
||||||
SAMPLER1DARRAY = 368,
|
SAMPLER1D = 369,
|
||||||
SAMPLER2DARRAY = 369,
|
SAMPLER2D = 370,
|
||||||
SAMPLER1DARRAYSHADOW = 370,
|
SAMPLER3D = 371,
|
||||||
SAMPLER2DARRAYSHADOW = 371,
|
SAMPLERCUBE = 372,
|
||||||
ISAMPLER1D = 372,
|
SAMPLER1DSHADOW = 373,
|
||||||
ISAMPLER2D = 373,
|
SAMPLER2DSHADOW = 374,
|
||||||
ISAMPLER3D = 374,
|
SAMPLERCUBESHADOW = 375,
|
||||||
ISAMPLERCUBE = 375,
|
SAMPLER1DARRAY = 376,
|
||||||
ISAMPLER1DARRAY = 376,
|
SAMPLER2DARRAY = 377,
|
||||||
ISAMPLER2DARRAY = 377,
|
SAMPLER1DARRAYSHADOW = 378,
|
||||||
USAMPLER1D = 378,
|
SAMPLER2DARRAYSHADOW = 379,
|
||||||
USAMPLER2D = 379,
|
ISAMPLER1D = 380,
|
||||||
USAMPLER3D = 380,
|
ISAMPLER2D = 381,
|
||||||
USAMPLERCUBE = 381,
|
ISAMPLER3D = 382,
|
||||||
USAMPLER1DARRAY = 382,
|
ISAMPLERCUBE = 383,
|
||||||
USAMPLER2DARRAY = 383,
|
ISAMPLER1DARRAY = 384,
|
||||||
SAMPLER2DRECT = 384,
|
ISAMPLER2DARRAY = 385,
|
||||||
SAMPLER2DRECTSHADOW = 385,
|
USAMPLER1D = 386,
|
||||||
ISAMPLER2DRECT = 386,
|
USAMPLER2D = 387,
|
||||||
USAMPLER2DRECT = 387,
|
USAMPLER3D = 388,
|
||||||
SAMPLERBUFFER = 388,
|
USAMPLERCUBE = 389,
|
||||||
ISAMPLERBUFFER = 389,
|
USAMPLER1DARRAY = 390,
|
||||||
USAMPLERBUFFER = 390,
|
USAMPLER2DARRAY = 391,
|
||||||
SAMPLERCUBEARRAY = 391,
|
SAMPLER2DRECT = 392,
|
||||||
SAMPLERCUBEARRAYSHADOW = 392,
|
SAMPLER2DRECTSHADOW = 393,
|
||||||
ISAMPLERCUBEARRAY = 393,
|
ISAMPLER2DRECT = 394,
|
||||||
USAMPLERCUBEARRAY = 394,
|
USAMPLER2DRECT = 395,
|
||||||
SAMPLER2DMS = 395,
|
SAMPLERBUFFER = 396,
|
||||||
ISAMPLER2DMS = 396,
|
ISAMPLERBUFFER = 397,
|
||||||
USAMPLER2DMS = 397,
|
USAMPLERBUFFER = 398,
|
||||||
SAMPLER2DMSARRAY = 398,
|
SAMPLERCUBEARRAY = 399,
|
||||||
ISAMPLER2DMSARRAY = 399,
|
SAMPLERCUBEARRAYSHADOW = 400,
|
||||||
USAMPLER2DMSARRAY = 400,
|
ISAMPLERCUBEARRAY = 401,
|
||||||
SAMPLEREXTERNALOES = 401,
|
USAMPLERCUBEARRAY = 402,
|
||||||
SAMPLER = 402,
|
SAMPLER2DMS = 403,
|
||||||
SAMPLERSHADOW = 403,
|
ISAMPLER2DMS = 404,
|
||||||
TEXTURE1D = 404,
|
USAMPLER2DMS = 405,
|
||||||
TEXTURE2D = 405,
|
SAMPLER2DMSARRAY = 406,
|
||||||
TEXTURE3D = 406,
|
ISAMPLER2DMSARRAY = 407,
|
||||||
TEXTURECUBE = 407,
|
USAMPLER2DMSARRAY = 408,
|
||||||
TEXTURE1DARRAY = 408,
|
SAMPLEREXTERNALOES = 409,
|
||||||
TEXTURE2DARRAY = 409,
|
SAMPLER = 410,
|
||||||
ITEXTURE1D = 410,
|
SAMPLERSHADOW = 411,
|
||||||
ITEXTURE2D = 411,
|
TEXTURE1D = 412,
|
||||||
ITEXTURE3D = 412,
|
TEXTURE2D = 413,
|
||||||
ITEXTURECUBE = 413,
|
TEXTURE3D = 414,
|
||||||
ITEXTURE1DARRAY = 414,
|
TEXTURECUBE = 415,
|
||||||
ITEXTURE2DARRAY = 415,
|
TEXTURE1DARRAY = 416,
|
||||||
UTEXTURE1D = 416,
|
TEXTURE2DARRAY = 417,
|
||||||
UTEXTURE2D = 417,
|
ITEXTURE1D = 418,
|
||||||
UTEXTURE3D = 418,
|
ITEXTURE2D = 419,
|
||||||
UTEXTURECUBE = 419,
|
ITEXTURE3D = 420,
|
||||||
UTEXTURE1DARRAY = 420,
|
ITEXTURECUBE = 421,
|
||||||
UTEXTURE2DARRAY = 421,
|
ITEXTURE1DARRAY = 422,
|
||||||
TEXTURE2DRECT = 422,
|
ITEXTURE2DARRAY = 423,
|
||||||
ITEXTURE2DRECT = 423,
|
UTEXTURE1D = 424,
|
||||||
UTEXTURE2DRECT = 424,
|
UTEXTURE2D = 425,
|
||||||
TEXTUREBUFFER = 425,
|
UTEXTURE3D = 426,
|
||||||
ITEXTUREBUFFER = 426,
|
UTEXTURECUBE = 427,
|
||||||
UTEXTUREBUFFER = 427,
|
UTEXTURE1DARRAY = 428,
|
||||||
TEXTURECUBEARRAY = 428,
|
UTEXTURE2DARRAY = 429,
|
||||||
ITEXTURECUBEARRAY = 429,
|
TEXTURE2DRECT = 430,
|
||||||
UTEXTURECUBEARRAY = 430,
|
ITEXTURE2DRECT = 431,
|
||||||
TEXTURE2DMS = 431,
|
UTEXTURE2DRECT = 432,
|
||||||
ITEXTURE2DMS = 432,
|
TEXTUREBUFFER = 433,
|
||||||
UTEXTURE2DMS = 433,
|
ITEXTUREBUFFER = 434,
|
||||||
TEXTURE2DMSARRAY = 434,
|
UTEXTUREBUFFER = 435,
|
||||||
ITEXTURE2DMSARRAY = 435,
|
TEXTURECUBEARRAY = 436,
|
||||||
UTEXTURE2DMSARRAY = 436,
|
ITEXTURECUBEARRAY = 437,
|
||||||
SUBPASSINPUT = 437,
|
UTEXTURECUBEARRAY = 438,
|
||||||
SUBPASSINPUTMS = 438,
|
TEXTURE2DMS = 439,
|
||||||
ISUBPASSINPUT = 439,
|
ITEXTURE2DMS = 440,
|
||||||
ISUBPASSINPUTMS = 440,
|
UTEXTURE2DMS = 441,
|
||||||
USUBPASSINPUT = 441,
|
TEXTURE2DMSARRAY = 442,
|
||||||
USUBPASSINPUTMS = 442,
|
ITEXTURE2DMSARRAY = 443,
|
||||||
IMAGE1D = 443,
|
UTEXTURE2DMSARRAY = 444,
|
||||||
IIMAGE1D = 444,
|
SUBPASSINPUT = 445,
|
||||||
UIMAGE1D = 445,
|
SUBPASSINPUTMS = 446,
|
||||||
IMAGE2D = 446,
|
ISUBPASSINPUT = 447,
|
||||||
IIMAGE2D = 447,
|
ISUBPASSINPUTMS = 448,
|
||||||
UIMAGE2D = 448,
|
USUBPASSINPUT = 449,
|
||||||
IMAGE3D = 449,
|
USUBPASSINPUTMS = 450,
|
||||||
IIMAGE3D = 450,
|
IMAGE1D = 451,
|
||||||
UIMAGE3D = 451,
|
IIMAGE1D = 452,
|
||||||
IMAGE2DRECT = 452,
|
UIMAGE1D = 453,
|
||||||
IIMAGE2DRECT = 453,
|
IMAGE2D = 454,
|
||||||
UIMAGE2DRECT = 454,
|
IIMAGE2D = 455,
|
||||||
IMAGECUBE = 455,
|
UIMAGE2D = 456,
|
||||||
IIMAGECUBE = 456,
|
IMAGE3D = 457,
|
||||||
UIMAGECUBE = 457,
|
IIMAGE3D = 458,
|
||||||
IMAGEBUFFER = 458,
|
UIMAGE3D = 459,
|
||||||
IIMAGEBUFFER = 459,
|
IMAGE2DRECT = 460,
|
||||||
UIMAGEBUFFER = 460,
|
IIMAGE2DRECT = 461,
|
||||||
IMAGE1DARRAY = 461,
|
UIMAGE2DRECT = 462,
|
||||||
IIMAGE1DARRAY = 462,
|
IMAGECUBE = 463,
|
||||||
UIMAGE1DARRAY = 463,
|
IIMAGECUBE = 464,
|
||||||
IMAGE2DARRAY = 464,
|
UIMAGECUBE = 465,
|
||||||
IIMAGE2DARRAY = 465,
|
IMAGEBUFFER = 466,
|
||||||
UIMAGE2DARRAY = 466,
|
IIMAGEBUFFER = 467,
|
||||||
IMAGECUBEARRAY = 467,
|
UIMAGEBUFFER = 468,
|
||||||
IIMAGECUBEARRAY = 468,
|
IMAGE1DARRAY = 469,
|
||||||
UIMAGECUBEARRAY = 469,
|
IIMAGE1DARRAY = 470,
|
||||||
IMAGE2DMS = 470,
|
UIMAGE1DARRAY = 471,
|
||||||
IIMAGE2DMS = 471,
|
IMAGE2DARRAY = 472,
|
||||||
UIMAGE2DMS = 472,
|
IIMAGE2DARRAY = 473,
|
||||||
IMAGE2DMSARRAY = 473,
|
UIMAGE2DARRAY = 474,
|
||||||
IIMAGE2DMSARRAY = 474,
|
IMAGECUBEARRAY = 475,
|
||||||
UIMAGE2DMSARRAY = 475,
|
IIMAGECUBEARRAY = 476,
|
||||||
STRUCT = 476,
|
UIMAGECUBEARRAY = 477,
|
||||||
VOID = 477,
|
IMAGE2DMS = 478,
|
||||||
WHILE = 478,
|
IIMAGE2DMS = 479,
|
||||||
IDENTIFIER = 479,
|
UIMAGE2DMS = 480,
|
||||||
TYPE_NAME = 480,
|
IMAGE2DMSARRAY = 481,
|
||||||
FLOATCONSTANT = 481,
|
IIMAGE2DMSARRAY = 482,
|
||||||
DOUBLECONSTANT = 482,
|
UIMAGE2DMSARRAY = 483,
|
||||||
INTCONSTANT = 483,
|
STRUCT = 484,
|
||||||
UINTCONSTANT = 484,
|
VOID = 485,
|
||||||
INT64CONSTANT = 485,
|
WHILE = 486,
|
||||||
UINT64CONSTANT = 486,
|
IDENTIFIER = 487,
|
||||||
BOOLCONSTANT = 487,
|
TYPE_NAME = 488,
|
||||||
FLOAT16CONSTANT = 488,
|
FLOATCONSTANT = 489,
|
||||||
LEFT_OP = 489,
|
DOUBLECONSTANT = 490,
|
||||||
RIGHT_OP = 490,
|
INTCONSTANT = 491,
|
||||||
INC_OP = 491,
|
UINTCONSTANT = 492,
|
||||||
DEC_OP = 492,
|
INT64CONSTANT = 493,
|
||||||
LE_OP = 493,
|
UINT64CONSTANT = 494,
|
||||||
GE_OP = 494,
|
INT16CONSTANT = 495,
|
||||||
EQ_OP = 495,
|
UINT16CONSTANT = 496,
|
||||||
NE_OP = 496,
|
BOOLCONSTANT = 497,
|
||||||
AND_OP = 497,
|
FLOAT16CONSTANT = 498,
|
||||||
OR_OP = 498,
|
LEFT_OP = 499,
|
||||||
XOR_OP = 499,
|
RIGHT_OP = 500,
|
||||||
MUL_ASSIGN = 500,
|
INC_OP = 501,
|
||||||
DIV_ASSIGN = 501,
|
DEC_OP = 502,
|
||||||
ADD_ASSIGN = 502,
|
LE_OP = 503,
|
||||||
MOD_ASSIGN = 503,
|
GE_OP = 504,
|
||||||
LEFT_ASSIGN = 504,
|
EQ_OP = 505,
|
||||||
RIGHT_ASSIGN = 505,
|
NE_OP = 506,
|
||||||
AND_ASSIGN = 506,
|
AND_OP = 507,
|
||||||
XOR_ASSIGN = 507,
|
OR_OP = 508,
|
||||||
OR_ASSIGN = 508,
|
XOR_OP = 509,
|
||||||
SUB_ASSIGN = 509,
|
MUL_ASSIGN = 510,
|
||||||
LEFT_PAREN = 510,
|
DIV_ASSIGN = 511,
|
||||||
RIGHT_PAREN = 511,
|
ADD_ASSIGN = 512,
|
||||||
LEFT_BRACKET = 512,
|
MOD_ASSIGN = 513,
|
||||||
RIGHT_BRACKET = 513,
|
LEFT_ASSIGN = 514,
|
||||||
LEFT_BRACE = 514,
|
RIGHT_ASSIGN = 515,
|
||||||
RIGHT_BRACE = 515,
|
AND_ASSIGN = 516,
|
||||||
DOT = 516,
|
XOR_ASSIGN = 517,
|
||||||
COMMA = 517,
|
OR_ASSIGN = 518,
|
||||||
COLON = 518,
|
SUB_ASSIGN = 519,
|
||||||
EQUAL = 519,
|
LEFT_PAREN = 520,
|
||||||
SEMICOLON = 520,
|
RIGHT_PAREN = 521,
|
||||||
BANG = 521,
|
LEFT_BRACKET = 522,
|
||||||
DASH = 522,
|
RIGHT_BRACKET = 523,
|
||||||
TILDE = 523,
|
LEFT_BRACE = 524,
|
||||||
PLUS = 524,
|
RIGHT_BRACE = 525,
|
||||||
STAR = 525,
|
DOT = 526,
|
||||||
SLASH = 526,
|
COMMA = 527,
|
||||||
PERCENT = 527,
|
COLON = 528,
|
||||||
LEFT_ANGLE = 528,
|
EQUAL = 529,
|
||||||
RIGHT_ANGLE = 529,
|
SEMICOLON = 530,
|
||||||
VERTICAL_BAR = 530,
|
BANG = 531,
|
||||||
CARET = 531,
|
DASH = 532,
|
||||||
AMPERSAND = 532,
|
TILDE = 533,
|
||||||
QUESTION = 533,
|
PLUS = 534,
|
||||||
INVARIANT = 534,
|
STAR = 535,
|
||||||
PRECISE = 535,
|
SLASH = 536,
|
||||||
HIGH_PRECISION = 536,
|
PERCENT = 537,
|
||||||
MEDIUM_PRECISION = 537,
|
LEFT_ANGLE = 538,
|
||||||
LOW_PRECISION = 538,
|
RIGHT_ANGLE = 539,
|
||||||
PRECISION = 539,
|
VERTICAL_BAR = 540,
|
||||||
PACKED = 540,
|
CARET = 541,
|
||||||
RESOURCE = 541,
|
AMPERSAND = 542,
|
||||||
SUPERP = 542
|
QUESTION = 543,
|
||||||
};
|
INVARIANT = 544,
|
||||||
|
PRECISE = 545,
|
||||||
|
HIGH_PRECISION = 546,
|
||||||
|
MEDIUM_PRECISION = 547,
|
||||||
|
LOW_PRECISION = 548,
|
||||||
|
PRECISION = 549,
|
||||||
|
PACKED = 550,
|
||||||
|
RESOURCE = 551,
|
||||||
|
SUPERP = 552
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE
|
|
||||||
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
/* Line 2058 of yacc.c */
|
#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
#line 66 "glslang.y"
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
@@ -373,28 +382,16 @@ typedef union YYSTYPE
|
|||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
|
#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
|
};
|
||||||
|
|
||||||
/* Line 2058 of yacc.c */
|
typedef union YYSTYPE YYSTYPE;
|
||||||
#line 379 "glslang_tab.cpp.h"
|
|
||||||
} YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef YYPARSE_PARAM
|
|
||||||
#if defined __STDC__ || defined __cplusplus
|
|
||||||
int yyparse (void *YYPARSE_PARAM);
|
|
||||||
#else
|
|
||||||
int yyparse ();
|
|
||||||
#endif
|
|
||||||
#else /* ! YYPARSE_PARAM */
|
|
||||||
#if defined __STDC__ || defined __cplusplus
|
|
||||||
int yyparse (glslang::TParseContext* pParseContext);
|
|
||||||
#else
|
|
||||||
int yyparse ();
|
|
||||||
#endif
|
|
||||||
#endif /* ! YYPARSE_PARAM */
|
|
||||||
|
|
||||||
#endif /* !YY_YY_GLSLANG_TAB_CPP_H_INCLUDED */
|
int yyparse (glslang::TParseContext* pParseContext);
|
||||||
|
|
||||||
|
#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */
|
||||||
|
|||||||
@@ -45,11 +45,31 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool is_positive_infinity(double x) {
|
bool IsInfinity(double x) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return _fpclass(x) == _FPCLASS_PINF;
|
switch (_fpclass(x)) {
|
||||||
|
case _FPCLASS_NINF:
|
||||||
|
case _FPCLASS_PINF:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
return std::isinf(x) && (x >= 0);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +308,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
|
case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
|
||||||
case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break;
|
case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break;
|
||||||
case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
|
case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpFloat16BitsToInt16: out.debug << "float16BitsToInt16"; break;
|
||||||
|
case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
|
||||||
|
case EOpInt16BitsToFloat16: out.debug << "int16BitsToFloat16"; break;
|
||||||
|
case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
|
case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
|
||||||
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
|
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
|
||||||
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
|
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
|
||||||
@@ -308,6 +335,16 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break;
|
case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpPackInt2x16: out.debug << "packInt2x16"; break;
|
||||||
|
case EOpUnpackInt2x16: out.debug << "unpackInt2x16"; break;
|
||||||
|
case EOpPackUint2x16: out.debug << "packUint2x16"; break;
|
||||||
|
case EOpUnpackUint2x16: out.debug << "unpackUint2x16"; break;
|
||||||
|
|
||||||
|
case EOpPackInt4x16: out.debug << "packInt4x16"; break;
|
||||||
|
case EOpUnpackInt4x16: out.debug << "unpackInt4x16"; break;
|
||||||
|
case EOpPackUint4x16: out.debug << "packUint4x16"; break;
|
||||||
|
case EOpUnpackUint4x16: out.debug << "unpackUint4x16"; break;
|
||||||
|
|
||||||
case EOpPackFloat2x16: out.debug << "packFloat2x16"; break;
|
case EOpPackFloat2x16: out.debug << "packFloat2x16"; break;
|
||||||
case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break;
|
case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break;
|
||||||
#endif
|
#endif
|
||||||
@@ -370,6 +407,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpRcp: out.debug << "rcp"; break;
|
case EOpRcp: out.debug << "rcp"; break;
|
||||||
case EOpSaturate: out.debug << "saturate"; break;
|
case EOpSaturate: out.debug << "saturate"; break;
|
||||||
|
|
||||||
|
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
||||||
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
||||||
@@ -411,6 +450,42 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpConvFloat16ToDouble: out.debug << "Convert float16 to double"; break;
|
case EOpConvFloat16ToDouble: out.debug << "Convert float16 to double"; break;
|
||||||
case EOpConvFloat16ToInt64: out.debug << "Convert float16 to int64"; break;
|
case EOpConvFloat16ToInt64: out.debug << "Convert float16 to int64"; break;
|
||||||
case EOpConvFloat16ToUint64: out.debug << "Convert float16 to uint64"; break;
|
case EOpConvFloat16ToUint64: out.debug << "Convert float16 to uint64"; break;
|
||||||
|
|
||||||
|
case EOpConvBoolToInt16: out.debug << "Convert bool to int16"; break;
|
||||||
|
case EOpConvIntToInt16: out.debug << "Convert int to int16"; break;
|
||||||
|
case EOpConvUintToInt16: out.debug << "Convert uint to int16"; break;
|
||||||
|
case EOpConvFloatToInt16: out.debug << "Convert float to int16"; break;
|
||||||
|
case EOpConvDoubleToInt16: out.debug << "Convert double to int16"; break;
|
||||||
|
case EOpConvFloat16ToInt16: out.debug << "Convert float16 to int16"; break;
|
||||||
|
case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16"; break;
|
||||||
|
case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16"; break;
|
||||||
|
case EOpConvUint16ToInt16: out.debug << "Convert uint16 to int16"; break;
|
||||||
|
case EOpConvInt16ToBool: out.debug << "Convert int16 to bool"; break;
|
||||||
|
case EOpConvInt16ToInt: out.debug << "Convert int16 to int"; break;
|
||||||
|
case EOpConvInt16ToUint: out.debug << "Convert int16 to uint"; break;
|
||||||
|
case EOpConvInt16ToFloat: out.debug << "Convert int16 to float"; break;
|
||||||
|
case EOpConvInt16ToDouble: out.debug << "Convert int16 to double"; break;
|
||||||
|
case EOpConvInt16ToFloat16: out.debug << "Convert int16 to float16"; break;
|
||||||
|
case EOpConvInt16ToInt64: out.debug << "Convert int16 to int64"; break;
|
||||||
|
case EOpConvInt16ToUint64: out.debug << "Convert int16 to uint64"; break;
|
||||||
|
|
||||||
|
case EOpConvBoolToUint16: out.debug << "Convert bool to uint16"; break;
|
||||||
|
case EOpConvIntToUint16: out.debug << "Convert int to uint16"; break;
|
||||||
|
case EOpConvUintToUint16: out.debug << "Convert uint to uint16"; break;
|
||||||
|
case EOpConvFloatToUint16: out.debug << "Convert float to uint16"; break;
|
||||||
|
case EOpConvDoubleToUint16: out.debug << "Convert double to uint16"; break;
|
||||||
|
case EOpConvFloat16ToUint16: out.debug << "Convert float16 to uint16"; break;
|
||||||
|
case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16"; break;
|
||||||
|
case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break;
|
||||||
|
case EOpConvInt16ToUint16: out.debug << "Convert int16 to uint16"; break;
|
||||||
|
case EOpConvUint16ToBool: out.debug << "Convert uint16 to bool"; break;
|
||||||
|
case EOpConvUint16ToInt: out.debug << "Convert uint16 to int"; break;
|
||||||
|
case EOpConvUint16ToUint: out.debug << "Convert uint16 to uint"; break;
|
||||||
|
case EOpConvUint16ToFloat: out.debug << "Convert uint16 to float"; break;
|
||||||
|
case EOpConvUint16ToDouble: out.debug << "Convert uint16 to double"; break;
|
||||||
|
case EOpConvUint16ToFloat16: out.debug << "Convert uint16 to float16"; break;
|
||||||
|
case EOpConvUint16ToInt64: out.debug << "Convert uint16 to int64"; break;
|
||||||
|
case EOpConvUint16ToUint64: out.debug << "Convert uint16 to uint64"; break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
default: out.debug.message(EPrefixError, "Bad unary op");
|
||||||
@@ -444,9 +519,13 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
|
|
||||||
case EOpConstructFloat: out.debug << "Construct float"; break;
|
case EOpConstructFloat: out.debug << "Construct float"; break;
|
||||||
case EOpConstructDouble:out.debug << "Construct double"; break;
|
case EOpConstructDouble:out.debug << "Construct double"; break;
|
||||||
|
|
||||||
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
||||||
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
||||||
case EOpConstructVec4: out.debug << "Construct vec4"; break;
|
case EOpConstructVec4: out.debug << "Construct vec4"; break;
|
||||||
|
case EOpConstructDVec2: out.debug << "Construct dvec2"; break;
|
||||||
|
case EOpConstructDVec3: out.debug << "Construct dvec3"; break;
|
||||||
|
case EOpConstructDVec4: out.debug << "Construct dvec4"; break;
|
||||||
case EOpConstructBool: out.debug << "Construct bool"; break;
|
case EOpConstructBool: out.debug << "Construct bool"; break;
|
||||||
case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
|
case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
|
||||||
case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
|
case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
|
||||||
@@ -467,6 +546,16 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
|
case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
|
||||||
case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
|
case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
|
||||||
case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
|
case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpConstructInt16: out.debug << "Construct int16_t"; break;
|
||||||
|
case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
|
||||||
|
case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
|
||||||
|
case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
|
||||||
|
case EOpConstructUint16: out.debug << "Construct uint16_t"; break;
|
||||||
|
case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
|
||||||
|
case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
|
||||||
|
case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
|
||||||
|
#endif
|
||||||
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
|
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
|
||||||
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
|
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
|
||||||
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
|
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
|
||||||
@@ -485,6 +574,33 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
|
case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
|
||||||
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
||||||
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
||||||
|
case EOpConstructIMat2x2: out.debug << "Construct imat2"; break;
|
||||||
|
case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
|
||||||
|
case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
|
||||||
|
case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
|
||||||
|
case EOpConstructIMat3x3: out.debug << "Construct imat3"; break;
|
||||||
|
case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
|
||||||
|
case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
|
||||||
|
case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
|
||||||
|
case EOpConstructIMat4x4: out.debug << "Construct imat4"; break;
|
||||||
|
case EOpConstructUMat2x2: out.debug << "Construct umat2"; break;
|
||||||
|
case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
|
||||||
|
case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
|
||||||
|
case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
|
||||||
|
case EOpConstructUMat3x3: out.debug << "Construct umat3"; break;
|
||||||
|
case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
|
||||||
|
case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
|
||||||
|
case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
|
||||||
|
case EOpConstructUMat4x4: out.debug << "Construct umat4"; break;
|
||||||
|
case EOpConstructBMat2x2: out.debug << "Construct bmat2"; break;
|
||||||
|
case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
|
||||||
|
case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
|
||||||
|
case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
|
||||||
|
case EOpConstructBMat3x3: out.debug << "Construct bmat3"; break;
|
||||||
|
case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
|
||||||
|
case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
|
||||||
|
case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
|
||||||
|
case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EOpConstructFloat16: out.debug << "Construct float16_t"; break;
|
case EOpConstructFloat16: out.debug << "Construct float16_t"; break;
|
||||||
case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break;
|
case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break;
|
||||||
@@ -600,6 +716,37 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpTextureGather: out.debug << "textureGather"; break;
|
case EOpTextureGather: out.debug << "textureGather"; break;
|
||||||
case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break;
|
case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break;
|
||||||
case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break;
|
case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break;
|
||||||
|
case EOpTextureClamp: out.debug << "textureClamp"; break;
|
||||||
|
case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break;
|
||||||
|
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
||||||
|
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
||||||
|
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
||||||
|
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
||||||
|
case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break;
|
||||||
|
case EOpSparseTextureLod: out.debug << "sparseTextureLod"; break;
|
||||||
|
case EOpSparseTextureLodOffset: out.debug << "sparseTextureLodOffset"; break;
|
||||||
|
case EOpSparseTextureFetch: out.debug << "sparseTexelFetch"; break;
|
||||||
|
case EOpSparseTextureFetchOffset: out.debug << "sparseTexelFetchOffset"; break;
|
||||||
|
case EOpSparseTextureGrad: out.debug << "sparseTextureGrad"; break;
|
||||||
|
case EOpSparseTextureGradOffset: out.debug << "sparseTextureGradOffset"; break;
|
||||||
|
case EOpSparseTextureGather: out.debug << "sparseTextureGather"; break;
|
||||||
|
case EOpSparseTextureGatherOffset: out.debug << "sparseTextureGatherOffset"; break;
|
||||||
|
case EOpSparseTextureGatherOffsets: out.debug << "sparseTextureGatherOffsets"; break;
|
||||||
|
case EOpSparseImageLoad: out.debug << "sparseImageLoad"; break;
|
||||||
|
case EOpSparseTextureClamp: out.debug << "sparseTextureClamp"; break;
|
||||||
|
case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break;
|
||||||
|
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
||||||
|
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
||||||
|
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
||||||
|
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpAddCarry: out.debug << "addCarry"; break;
|
case EOpAddCarry: out.debug << "addCarry"; break;
|
||||||
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
||||||
@@ -694,11 +841,14 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const double value = constUnion[i].getDConst();
|
const double value = constUnion[i].getDConst();
|
||||||
// Print infinity in a portable way, for test stability.
|
// Print infinities and NaNs in a portable way.
|
||||||
// Other cases may be needed in the future: negative infinity,
|
if (IsInfinity(value)) {
|
||||||
// and NaNs.
|
if (value < 0)
|
||||||
if (is_positive_infinity(value))
|
out.debug << "-1.#INF\n";
|
||||||
out.debug << "inf\n";
|
else
|
||||||
|
out.debug << "+1.#INF\n";
|
||||||
|
} else if (IsNan(value))
|
||||||
|
out.debug << "1.#IND\n";
|
||||||
else {
|
else {
|
||||||
const int maxSize = 300;
|
const int maxSize = 300;
|
||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
@@ -744,6 +894,26 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
|
|||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
{
|
||||||
|
const int maxSize = 300;
|
||||||
|
char buf[maxSize];
|
||||||
|
snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t");
|
||||||
|
|
||||||
|
out.debug << buf << "\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
{
|
||||||
|
const int maxSize = 300;
|
||||||
|
char buf[maxSize];
|
||||||
|
snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t");
|
||||||
|
|
||||||
|
out.debug << buf << "\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
|
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
|
||||||
break;
|
break;
|
||||||
@@ -884,6 +1054,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||||||
|
|
||||||
case EShLangTessControl:
|
case EShLangTessControl:
|
||||||
infoSink.debug << "vertices = " << vertices << "\n";
|
infoSink.debug << "vertices = " << vertices << "\n";
|
||||||
|
|
||||||
|
if (inputPrimitive != ElgNone)
|
||||||
|
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
|
||||||
|
if (vertexSpacing != EvsNone)
|
||||||
|
infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
|
||||||
|
if (vertexOrder != EvoNone)
|
||||||
|
infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2016 LunarG, Inc.
|
// Copyright (C) 2016-2017 LunarG, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -66,11 +66,14 @@ namespace glslang {
|
|||||||
|
|
||||||
struct TVarEntryInfo
|
struct TVarEntryInfo
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
TIntermSymbol* symbol;
|
TIntermSymbol* symbol;
|
||||||
bool live;
|
bool live;
|
||||||
int newBinding;
|
int newBinding;
|
||||||
int newSet;
|
int newSet;
|
||||||
|
int newLocation;
|
||||||
|
int newComponent;
|
||||||
|
int newIndex;
|
||||||
|
|
||||||
struct TOrderById
|
struct TOrderById
|
||||||
{
|
{
|
||||||
@@ -113,70 +116,143 @@ typedef std::vector<TVarEntryInfo> TVarLiveMap;
|
|||||||
class TVarGatherTraverser : public TLiveTraverser
|
class TVarGatherTraverser : public TLiveTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TVarGatherTraverser(const TIntermediate& i, TVarLiveMap& vars, bool traverseDeadCode)
|
TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
|
||||||
: TLiveTraverser(i, traverseDeadCode, true, true, false)
|
: TLiveTraverser(i, traverseDeadCode, true, true, false)
|
||||||
, varLiveList(vars)
|
, inputList(inList)
|
||||||
|
, outputList(outList)
|
||||||
|
, uniformList(uniformList)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void visitSymbol(TIntermSymbol* base)
|
virtual void visitSymbol(TIntermSymbol* base)
|
||||||
{
|
{
|
||||||
if (base->getQualifier().storage == EvqUniform) {
|
TVarLiveMap* target = nullptr;
|
||||||
|
if (base->getQualifier().storage == EvqVaryingIn)
|
||||||
|
target = &inputList;
|
||||||
|
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||||
|
target = &outputList;
|
||||||
|
else if (base->getQualifier().isUniformOrBuffer())
|
||||||
|
target = &uniformList;
|
||||||
|
|
||||||
|
if (target) {
|
||||||
TVarEntryInfo ent = { base->getId(), base, !traverseAll };
|
TVarEntryInfo ent = { base->getId(), base, !traverseAll };
|
||||||
TVarLiveMap::iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
|
TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
|
||||||
if (at != varLiveList.end() && at->id == ent.id)
|
if (at != target->end() && at->id == ent.id)
|
||||||
at->live = at->live || !traverseAll; // update live state
|
at->live = at->live || !traverseAll; // update live state
|
||||||
else
|
else
|
||||||
varLiveList.insert(at, ent);
|
target->insert(at, ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TVarLiveMap& varLiveList;
|
TVarLiveMap& inputList;
|
||||||
|
TVarLiveMap& outputList;
|
||||||
|
TVarLiveMap& uniformList;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TVarSetTraverser : public TLiveTraverser
|
class TVarSetTraverser : public TLiveTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& vars)
|
TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
|
||||||
: TLiveTraverser(i, true, true, true, false)
|
: TLiveTraverser(i, true, true, true, false)
|
||||||
, varLiveList(vars)
|
, inputList(inList)
|
||||||
|
, outputList(outList)
|
||||||
|
, uniformList(uniformList)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void visitSymbol(TIntermSymbol* base)
|
virtual void visitSymbol(TIntermSymbol* base)
|
||||||
{
|
{
|
||||||
TVarEntryInfo ent = { base->getId() };
|
const TVarLiveMap* source;
|
||||||
TVarLiveMap::const_iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
|
if (base->getQualifier().storage == EvqVaryingIn)
|
||||||
if (at == varLiveList.end())
|
source = &inputList;
|
||||||
|
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||||
|
source = &outputList;
|
||||||
|
else if (base->getQualifier().isUniformOrBuffer())
|
||||||
|
source = &uniformList;
|
||||||
|
else
|
||||||
return;
|
return;
|
||||||
if (!(at->id == ent.id))
|
|
||||||
|
TVarEntryInfo ent = { base->getId() };
|
||||||
|
TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById());
|
||||||
|
if (at == source->end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (at->id != ent.id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (at->newBinding != -1)
|
if (at->newBinding != -1)
|
||||||
base->getWritableType().getQualifier().layoutBinding = at->newBinding;
|
base->getWritableType().getQualifier().layoutBinding = at->newBinding;
|
||||||
if (at->newSet != -1)
|
if (at->newSet != -1)
|
||||||
base->getWritableType().getQualifier().layoutSet = at->newSet;
|
base->getWritableType().getQualifier().layoutSet = at->newSet;
|
||||||
|
if (at->newLocation != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutLocation = at->newLocation;
|
||||||
|
if (at->newComponent != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutComponent = at->newComponent;
|
||||||
|
if (at->newIndex != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutIndex = at->newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TVarLiveMap& varLiveList;
|
const TVarLiveMap& inputList;
|
||||||
|
const TVarLiveMap& outputList;
|
||||||
|
const TVarLiveMap& uniformList;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TResolverAdaptor
|
struct TNotifyUniformAdaptor
|
||||||
{
|
{
|
||||||
TResolverAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e)
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TNotifyInOutAdaptor
|
||||||
|
{
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TResolverUniformAdaptor
|
||||||
|
{
|
||||||
|
TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
|
||||||
: stage(s)
|
: stage(s)
|
||||||
, resolver(r)
|
, resolver(r)
|
||||||
, infoSink(i)
|
, infoSink(i)
|
||||||
, error(e)
|
, error(e)
|
||||||
|
, intermediate(interm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void operator()(TVarEntryInfo& ent)
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
{
|
{
|
||||||
|
ent.newLocation = -1;
|
||||||
|
ent.newComponent = -1;
|
||||||
|
ent.newBinding = -1;
|
||||||
|
ent.newSet = -1;
|
||||||
|
ent.newIndex = -1;
|
||||||
const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
@@ -209,25 +285,77 @@ struct TResolverAdaptor
|
|||||||
TIoMapResolver& resolver;
|
TIoMapResolver& resolver;
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
bool& error;
|
bool& error;
|
||||||
|
TIntermediate& intermediate;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TResolverAdaptor& operator=(TResolverAdaptor&);
|
TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct TResolverInOutAdaptor
|
||||||
* Basic implementation of glslang::TIoMapResolver that replaces the
|
{
|
||||||
* previous offset behaviour.
|
TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
|
||||||
* It does the same, uses the offsets for th corresponding uniform
|
: stage(s)
|
||||||
* types. Also respects the EOptionAutoMapBindings flag and binds
|
, resolver(r)
|
||||||
* them if needed.
|
, infoSink(i)
|
||||||
*/
|
, error(e)
|
||||||
struct TDefaultIoResolver : public glslang::TIoMapResolver
|
, intermediate(interm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
ent.newLocation = -1;
|
||||||
|
ent.newComponent = -1;
|
||||||
|
ent.newBinding = -1;
|
||||||
|
ent.newSet = -1;
|
||||||
|
ent.newIndex = -1;
|
||||||
|
const bool isValid = resolver.validateInOut(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
if (isValid) {
|
||||||
|
ent.newLocation = resolver.resolveInOutLocation(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
ent.newComponent = resolver.resolveInOutComponent(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
ent.newIndex = resolver.resolveInOutIndex(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
} else {
|
||||||
|
TString errorMsg = "Invalid shader In/Out variable semantic: ";
|
||||||
|
errorMsg += ent.symbol->getType().getQualifier().semanticName;
|
||||||
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
TInfoSink& infoSink;
|
||||||
|
bool& error;
|
||||||
|
TIntermediate& intermediate;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
||||||
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
{
|
{
|
||||||
int baseSamplerBinding;
|
int baseSamplerBinding;
|
||||||
int baseTextureBinding;
|
int baseTextureBinding;
|
||||||
int baseImageBinding;
|
int baseImageBinding;
|
||||||
int baseUboBinding;
|
int baseUboBinding;
|
||||||
bool doAutoMapping;
|
int baseSsboBinding;
|
||||||
|
int baseUavBinding;
|
||||||
|
std::vector<std::string> baseResourceSetBinding;
|
||||||
|
bool doAutoBindingMapping;
|
||||||
|
bool doAutoLocationMapping;
|
||||||
typedef std::vector<int> TSlotSet;
|
typedef std::vector<int> TSlotSet;
|
||||||
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||||
TSlotSetMap slots;
|
TSlotSetMap slots;
|
||||||
@@ -246,7 +374,12 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
|
|||||||
int reserveSlot(int set, int slot)
|
int reserveSlot(int set, int slot)
|
||||||
{
|
{
|
||||||
TSlotSet::iterator at = findSlot(set, slot);
|
TSlotSet::iterator at = findSlot(set, slot);
|
||||||
slots[set].insert(at, slot);
|
|
||||||
|
// tolerate aliasing, by not double-recording aliases
|
||||||
|
// (policy about appropriateness of the alias is higher up)
|
||||||
|
if (at == slots[set].end() || *at != slot)
|
||||||
|
slots[set].insert(at, slot);
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,74 +396,9 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
|
|||||||
return reserveSlot(set, base);
|
return reserveSlot(set, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0;
|
||||||
{
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
|
||||||
int set;
|
|
||||||
if (type.getQualifier().hasSet())
|
|
||||||
set = type.getQualifier().layoutSet;
|
|
||||||
else
|
|
||||||
set = 0;
|
|
||||||
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0;
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().isUniformOrBuffer())
|
|
||||||
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
|
||||||
{
|
|
||||||
int set;
|
|
||||||
if (type.getQualifier().hasSet())
|
|
||||||
set = type.getQualifier().layoutSet;
|
|
||||||
else
|
|
||||||
set = 0;
|
|
||||||
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isImage())
|
|
||||||
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().isUniformOrBuffer())
|
|
||||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
||||||
} else if (is_live && doAutoMapping) {
|
|
||||||
// find free slot, the caller did make sure it passes all vars with binding
|
|
||||||
// first and now all are passed that do not have a binding and needs one
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isImage())
|
|
||||||
return getFreeSlot(set, baseImageBinding);
|
|
||||||
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return getFreeSlot(set, baseSamplerBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return getFreeSlot(set, baseTextureBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().isUniformOrBuffer())
|
|
||||||
return getFreeSlot(set, baseUboBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
@@ -338,8 +406,231 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
|
|||||||
return type.getQualifier().layoutSet;
|
return type.getQualifier().layoutSet;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
if (!doAutoLocationMapping || type.getQualifier().hasLocation())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Placeholder.
|
||||||
|
// TODO: It would be nice to flesh this out using
|
||||||
|
// intermediate->computeTypeLocationSize(type), or functions that call it like
|
||||||
|
// intermediate->addUsedLocation()
|
||||||
|
// These in turn would want the intermediate, which is not available here, but
|
||||||
|
// is available in many places, and a lot of copying from it could be saved if
|
||||||
|
// it were just available.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
|
||||||
|
void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
|
||||||
|
void endNotifications() override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static int getLayoutSet(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().hasSet())
|
||||||
|
return type.getQualifier().layoutSet;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSamplerType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isTextureType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isUboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqUniform;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic implementation of glslang::TIoMapResolver that replaces the
|
||||||
|
* previous offset behavior.
|
||||||
|
* It does the same, uses the offsets for the corresponding uniform
|
||||||
|
* types. Also respects the EOptionAutoMapBindings flag and binds
|
||||||
|
* them if needed.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Default resolver
|
||||||
|
*/
|
||||||
|
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isImageType(type))
|
||||||
|
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoBindingMapping) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isImageType(type))
|
||||||
|
return getFreeSlot(set, baseImageBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return getFreeSlot(set, baseTextureBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return getFreeSlot(set, baseSsboBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, baseSamplerBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, baseUboBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static bool isImageType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSsboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
The following IO resolver maps types in HLSL register space, as follows:
|
||||||
|
|
||||||
|
t – for shader resource views (SRV)
|
||||||
|
TEXTURE1D
|
||||||
|
TEXTURE1DARRAY
|
||||||
|
TEXTURE2D
|
||||||
|
TEXTURE2DARRAY
|
||||||
|
TEXTURE3D
|
||||||
|
TEXTURECUBE
|
||||||
|
TEXTURECUBEARRAY
|
||||||
|
TEXTURE2DMS
|
||||||
|
TEXTURE2DMSARRAY
|
||||||
|
STRUCTUREDBUFFER
|
||||||
|
BYTEADDRESSBUFFER
|
||||||
|
BUFFER
|
||||||
|
TBUFFER
|
||||||
|
|
||||||
|
s – for samplers
|
||||||
|
SAMPLER
|
||||||
|
SAMPLER1D
|
||||||
|
SAMPLER2D
|
||||||
|
SAMPLER3D
|
||||||
|
SAMPLERCUBE
|
||||||
|
SAMPLERSTATE
|
||||||
|
SAMPLERCOMPARISONSTATE
|
||||||
|
|
||||||
|
u – for unordered access views (UAV)
|
||||||
|
RWBYTEADDRESSBUFFER
|
||||||
|
RWSTRUCTUREDBUFFER
|
||||||
|
APPENDSTRUCTUREDBUFFER
|
||||||
|
CONSUMESTRUCTUREDBUFFER
|
||||||
|
RWBUFFER
|
||||||
|
RWTEXTURE1D
|
||||||
|
RWTEXTURE1DARRAY
|
||||||
|
RWTEXTURE2D
|
||||||
|
RWTEXTURE2DARRAY
|
||||||
|
RWTEXTURE3D
|
||||||
|
|
||||||
|
b – for constant buffer views (CBV)
|
||||||
|
CBUFFER
|
||||||
|
CONSTANTBUFFER
|
||||||
|
********************************************************************************/
|
||||||
|
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isUavType(type))
|
||||||
|
return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoBindingMapping) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isUavType(type))
|
||||||
|
return getFreeSlot(set, baseUavBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return getFreeSlot(set, baseTextureBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, baseSamplerBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, baseUboBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Return true if this is a SRV (shader resource view) type:
|
||||||
|
static bool isSrvType(const glslang::TType& type) {
|
||||||
|
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if this is a UAV (unordered access view) type:
|
||||||
|
static bool isUavType(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().readonly)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
|
||||||
|
(type.getQualifier().storage == EvqBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Map I/O variables to provided offsets, and make bindings for
|
// Map I/O variables to provided offsets, and make bindings for
|
||||||
// unbound but live variables.
|
// unbound but live variables.
|
||||||
//
|
//
|
||||||
@@ -351,7 +642,11 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|||||||
intermediate.getShiftTextureBinding() == 0 &&
|
intermediate.getShiftTextureBinding() == 0 &&
|
||||||
intermediate.getShiftImageBinding() == 0 &&
|
intermediate.getShiftImageBinding() == 0 &&
|
||||||
intermediate.getShiftUboBinding() == 0 &&
|
intermediate.getShiftUboBinding() == 0 &&
|
||||||
|
intermediate.getShiftSsboBinding() == 0 &&
|
||||||
|
intermediate.getShiftUavBinding() == 0 &&
|
||||||
|
intermediate.getResourceSetBinding().empty() &&
|
||||||
intermediate.getAutoMapBindings() == false &&
|
intermediate.getAutoMapBindings() == false &&
|
||||||
|
intermediate.getAutoMapLocations() == false &&
|
||||||
resolver == nullptr)
|
resolver == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -364,19 +659,33 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|||||||
|
|
||||||
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
||||||
TDefaultIoResolver defaultResolver;
|
TDefaultIoResolver defaultResolver;
|
||||||
if (resolver == nullptr) {
|
TDefaultHlslIoResolver defaultHlslResolver;
|
||||||
defaultResolver.baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
|
||||||
defaultResolver.baseTextureBinding = intermediate.getShiftTextureBinding();
|
|
||||||
defaultResolver.baseImageBinding = intermediate.getShiftImageBinding();
|
|
||||||
defaultResolver.baseUboBinding = intermediate.getShiftUboBinding();
|
|
||||||
defaultResolver.doAutoMapping = intermediate.getAutoMapBindings();
|
|
||||||
|
|
||||||
resolver = &defaultResolver;
|
if (resolver == nullptr) {
|
||||||
|
TDefaultIoResolverBase* resolverBase;
|
||||||
|
|
||||||
|
// TODO: use a passed in IO mapper for this
|
||||||
|
if (intermediate.usingHlslIoMapping())
|
||||||
|
resolverBase = &defaultHlslResolver;
|
||||||
|
else
|
||||||
|
resolverBase = &defaultResolver;
|
||||||
|
|
||||||
|
resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
||||||
|
resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
|
||||||
|
resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
|
||||||
|
resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
|
||||||
|
resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
|
||||||
|
resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
|
||||||
|
resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
|
||||||
|
resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
|
||||||
|
resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
|
||||||
|
|
||||||
|
resolver = resolverBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVarLiveMap varMap;
|
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
||||||
TVarGatherTraverser iter_binding_all(intermediate, varMap, true);
|
TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);
|
||||||
TVarGatherTraverser iter_binding_live(intermediate, varMap, false);
|
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
||||||
|
|
||||||
root->traverse(&iter_binding_all);
|
root->traverse(&iter_binding_all);
|
||||||
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
@@ -388,16 +697,25 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
||||||
std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderByPriority());
|
std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority());
|
||||||
|
|
||||||
bool hadError = false;
|
bool hadError = false;
|
||||||
TResolverAdaptor doResolve(stage, *resolver, infoSink, hadError);
|
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
||||||
std::for_each(varMap.begin(), varMap.end(), doResolve);
|
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
||||||
|
TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
|
||||||
|
TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
|
||||||
|
std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify);
|
||||||
|
std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify);
|
||||||
|
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify);
|
||||||
|
resolver->endNotifications();
|
||||||
|
std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
|
||||||
|
std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
|
||||||
|
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
|
||||||
|
|
||||||
if (!hadError) {
|
if (!hadError) {
|
||||||
// sort by id again, so we can use lower bound to find entries
|
// sort by id again, so we can use lower bound to find entries
|
||||||
std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderById());
|
std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById());
|
||||||
TVarSetTraverser iter_iomap(intermediate, varMap);
|
TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap);
|
||||||
root->traverse(&iter_iomap);
|
root->traverse(&iter_iomap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -461,10 +461,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (vertexSpacing == EvsNone)
|
if (source == EShSourceGlsl) {
|
||||||
vertexSpacing = EvsEqual;
|
if (vertexSpacing == EvsNone)
|
||||||
if (vertexOrder == EvoNone)
|
vertexSpacing = EvsEqual;
|
||||||
vertexOrder = EvoCcw;
|
if (vertexOrder == EvoNone)
|
||||||
|
vertexOrder = EvoCcw;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
@@ -858,7 +860,7 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
|
|||||||
return -1; // no collision
|
return -1; // no collision
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
|
// Accumulate bindings and offsets, and check for collisions
|
||||||
// as the accumulation is done.
|
// as the accumulation is done.
|
||||||
//
|
//
|
||||||
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
@@ -1045,9 +1047,9 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
|
|
||||||
const int baseAlignmentVec4Std140 = 16;
|
const int baseAlignmentVec4Std140 = 16;
|
||||||
|
|
||||||
// Return the size and alignment of a scalar.
|
// Return the size and alignment of a component of the given type.
|
||||||
// The size is returned in the 'size' parameter
|
// The size is returned in the 'size' parameter
|
||||||
// Return value is the alignment of the type.
|
// Return value is the alignment..
|
||||||
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
{
|
{
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
@@ -1055,6 +1057,8 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
|||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
case EbtDouble: size = 8; return 8;
|
case EbtDouble: size = 8; return 8;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
case EbtFloat16: size = 2; return 2;
|
case EbtFloat16: size = 2; return 2;
|
||||||
#endif
|
#endif
|
||||||
default: size = 4; return 4;
|
default: size = 4; return 4;
|
||||||
@@ -1217,4 +1221,14 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
|||||||
return baseAlignmentVec4Std140;
|
return baseAlignmentVec4Std140;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To aid the basic HLSL rule about crossing vec4 boundaries.
|
||||||
|
bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
||||||
|
{
|
||||||
|
if (! type.isVector() || type.isArray())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return size <= 16 ? offset / 16 != (offset + size - 1) / 16
|
||||||
|
: offset % 16 != 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -174,9 +174,16 @@ public:
|
|||||||
shiftTextureBinding(0),
|
shiftTextureBinding(0),
|
||||||
shiftImageBinding(0),
|
shiftImageBinding(0),
|
||||||
shiftUboBinding(0),
|
shiftUboBinding(0),
|
||||||
|
shiftSsboBinding(0),
|
||||||
|
shiftUavBinding(0),
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
|
autoMapLocations(false),
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
useUnknownFormat(false)
|
useUnknownFormat(false),
|
||||||
|
hlslOffsets(false),
|
||||||
|
useStorageBuffer(false),
|
||||||
|
hlslIoMapping(false),
|
||||||
|
textureSamplerTransformMode(EShTexSampTransKeep)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
@@ -207,12 +214,27 @@ public:
|
|||||||
unsigned int getShiftImageBinding() const { return shiftImageBinding; }
|
unsigned int getShiftImageBinding() const { return shiftImageBinding; }
|
||||||
void setShiftUboBinding(unsigned int shift) { shiftUboBinding = shift; }
|
void setShiftUboBinding(unsigned int shift) { shiftUboBinding = shift; }
|
||||||
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
|
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
|
||||||
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; }
|
||||||
|
unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
|
||||||
|
void setShiftUavBinding(unsigned int shift) { shiftUavBinding = shift; }
|
||||||
|
unsigned int getShiftUavBinding() const { return shiftUavBinding; }
|
||||||
|
void setResourceSetBinding(const std::vector<std::string>& shift) { resourceSetBinding = shift; }
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
|
||||||
|
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
||||||
bool getAutoMapBindings() const { return autoMapBindings; }
|
bool getAutoMapBindings() const { return autoMapBindings; }
|
||||||
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
void setAutoMapLocations(bool map) { autoMapLocations = map; }
|
||||||
|
bool getAutoMapLocations() const { return autoMapLocations; }
|
||||||
|
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
||||||
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||||
void setNoStorageFormat(bool b) { useUnknownFormat = b; }
|
void setNoStorageFormat(bool b) { useUnknownFormat = b; }
|
||||||
bool getNoStorageFormat() const { return useUnknownFormat; }
|
bool getNoStorageFormat() const { return useUnknownFormat; }
|
||||||
|
void setHlslOffsets() { hlslOffsets = true; }
|
||||||
|
bool usingHlslOFfsets() const { return hlslOffsets; }
|
||||||
|
void setUseStorageBuffer() { useStorageBuffer = true; }
|
||||||
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
|
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
||||||
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
@@ -237,7 +259,9 @@ public:
|
|||||||
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
||||||
TIntermSymbol* addSymbol(const TIntermSymbol&);
|
TIntermSymbol* addSymbol(const TIntermSymbol&);
|
||||||
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
|
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
|
||||||
TIntermTyped* addShapeConversion(TOperator, const TType&, TIntermTyped*);
|
TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
|
||||||
|
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
||||||
|
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
||||||
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
||||||
@@ -261,13 +285,18 @@ public:
|
|||||||
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
TIntermConstantUnion* addConstantUnion(short, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const;
|
||||||
|
|
||||||
|
#endif
|
||||||
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
|
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
|
||||||
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
||||||
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
|
||||||
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
|
||||||
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
||||||
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
||||||
template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
|
template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
|
||||||
@@ -410,7 +439,9 @@ public:
|
|||||||
}
|
}
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||||
|
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||||
|
static bool improperStraddle(const TType& type, int size, int offset);
|
||||||
bool promote(TIntermOperator*);
|
bool promote(TIntermOperator*);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
@@ -420,6 +451,18 @@ public:
|
|||||||
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char* addSemanticName(const TString& name)
|
||||||
|
{
|
||||||
|
return semanticNameSet.insert(name).first->c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSourceFile(const char* file) { sourceFile = file; }
|
||||||
|
const std::string& getSourceFile() const { return sourceFile; }
|
||||||
|
void addSourceText(const char* text) { sourceText = sourceText + text; }
|
||||||
|
const std::string& getSourceText() const { return sourceText; }
|
||||||
|
|
||||||
|
const char* const implicitThisName = "@this";
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*);
|
||||||
@@ -433,7 +476,6 @@ protected:
|
|||||||
void inOutLocationCheck(TInfoSink&);
|
void inOutLocationCheck(TInfoSink&);
|
||||||
TIntermSequence& findLinkerObjects() const;
|
TIntermSequence& findLinkerObjects() const;
|
||||||
bool userOutputUsed() const;
|
bool userOutputUsed() const;
|
||||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
|
||||||
bool isSpecializationOperation(const TIntermOperator&) const;
|
bool isSpecializationOperation(const TIntermOperator&) const;
|
||||||
bool promoteUnary(TIntermUnary&);
|
bool promoteUnary(TIntermUnary&);
|
||||||
bool promoteBinary(TIntermBinary&);
|
bool promoteBinary(TIntermBinary&);
|
||||||
@@ -442,6 +484,7 @@ protected:
|
|||||||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
|
|
||||||
const EShLanguage language; // stage, known at construction time
|
const EShLanguage language; // stage, known at construction time
|
||||||
EShSource source; // source language, known a bit later
|
EShSource source; // source language, known a bit later
|
||||||
@@ -485,9 +528,16 @@ protected:
|
|||||||
unsigned int shiftTextureBinding;
|
unsigned int shiftTextureBinding;
|
||||||
unsigned int shiftImageBinding;
|
unsigned int shiftImageBinding;
|
||||||
unsigned int shiftUboBinding;
|
unsigned int shiftUboBinding;
|
||||||
|
unsigned int shiftSsboBinding;
|
||||||
|
unsigned int shiftUavBinding;
|
||||||
|
std::vector<std::string> resourceSetBinding;
|
||||||
bool autoMapBindings;
|
bool autoMapBindings;
|
||||||
|
bool autoMapLocations;
|
||||||
bool flattenUniformArrays;
|
bool flattenUniformArrays;
|
||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
|
bool hlslOffsets;
|
||||||
|
bool useStorageBuffer;
|
||||||
|
bool hlslIoMapping;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
TGraph callGraph;
|
TGraph callGraph;
|
||||||
@@ -497,6 +547,13 @@ protected:
|
|||||||
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
||||||
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
|
std::set<TString> semanticNameSet;
|
||||||
|
|
||||||
|
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||||
|
|
||||||
|
// source code of shader, useful as part of debug information
|
||||||
|
std::string sourceFile;
|
||||||
|
std::string sourceText;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
|
|||||||
@@ -76,12 +76,6 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getSequence().size() == 0) {
|
|
||||||
error = true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
|
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
|
||||||
if (flag) {
|
if (flag) {
|
||||||
singleConstantParam = true;
|
singleConstantParam = true;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public:
|
|||||||
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
||||||
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
||||||
|
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
||||||
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
@@ -77,6 +78,7 @@ public:
|
|||||||
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
virtual void int16Check(const TSourceLoc& loc, const char* op, bool builtIn = false);
|
||||||
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
#endif
|
#endif
|
||||||
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -391,6 +393,14 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
|||||||
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
|
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
|
||||||
if (token == PpAtomIdentifier) {
|
if (token == PpAtomIdentifier) {
|
||||||
if (strcmp("defined", ppToken->name) == 0) {
|
if (strcmp("defined", ppToken->name) == 0) {
|
||||||
|
if (! parseContext.isReadingHLSL() && isMacroInput()) {
|
||||||
|
if (parseContext.relaxedErrors())
|
||||||
|
parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
|
||||||
|
"defined", "");
|
||||||
|
else
|
||||||
|
parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
|
||||||
|
"defined", "");
|
||||||
|
}
|
||||||
bool needclose = 0;
|
bool needclose = 0;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == '(') {
|
if (token == '(') {
|
||||||
@@ -611,14 +621,14 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||||||
TShader::Includer::IncludeResult* res = nullptr;
|
TShader::Includer::IncludeResult* res = nullptr;
|
||||||
if (startWithLocalSearch)
|
if (startWithLocalSearch)
|
||||||
res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||||
if (! res || res->headerName.empty()) {
|
if (res == nullptr || res->headerName.empty()) {
|
||||||
includer.releaseInclude(res);
|
includer.releaseInclude(res);
|
||||||
res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the results
|
// Process the results
|
||||||
if (res && !res->headerName.empty()) {
|
if (res != nullptr && !res->headerName.empty()) {
|
||||||
if (res->headerData && res->headerLength) {
|
if (res->headerData != nullptr && res->headerLength > 0) {
|
||||||
// path for processing one or more tokens from an included header, hand off 'res'
|
// path for processing one or more tokens from an included header, hand off 'res'
|
||||||
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
||||||
std::ostringstream prologue;
|
std::ostringstream prologue;
|
||||||
@@ -636,8 +646,8 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||||||
} else {
|
} else {
|
||||||
// error path, clean up
|
// error path, clean up
|
||||||
std::string message =
|
std::string message =
|
||||||
res ? std::string(res->headerData, res->headerLength)
|
res != nullptr ? std::string(res->headerData, res->headerLength)
|
||||||
: std::string("Could not process include directive");
|
: std::string("Could not process include directive");
|
||||||
parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
|
parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
|
||||||
includer.releaseInclude(res);
|
includer.releaseInclude(res);
|
||||||
}
|
}
|
||||||
@@ -714,6 +724,7 @@ int TPpContext::CPPerror(TPpToken* ppToken)
|
|||||||
if (token == PpAtomConstInt || token == PpAtomConstUint ||
|
if (token == PpAtomConstInt || token == PpAtomConstUint ||
|
||||||
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
|
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
token == PpAtomConstInt16 || token == PpAtomConstUint16 ||
|
||||||
token == PpAtomConstFloat16 ||
|
token == PpAtomConstFloat16 ||
|
||||||
#endif
|
#endif
|
||||||
token == PpAtomConstFloat || token == PpAtomConstDouble) {
|
token == PpAtomConstFloat || token == PpAtomConstDouble) {
|
||||||
@@ -748,6 +759,10 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
|
|||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
@@ -776,8 +791,12 @@ int TPpContext::CPPversion(TPpToken* ppToken)
|
|||||||
{
|
{
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
|
||||||
if (errorOnVersion || versionSeen)
|
if (errorOnVersion || versionSeen) {
|
||||||
parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
|
if (parseContext.isReadingHLSL())
|
||||||
|
parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", "");
|
||||||
|
else
|
||||||
|
parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
|
||||||
|
}
|
||||||
versionSeen = true;
|
versionSeen = true;
|
||||||
|
|
||||||
if (token == '\n') {
|
if (token == '\n') {
|
||||||
@@ -986,6 +1005,8 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
|
|||||||
int token;
|
int token;
|
||||||
while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
|
while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
|
||||||
token = tokenPaste(token, *ppToken);
|
token = tokenPaste(token, *ppToken);
|
||||||
|
if (token == tMarkerInput::marker || token == EndOfInput)
|
||||||
|
break;
|
||||||
if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
|
if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
|
||||||
continue;
|
continue;
|
||||||
expandedArg->putToken(token, ppToken);
|
expandedArg->putToken(token, ppToken);
|
||||||
@@ -1050,7 +1071,7 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
|
|||||||
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
|
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
|
||||||
if (token == PpAtomIdentifier) {
|
if (token == PpAtomIdentifier) {
|
||||||
int i;
|
int i;
|
||||||
for (i = mac->args.size() - 1; i >= 0; i--)
|
for (i = (int)mac->args.size() - 1; i >= 0; i--)
|
||||||
if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
|
if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
|
||||||
break;
|
break;
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -120,6 +122,8 @@ const struct {
|
|||||||
{ PpAtomDecrement, "--" },
|
{ PpAtomDecrement, "--" },
|
||||||
{ PpAtomIncrement, "++" },
|
{ PpAtomIncrement, "++" },
|
||||||
|
|
||||||
|
{ PpAtomColonColon, "::" },
|
||||||
|
|
||||||
{ PpAtomDefine, "define" },
|
{ PpAtomDefine, "define" },
|
||||||
{ PpAtomUndef, "undef" },
|
{ PpAtomUndef, "undef" },
|
||||||
{ PpAtomIf, "if" },
|
{ PpAtomIf, "if" },
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace glslang {
|
|||||||
|
|
||||||
class TPpToken {
|
class TPpToken {
|
||||||
public:
|
public:
|
||||||
TPpToken() : space(false), ival(0), dval(0.0), i64val(0)
|
TPpToken() : space(false), i64val(0)
|
||||||
{
|
{
|
||||||
loc.init();
|
loc.init();
|
||||||
name[0] = 0;
|
name[0] = 0;
|
||||||
@@ -108,10 +108,14 @@ public:
|
|||||||
bool operator!=(const TPpToken& right) { return ! operator==(right); }
|
bool operator!=(const TPpToken& right) { return ! operator==(right); }
|
||||||
|
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
|
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
|
||||||
int ival;
|
|
||||||
double dval;
|
union {
|
||||||
long long i64val;
|
int ival;
|
||||||
|
double dval;
|
||||||
|
long long i64val;
|
||||||
|
};
|
||||||
|
|
||||||
char name[MaxTokenLength + 1];
|
char name[MaxTokenLength + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,6 +200,7 @@ public:
|
|||||||
virtual void ungetch() = 0;
|
virtual void ungetch() = 0;
|
||||||
virtual bool peekPasting() { return false; } // true when about to see ##
|
virtual bool peekPasting() { return false; } // true when about to see ##
|
||||||
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
|
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
|
||||||
|
virtual bool isMacroInput() { return false; }
|
||||||
|
|
||||||
// Will be called when we start reading tokens from this instance
|
// Will be called when we start reading tokens from this instance
|
||||||
virtual void notifyActivated() {}
|
virtual void notifyActivated() {}
|
||||||
@@ -236,7 +241,7 @@ public:
|
|||||||
void reset() { current = 0; }
|
void reset() { current = 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void putSubtoken(int);
|
void putSubtoken(char);
|
||||||
int getSubtoken();
|
int getSubtoken();
|
||||||
void ungetSubtoken();
|
void ungetSubtoken();
|
||||||
|
|
||||||
@@ -302,6 +307,7 @@ protected:
|
|||||||
void ungetChar() { inputStack.back()->ungetch(); }
|
void ungetChar() { inputStack.back()->ungetch(); }
|
||||||
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
|
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
|
||||||
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
|
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
|
||||||
|
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
|
||||||
|
|
||||||
static const int maxIfNesting = 64;
|
static const int maxIfNesting = 64;
|
||||||
|
|
||||||
@@ -325,6 +331,7 @@ protected:
|
|||||||
virtual void ungetch() override { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
bool peekPasting() override { return prepaste; }
|
bool peekPasting() override { return prepaste; }
|
||||||
bool endOfReplacementList() override { return mac->body.atEnd(); }
|
bool endOfReplacementList() override { return mac->body.atEnd(); }
|
||||||
|
bool isMacroInput() override { return true; }
|
||||||
|
|
||||||
MacroSymbol *mac;
|
MacroSymbol *mac;
|
||||||
TVector<TokenStream*> args;
|
TVector<TokenStream*> args;
|
||||||
@@ -584,6 +591,7 @@ protected:
|
|||||||
int ScanFromString(char* s);
|
int ScanFromString(char* s);
|
||||||
void missingEndifCheck();
|
void missingEndifCheck();
|
||||||
int lFloatConst(int len, int ch, TPpToken* ppToken);
|
int lFloatConst(int len, int ch, TPpToken* ppToken);
|
||||||
|
int characterLiteral(TPpToken* ppToken);
|
||||||
|
|
||||||
void push_include(TShader::Includer::IncludeResult* result)
|
void push_include(TShader::Includer::IncludeResult* result)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions
|
|
||||||
// are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
|
|
||||||
namespace glslang {
|
|
||||||
|
|
||||||
} // end namespace glslang
|
|
||||||
@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -101,9 +103,16 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
{
|
{
|
||||||
bool HasDecimalOrExponent = false;
|
bool HasDecimalOrExponent = false;
|
||||||
int isDouble = 0;
|
int isDouble = 0;
|
||||||
|
bool generateFloat16 = false;
|
||||||
|
bool acceptFloat16 = parseContext.intermediate.getSource() == EShSourceHlsl;
|
||||||
|
bool isFloat16 = false;
|
||||||
|
bool requireHF = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
int isFloat16 = 0;
|
if (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) {
|
||||||
bool enableFloat16 = parseContext.version >= 450 && parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float);
|
acceptFloat16 = true;
|
||||||
|
generateFloat16 = true;
|
||||||
|
requireHF = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const auto saveName = [&](int ch) {
|
const auto saveName = [&](int ch) {
|
||||||
@@ -117,6 +126,35 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
HasDecimalOrExponent = true;
|
HasDecimalOrExponent = true;
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
ch = getChar();
|
ch = getChar();
|
||||||
|
|
||||||
|
// 1.#INF or -1.#INF
|
||||||
|
if (ch == '#') {
|
||||||
|
if ((len < 2) ||
|
||||||
|
(len == 2 && ppToken->name[0] != '1') ||
|
||||||
|
(len == 3 && ppToken->name[1] != '1' && !(ppToken->name[0] == '-' || ppToken->name[0] == '+')) ||
|
||||||
|
(len > 3))
|
||||||
|
parseContext.ppError(ppToken->loc, "unexpected use of", "#", "");
|
||||||
|
else {
|
||||||
|
// we have 1.# or -1.# or +1.#, check for 'INF'
|
||||||
|
if ((ch = getChar()) != 'I' ||
|
||||||
|
(ch = getChar()) != 'N' ||
|
||||||
|
(ch = getChar()) != 'F')
|
||||||
|
parseContext.ppError(ppToken->loc, "expected 'INF'", "#", "");
|
||||||
|
else {
|
||||||
|
// we have [+-].#INF, and we are targeting IEEE 754, so wrap it up:
|
||||||
|
saveName('I');
|
||||||
|
saveName('N');
|
||||||
|
saveName('F');
|
||||||
|
ppToken->name[len] = '\0';
|
||||||
|
if (ppToken->name[0] == '-')
|
||||||
|
ppToken->i64val = 0xfff0000000000000; // -Infinity
|
||||||
|
else
|
||||||
|
ppToken->i64val = 0x7ff0000000000000; // +Infinity
|
||||||
|
return PpAtomConstFloat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (ch >= '0' && ch <= '9') {
|
while (ch >= '0' && ch <= '9') {
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
ch = getChar();
|
ch = getChar();
|
||||||
@@ -158,21 +196,27 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
saveName(ch2);
|
saveName(ch2);
|
||||||
isDouble = 1;
|
isDouble = 1;
|
||||||
}
|
}
|
||||||
|
} else if (acceptFloat16 && (ch == 'h' || ch == 'H')) {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
} else if (enableFloat16 && (ch == 'h' || ch == 'H')) {
|
if (generateFloat16)
|
||||||
parseContext.float16Check(ppToken->loc, "half floating-point suffix");
|
parseContext.float16Check(ppToken->loc, "half floating-point suffix");
|
||||||
|
#endif
|
||||||
if (!HasDecimalOrExponent)
|
if (!HasDecimalOrExponent)
|
||||||
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
||||||
int ch2 = getChar();
|
if (requireHF) {
|
||||||
if (ch2 != 'f' && ch2 != 'F') {
|
int ch2 = getChar();
|
||||||
ungetChar();
|
if (ch2 != 'f' && ch2 != 'F') {
|
||||||
ungetChar();
|
ungetChar();
|
||||||
|
ungetChar();
|
||||||
|
} else {
|
||||||
|
saveName(ch);
|
||||||
|
saveName(ch2);
|
||||||
|
isFloat16 = generateFloat16;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
saveName(ch2);
|
isFloat16 = generateFloat16;
|
||||||
isFloat16 = 1;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else if (ch == 'f' || ch == 'F') {
|
} else if (ch == 'f' || ch == 'F') {
|
||||||
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
||||||
if (! parseContext.relaxedErrors())
|
if (! parseContext.relaxedErrors())
|
||||||
@@ -197,14 +241,88 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
// Return the right token type
|
// Return the right token type
|
||||||
if (isDouble)
|
if (isDouble)
|
||||||
return PpAtomConstDouble;
|
return PpAtomConstDouble;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
else if (isFloat16)
|
else if (isFloat16)
|
||||||
return PpAtomConstFloat16;
|
return PpAtomConstFloat16;
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
return PpAtomConstFloat;
|
return PpAtomConstFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recognize a character literal.
|
||||||
|
//
|
||||||
|
// The first ' has already been accepted, read the rest, through the closing '.
|
||||||
|
//
|
||||||
|
// Always returns PpAtomConstInt.
|
||||||
|
//
|
||||||
|
int TPpContext::characterLiteral(TPpToken* ppToken)
|
||||||
|
{
|
||||||
|
ppToken->name[0] = 0;
|
||||||
|
ppToken->ival = 0;
|
||||||
|
|
||||||
|
if (parseContext.intermediate.getSource() != EShSourceHlsl) {
|
||||||
|
// illegal, except in macro definition, for which case we report the character
|
||||||
|
return '\'';
|
||||||
|
}
|
||||||
|
|
||||||
|
int ch = getChar();
|
||||||
|
switch (ch) {
|
||||||
|
case '\'':
|
||||||
|
// As empty sequence: ''
|
||||||
|
parseContext.ppError(ppToken->loc, "unexpected", "\'", "");
|
||||||
|
return PpAtomConstInt;
|
||||||
|
case '\\':
|
||||||
|
// As escape sequence: '\XXX'
|
||||||
|
switch (ch = getChar()) {
|
||||||
|
case 'a':
|
||||||
|
ppToken->ival = 7;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
ppToken->ival = 8;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
ppToken->ival = 9;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
ppToken->ival = 10;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
ppToken->ival = 11;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
ppToken->ival = 12;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
ppToken->ival = 13;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case '0':
|
||||||
|
parseContext.ppError(ppToken->loc, "octal and hex sequences not supported", "\\", "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// This catches '\'', '\"', '\?', etc.
|
||||||
|
// Also, things like '\C' mean the same thing as 'C'
|
||||||
|
// (after the above cases are filtered out).
|
||||||
|
ppToken->ival = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ppToken->ival = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ppToken->name[0] = (char)ppToken->ival;
|
||||||
|
ppToken->name[1] = '\0';
|
||||||
|
ch = getChar();
|
||||||
|
if (ch != '\'') {
|
||||||
|
parseContext.ppError(ppToken->loc, "expected", "\'", "");
|
||||||
|
// Look ahead for a closing '
|
||||||
|
do {
|
||||||
|
ch = getChar();
|
||||||
|
} while (ch != '\'' && ch != EndOfInput && ch != '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
return PpAtomConstInt;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scanner used to tokenize source stream.
|
// Scanner used to tokenize source stream.
|
||||||
//
|
//
|
||||||
@@ -216,6 +334,18 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
int ii = 0;
|
int ii = 0;
|
||||||
unsigned long long ival = 0;
|
unsigned long long ival = 0;
|
||||||
bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64);
|
bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool enableInt16 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16);
|
||||||
|
#endif
|
||||||
|
bool acceptHalf = pp->parseContext.intermediate.getSource() == EShSourceHlsl;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float))
|
||||||
|
acceptHalf = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto floatingPointChar = [&](int ch) { return ch == '.' || ch == 'e' || ch == 'E' ||
|
||||||
|
ch == 'f' || ch == 'F' ||
|
||||||
|
(acceptHalf && (ch == 'h' || ch == 'H')); };
|
||||||
|
|
||||||
ppToken->ival = 0;
|
ppToken->ival = 0;
|
||||||
ppToken->i64val = 0;
|
ppToken->i64val = 0;
|
||||||
@@ -279,6 +409,9 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
|
|
||||||
bool isUnsigned = false;
|
bool isUnsigned = false;
|
||||||
bool isInt64 = false;
|
bool isInt64 = false;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool isInt16 = false;
|
||||||
|
#endif
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
ch = getch();
|
ch = getch();
|
||||||
if ((ch >= '0' && ch <= '9') ||
|
if ((ch >= '0' && ch <= '9') ||
|
||||||
@@ -287,7 +420,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
|
|
||||||
ival = 0;
|
ival = 0;
|
||||||
do {
|
do {
|
||||||
if (ival <= 0x0fffffff || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
|
if (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (ch >= '0' && ch <= '9') {
|
||||||
ii = ch - '0';
|
ii = ch - '0';
|
||||||
@@ -326,11 +459,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (enableInt16) {
|
||||||
|
int nextCh = getch();
|
||||||
|
if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)nextCh;
|
||||||
|
isInt16 = true;
|
||||||
|
} else
|
||||||
|
ungetch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (enableInt16 && (ch == 's' || ch == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)ch;
|
||||||
|
isInt16 = true;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
ppToken->name[len] = '\0';
|
ppToken->name[len] = '\0';
|
||||||
@@ -338,6 +488,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
if (isInt64) {
|
if (isInt64) {
|
||||||
ppToken->i64val = ival;
|
ppToken->i64val = ival;
|
||||||
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (isInt16) {
|
||||||
|
ppToken->ival = (int)ival;
|
||||||
|
return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ppToken->ival = (int)ival;
|
ppToken->ival = (int)ival;
|
||||||
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
||||||
@@ -347,6 +502,9 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
|
|
||||||
bool isUnsigned = false;
|
bool isUnsigned = false;
|
||||||
bool isInt64 = false;
|
bool isInt64 = false;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool isInt16 = false;
|
||||||
|
#endif
|
||||||
bool octalOverflow = false;
|
bool octalOverflow = false;
|
||||||
bool nonOctal = false;
|
bool nonOctal = false;
|
||||||
ival = 0;
|
ival = 0;
|
||||||
@@ -359,7 +517,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
if (ival <= 0x1fffffff || (enableInt64 && ival <= 0x1fffffffffffffffull)) {
|
if (ival <= 0x1fffffffu || (enableInt64 && ival <= 0x1fffffffffffffffull)) {
|
||||||
ii = ch - '0';
|
ii = ch - '0';
|
||||||
ival = (ival << 3) | ii;
|
ival = (ival << 3) | ii;
|
||||||
} else
|
} else
|
||||||
@@ -380,7 +538,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ch = getch();
|
ch = getch();
|
||||||
} while (ch >= '0' && ch <= '9');
|
} while (ch >= '0' && ch <= '9');
|
||||||
}
|
}
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F')
|
if (floatingPointChar(ch))
|
||||||
return pp->lFloatConst(len, ch, ppToken);
|
return pp->lFloatConst(len, ch, ppToken);
|
||||||
|
|
||||||
// wasn't a float, so must be octal...
|
// wasn't a float, so must be octal...
|
||||||
@@ -401,11 +559,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (enableInt16) {
|
||||||
|
int nextCh = getch();
|
||||||
|
if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)nextCh;
|
||||||
|
isInt16 = true;
|
||||||
|
} else
|
||||||
|
ungetch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (enableInt16 && (ch == 's' || ch == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)ch;
|
||||||
|
isInt16 = true;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
ppToken->name[len] = '\0';
|
ppToken->name[len] = '\0';
|
||||||
@@ -416,6 +591,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
if (isInt64) {
|
if (isInt64) {
|
||||||
ppToken->i64val = ival;
|
ppToken->i64val = ival;
|
||||||
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (isInt16) {
|
||||||
|
ppToken->ival = (int)ival;
|
||||||
|
return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ppToken->ival = (int)ival;
|
ppToken->ival = (int)ival;
|
||||||
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
||||||
@@ -435,13 +615,16 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
ch = getch();
|
ch = getch();
|
||||||
} while (ch >= '0' && ch <= '9');
|
} while (ch >= '0' && ch <= '9');
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F') {
|
if (floatingPointChar(ch))
|
||||||
return pp->lFloatConst(len, ch, ppToken);
|
return pp->lFloatConst(len, ch, ppToken);
|
||||||
} else {
|
else {
|
||||||
// Finish handling signed and unsigned integers
|
// Finish handling signed and unsigned integers
|
||||||
int numericLen = len;
|
int numericLen = len;
|
||||||
bool isUnsigned = false;
|
bool isUnsigned = false;
|
||||||
bool isInt64 = false;
|
bool isInt64 = false;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool isInt16 = false;
|
||||||
|
#endif
|
||||||
if (ch == 'u' || ch == 'U') {
|
if (ch == 'u' || ch == 'U') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
@@ -456,10 +639,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (enableInt16) {
|
||||||
|
int nextCh = getch();
|
||||||
|
if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)nextCh;
|
||||||
|
isInt16 = true;
|
||||||
|
} else
|
||||||
|
ungetch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
} else if (enableInt64 && (ch == 'l' || ch == 'L')) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (enableInt16 && (ch == 's' || ch == 'S')) {
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)ch;
|
||||||
|
isInt16 = true;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
@@ -469,10 +670,22 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt;
|
const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt;
|
||||||
const unsigned long long oneTenthMaxInt64 = 0xFFFFFFFFFFFFFFFFull / 10;
|
const unsigned long long oneTenthMaxInt64 = 0xFFFFFFFFFFFFFFFFull / 10;
|
||||||
const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64;
|
const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
const unsigned short oneTenthMaxInt16 = 0xFFFFu / 10;
|
||||||
|
const unsigned short remainderMaxInt16 = 0xFFFFu - 10 * oneTenthMaxInt16;
|
||||||
|
#endif
|
||||||
for (int i = 0; i < numericLen; i++) {
|
for (int i = 0; i < numericLen; i++) {
|
||||||
ch = ppToken->name[i] - '0';
|
ch = ppToken->name[i] - '0';
|
||||||
if ((enableInt64 == false && ((ival > oneTenthMaxInt) || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt))) ||
|
bool overflow = false;
|
||||||
(enableInt64 && ((ival > oneTenthMaxInt64) || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64)))) {
|
if (isInt64)
|
||||||
|
overflow = (ival > oneTenthMaxInt64 || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64));
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
else if (isInt16)
|
||||||
|
overflow = (ival > oneTenthMaxInt16 || (ival == oneTenthMaxInt16 && (unsigned short)ch > remainderMaxInt16));
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
overflow = (ival > oneTenthMaxInt || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt));
|
||||||
|
if (overflow) {
|
||||||
pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", "");
|
pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", "");
|
||||||
ival = 0xFFFFFFFFFFFFFFFFull;
|
ival = 0xFFFFFFFFFFFFFFFFull;
|
||||||
break;
|
break;
|
||||||
@@ -483,6 +696,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
if (isInt64) {
|
if (isInt64) {
|
||||||
ppToken->i64val = ival;
|
ppToken->i64val = ival;
|
||||||
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (isInt16) {
|
||||||
|
ppToken->ival = (int)ival;
|
||||||
|
return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ppToken->ival = (int)ival;
|
ppToken->ival = (int)ival;
|
||||||
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
|
||||||
@@ -652,6 +870,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '\'':
|
||||||
|
return pp->characterLiteral(ppToken);
|
||||||
case '"':
|
case '"':
|
||||||
// TODO: If this gets enhanced to handle escape sequences, or
|
// TODO: If this gets enhanced to handle escape sequences, or
|
||||||
// anything that is different than what #include needs, then
|
// anything that is different than what #include needs, then
|
||||||
@@ -671,6 +891,12 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
|
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
|
||||||
}
|
}
|
||||||
return PpAtomConstString;
|
return PpAtomConstString;
|
||||||
|
case ':':
|
||||||
|
ch = getch();
|
||||||
|
if (ch == ':')
|
||||||
|
return PpAtomColonColon;
|
||||||
|
ungetch();
|
||||||
|
return ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = getch();
|
ch = getch();
|
||||||
@@ -724,6 +950,10 @@ int TPpContext::tokenize(TPpToken& ppToken)
|
|||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case PpAtomConstFloat16:
|
case PpAtomConstFloat16:
|
||||||
@@ -773,6 +1003,7 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
|||||||
token = scanToken(&pastedPpToken);
|
token = scanToken(&pastedPpToken);
|
||||||
assert(token == PpAtomPaste);
|
assert(token == PpAtomPaste);
|
||||||
|
|
||||||
|
// This covers end of macro expansion
|
||||||
if (endOfReplacementList()) {
|
if (endOfReplacementList()) {
|
||||||
parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
|
parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
|
||||||
break;
|
break;
|
||||||
@@ -781,6 +1012,12 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
|||||||
// get the token after the ##
|
// get the token after the ##
|
||||||
token = scanToken(&pastedPpToken);
|
token = scanToken(&pastedPpToken);
|
||||||
|
|
||||||
|
// This covers end of argument expansion
|
||||||
|
if (token == tMarkerInput::marker) {
|
||||||
|
parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// get the token text
|
// get the token text
|
||||||
switch (resultToken) {
|
switch (resultToken) {
|
||||||
case PpAtomIdentifier:
|
case PpAtomIdentifier:
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions
|
|
||||||
// are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
@@ -80,8 +80,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// For recording and playing back the stream of tokens in a macro definition.
|
// For recording and playing back the stream of tokens in a macro definition.
|
||||||
//
|
//
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
|
||||||
#define snprintf sprintf_s
|
#define snprintf sprintf_s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -96,9 +98,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
// push onto back of stream
|
// push onto back of stream
|
||||||
void TPpContext::TokenStream::putSubtoken(int subtoken)
|
void TPpContext::TokenStream::putSubtoken(char subtoken)
|
||||||
{
|
{
|
||||||
assert((subtoken & ~0xff) == 0);
|
|
||||||
data.push_back(static_cast<unsigned char>(subtoken));
|
data.push_back(static_cast<unsigned char>(subtoken));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +126,8 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
|
|||||||
const char* s;
|
const char* s;
|
||||||
char* str = NULL;
|
char* str = NULL;
|
||||||
|
|
||||||
putSubtoken(token);
|
assert((token & ~0xff) == 0);
|
||||||
|
putSubtoken(static_cast<char>(token));
|
||||||
|
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case PpAtomIdentifier:
|
case PpAtomIdentifier:
|
||||||
@@ -139,6 +141,10 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
|
|||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
@@ -188,6 +194,10 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
|
|||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
len = 0;
|
len = 0;
|
||||||
ch = getSubtoken();
|
ch = getSubtoken();
|
||||||
while (ch != 0 && ch != EndOfInput) {
|
while (ch != 0 && ch != EndOfInput) {
|
||||||
@@ -215,6 +225,9 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
|
|||||||
ppToken->dval = atof(ppToken->name);
|
ppToken->dval = atof(ppToken->name);
|
||||||
break;
|
break;
|
||||||
case PpAtomConstInt:
|
case PpAtomConstInt:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
#endif
|
||||||
if (len > 0 && ppToken->name[0] == '0') {
|
if (len > 0 && ppToken->name[0] == '0') {
|
||||||
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
|
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
|
||||||
ppToken->ival = (int)strtol(ppToken->name, 0, 16);
|
ppToken->ival = (int)strtol(ppToken->name, 0, 16);
|
||||||
@@ -224,6 +237,9 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
|
|||||||
ppToken->ival = atoi(ppToken->name);
|
ppToken->ival = atoi(ppToken->name);
|
||||||
break;
|
break;
|
||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
if (len > 0 && ppToken->name[0] == '0') {
|
if (len > 0 && ppToken->name[0] == '0') {
|
||||||
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
|
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
|
||||||
ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
|
ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ enum EFixedAtoms {
|
|||||||
PpAtomDecrement,
|
PpAtomDecrement,
|
||||||
PpAtomIncrement,
|
PpAtomIncrement,
|
||||||
|
|
||||||
|
PpAtomColonColon,
|
||||||
|
|
||||||
PpAtomPaste,
|
PpAtomPaste,
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
@@ -125,11 +127,13 @@ enum EFixedAtoms {
|
|||||||
PpAtomConstUint,
|
PpAtomConstUint,
|
||||||
PpAtomConstInt64,
|
PpAtomConstInt64,
|
||||||
PpAtomConstUint64,
|
PpAtomConstUint64,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
PpAtomConstInt16,
|
||||||
|
PpAtomConstUint16,
|
||||||
|
#endif
|
||||||
PpAtomConstFloat,
|
PpAtomConstFloat,
|
||||||
PpAtomConstDouble,
|
PpAtomConstDouble,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
PpAtomConstFloat16,
|
PpAtomConstFloat16,
|
||||||
#endif
|
|
||||||
PpAtomConstString,
|
PpAtomConstString,
|
||||||
|
|
||||||
// Identifiers
|
// Identifiers
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
// propagate 'noContraction' qualifier.
|
// propagate 'noContraction' qualifier.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|||||||
@@ -696,14 +696,40 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
|
|||||||
// Implement TReflection methods.
|
// Implement TReflection methods.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Track any required attribute reflection, such as compute shader numthreads.
|
||||||
|
//
|
||||||
|
void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediate& intermediate)
|
||||||
|
{
|
||||||
|
if (stage == EShLangCompute) {
|
||||||
|
// Remember thread dimensions
|
||||||
|
for (int dim=0; dim<3; ++dim)
|
||||||
|
localSize[dim] = intermediate.getLocalSize(dim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build counter block index associations for buffers
|
||||||
|
void TReflection::buildCounterIndices()
|
||||||
|
{
|
||||||
|
// search for ones that have counters
|
||||||
|
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
||||||
|
const TString counterName(indexToUniformBlock[i].name + "@count");
|
||||||
|
const int index = getIndex(counterName);
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
indexToUniformBlock[i].counterIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Merge live symbols from 'intermediate' into the existing reflection database.
|
// Merge live symbols from 'intermediate' into the existing reflection database.
|
||||||
//
|
//
|
||||||
// Returns false if the input is too malformed to do this.
|
// Returns false if the input is too malformed to do this.
|
||||||
bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
|
bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
buildAttributeReflection(stage, intermediate);
|
||||||
|
|
||||||
TReflectionTraverser it(intermediate, *this);
|
TReflectionTraverser it(intermediate, *this);
|
||||||
|
|
||||||
// put the entry point on the list of functions to process
|
// put the entry point on the list of functions to process
|
||||||
@@ -716,6 +742,8 @@ bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
|
|||||||
function->traverse(&it);
|
function->traverse(&it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildCounterIndices();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,6 +764,16 @@ void TReflection::dump()
|
|||||||
indexToAttribute[i].dump();
|
indexToAttribute[i].dump();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
if (getLocalSize(0) > 1) {
|
||||||
|
static const char* axis[] = { "X", "Y", "Z" };
|
||||||
|
|
||||||
|
for (int dim=0; dim<3; ++dim)
|
||||||
|
if (getLocalSize(dim) > 1)
|
||||||
|
printf("Local size %s: %d\n", axis[dim], getLocalSize(dim));
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
// printf("Live names\n");
|
// printf("Live names\n");
|
||||||
// for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
|
// for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
|
||||||
// printf("%s: %d\n", it->first.c_str(), it->second);
|
// printf("%s: %d\n", it->first.c_str(), it->second);
|
||||||
|
|||||||
@@ -57,11 +57,16 @@ class TObjectReflection {
|
|||||||
public:
|
public:
|
||||||
TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
||||||
name(pName), offset(pOffset),
|
name(pName), offset(pOffset),
|
||||||
glDefineType(pGLDefineType), size(pSize), index(pIndex), type(pType.clone()) { }
|
glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { }
|
||||||
|
|
||||||
void dump() const {
|
void dump() const {
|
||||||
printf("%s: offset %d, type %x, size %d, index %d, binding %d\n",
|
printf("%s: offset %d, type %x, size %d, index %d, binding %d",
|
||||||
name.c_str(), offset, glDefineType, size, index, getBinding() );
|
name.c_str(), offset, glDefineType, size, index, getBinding() );
|
||||||
|
|
||||||
|
if (counterIndex != -1)
|
||||||
|
printf(", counter %d", counterIndex);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const TType* const getType() const { return type; }
|
const TType* const getType() const { return type; }
|
||||||
@@ -71,6 +76,7 @@ public:
|
|||||||
int glDefineType;
|
int glDefineType;
|
||||||
int size; // data size in bytes for a block, array size for a (non-block) object that's an array
|
int size; // data size in bytes for a block, array size for a (non-block) object that's an array
|
||||||
int index;
|
int index;
|
||||||
|
int counterIndex;
|
||||||
|
|
||||||
static TObjectReflection badReflection() { return TObjectReflection(); }
|
static TObjectReflection badReflection() { return TObjectReflection(); }
|
||||||
|
|
||||||
@@ -89,7 +95,12 @@ protected:
|
|||||||
// The full reflection database
|
// The full reflection database
|
||||||
class TReflection {
|
class TReflection {
|
||||||
public:
|
public:
|
||||||
TReflection() : badReflection(TObjectReflection::badReflection()) { }
|
TReflection() : badReflection(TObjectReflection::badReflection())
|
||||||
|
{
|
||||||
|
for (int dim=0; dim<3; ++dim)
|
||||||
|
localSize[dim] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~TReflection() {}
|
virtual ~TReflection() {}
|
||||||
|
|
||||||
// grow the reflection stage by stage
|
// grow the reflection stage by stage
|
||||||
@@ -135,11 +146,20 @@ public:
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see getIndex(const char*)
|
||||||
|
int getIndex(const TString& name) const { return getIndex(name.c_str()); }
|
||||||
|
|
||||||
|
// Thread local size
|
||||||
|
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class glslang::TReflectionTraverser;
|
friend class glslang::TReflectionTraverser;
|
||||||
|
|
||||||
|
void buildCounterIndices();
|
||||||
|
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
||||||
|
|
||||||
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
||||||
typedef std::map<TString, int> TNameToIndex;
|
typedef std::map<TString, int> TNameToIndex;
|
||||||
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
||||||
@@ -149,6 +169,8 @@ protected:
|
|||||||
TMapIndexToReflection indexToUniform;
|
TMapIndexToReflection indexToUniform;
|
||||||
TMapIndexToReflection indexToUniformBlock;
|
TMapIndexToReflection indexToUniformBlock;
|
||||||
TMapIndexToReflection indexToAttribute;
|
TMapIndexToReflection indexToAttribute;
|
||||||
|
|
||||||
|
unsigned int localSize[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -184,20 +184,6 @@ void ReleaseGlobalLock()
|
|||||||
pthread_mutex_unlock(&gMutex);
|
pthread_mutex_unlock(&gMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: non-windows: if we need these on linux, flesh them out
|
|
||||||
void* OS_CreateThread(TThreadEntrypoint /*entry*/)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_WaitForAllThreads(void* /*threads*/, int /*numThreads*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Sleep(int /*milliseconds*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_DumpMemoryCounters()
|
void OS_DumpMemoryCounters()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,21 +131,6 @@ unsigned int __stdcall EnterGenericThread (void* entry)
|
|||||||
return ((TThreadEntrypoint)entry)(0);
|
return ((TThreadEntrypoint)entry)(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OS_CreateThread(TThreadEntrypoint entry)
|
|
||||||
{
|
|
||||||
return (void*)_beginthreadex(0, 0, EnterGenericThread, (void*)entry, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_WaitForAllThreads(void* threads, int numThreads)
|
|
||||||
{
|
|
||||||
WaitForMultipleObjects(numThreads, (HANDLE*)threads, true, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Sleep(int milliseconds)
|
|
||||||
{
|
|
||||||
Sleep(milliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#define DUMP_COUNTERS
|
//#define DUMP_COUNTERS
|
||||||
|
|
||||||
void OS_DumpMemoryCounters()
|
void OS_DumpMemoryCounters()
|
||||||
|
|||||||
@@ -53,11 +53,8 @@ void GetGlobalLock();
|
|||||||
void ReleaseGlobalLock();
|
void ReleaseGlobalLock();
|
||||||
|
|
||||||
typedef unsigned int (*TThreadEntrypoint)(void*);
|
typedef unsigned int (*TThreadEntrypoint)(void*);
|
||||||
void* OS_CreateThread(TThreadEntrypoint);
|
|
||||||
void OS_WaitForAllThreads(void* threads, int numThreads);
|
|
||||||
|
|
||||||
void OS_CleanupThreadData(void);
|
void OS_CleanupThreadData(void);
|
||||||
void OS_Sleep(int milliseconds);
|
|
||||||
|
|
||||||
void OS_DumpMemoryCounters();
|
void OS_DumpMemoryCounters();
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "../MachineIndependent/Versions.h"
|
#include "../MachineIndependent/Versions.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define C_DECL __cdecl
|
#define C_DECL __cdecl
|
||||||
@@ -133,6 +134,14 @@ typedef enum {
|
|||||||
EShOptFull, // Optimizations that will take more time
|
EShOptFull, // Optimizations that will take more time
|
||||||
} EShOptimizationLevel;
|
} EShOptimizationLevel;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Texture and Sampler transformation mode.
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
||||||
|
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
||||||
|
} EShTextureSamplerTransformMode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message choices for what errors and warnings are given.
|
// Message choices for what errors and warnings are given.
|
||||||
//
|
//
|
||||||
@@ -147,6 +156,8 @@ enum EShMessages {
|
|||||||
EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
|
EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
|
||||||
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
|
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
|
||||||
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
|
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
|
||||||
|
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
|
||||||
|
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -203,14 +214,6 @@ SH_IMPORT_EXPORT int ShCompile(
|
|||||||
EShMessages messages = EShMsgDefault // warnings and errors
|
EShMessages messages = EShMsgDefault // warnings and errors
|
||||||
);
|
);
|
||||||
|
|
||||||
SH_IMPORT_EXPORT int ShLink(
|
|
||||||
const ShHandle, // linker object
|
|
||||||
const ShHandle h[], // compiler objects to link together
|
|
||||||
const int numHandles,
|
|
||||||
ShHandle uniformMap, // updated with new uniforms
|
|
||||||
short int** uniformsAccessed, // returned with indexes of uniforms accessed
|
|
||||||
int* numUniformsAccessed);
|
|
||||||
|
|
||||||
SH_IMPORT_EXPORT int ShLinkExt(
|
SH_IMPORT_EXPORT int ShLinkExt(
|
||||||
const ShHandle, // linker object
|
const ShHandle, // linker object
|
||||||
const ShHandle h[], // compiler objects to link together
|
const ShHandle h[], // compiler objects to link together
|
||||||
@@ -310,9 +313,16 @@ public:
|
|||||||
void setShiftTextureBinding(unsigned int base);
|
void setShiftTextureBinding(unsigned int base);
|
||||||
void setShiftImageBinding(unsigned int base);
|
void setShiftImageBinding(unsigned int base);
|
||||||
void setShiftUboBinding(unsigned int base);
|
void setShiftUboBinding(unsigned int base);
|
||||||
|
void setShiftUavBinding(unsigned int base);
|
||||||
|
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
||||||
|
void setShiftSsboBinding(unsigned int base);
|
||||||
|
void setResourceSetBinding(const std::vector<std::string>& base);
|
||||||
void setAutoMapBindings(bool map);
|
void setAutoMapBindings(bool map);
|
||||||
|
void setAutoMapLocations(bool map);
|
||||||
|
void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
void setFlattenUniformArrays(bool flatten);
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
void setNoStorageFormat(bool useUnknownFormat);
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||||
|
|
||||||
// Interface to #include handlers.
|
// Interface to #include handlers.
|
||||||
//
|
//
|
||||||
@@ -397,6 +407,9 @@ public:
|
|||||||
virtual void releaseInclude(IncludeResult*) override { }
|
virtual void releaseInclude(IncludeResult*) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
|
bool forwardCompatible, EShMessages, Includer&);
|
||||||
|
|
||||||
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
{
|
{
|
||||||
@@ -404,12 +417,18 @@ public:
|
|||||||
return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
|
return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
|
||||||
bool forwardCompatible, EShMessages, Includer&);
|
|
||||||
|
|
||||||
// Equivalent to parse() without a default profile and without forcing defaults.
|
// Equivalent to parse() without a default profile and without forcing defaults.
|
||||||
// Provided for backwards compatibility.
|
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
|
||||||
bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages);
|
{
|
||||||
|
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
|
||||||
|
Includer& includer)
|
||||||
|
{
|
||||||
|
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
|
||||||
|
}
|
||||||
|
|
||||||
bool preprocess(const TBuiltInResource* builtInResources,
|
bool preprocess(const TBuiltInResource* builtInResources,
|
||||||
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages message, std::string* outputString,
|
bool forwardCompatible, EShMessages message, std::string* outputString,
|
||||||
@@ -459,10 +478,19 @@ class TIoMapper;
|
|||||||
// and resolveSet are invoked to resolve the binding and descriptor
|
// and resolveSet are invoked to resolve the binding and descriptor
|
||||||
// set index respectively.
|
// set index respectively.
|
||||||
// Invocations happen in a particular order:
|
// Invocations happen in a particular order:
|
||||||
// 1) var with binding and set already defined
|
// 1) all shader inputs
|
||||||
// 2) var with binding but no set defined
|
// 2) all shader outputs
|
||||||
// 3) var with set but no binding defined
|
// 3) all uniforms with binding and set already defined
|
||||||
// 4) var with no binding and no set defined
|
// 4) all uniforms with binding but no set defined
|
||||||
|
// 5) all uniforms with set but no binding defined
|
||||||
|
// 6) all uniforms with no binding and no set defined
|
||||||
|
//
|
||||||
|
// mapIO will use this resolver in two phases. The first
|
||||||
|
// phase is a notification phase, calling the corresponging
|
||||||
|
// notifiy callbacks, this phase ends with a call to endNotifications.
|
||||||
|
// Phase two starts directly after the call to endNotifications
|
||||||
|
// and calls all other callbacks to validate and to get the
|
||||||
|
// bindings, sets, locations, component and color indices.
|
||||||
//
|
//
|
||||||
// NOTE: that still limit checks are applied to bindings and sets
|
// NOTE: that still limit checks are applied to bindings and sets
|
||||||
// and may result in an error.
|
// and may result in an error.
|
||||||
@@ -471,15 +499,33 @@ class TIoMapResolver
|
|||||||
public:
|
public:
|
||||||
virtual ~TIoMapResolver() {}
|
virtual ~TIoMapResolver() {}
|
||||||
|
|
||||||
// Should return true if the resulting/current binding would be ok.
|
// Should return true if the resulting/current binding would be okay.
|
||||||
// Basic idea is to do aliasing binding checks with this.
|
// Basic idea is to do aliasing binding checks with this.
|
||||||
virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
// Should return a value >= 0 if the current binding should be overridden.
|
// Should return a value >= 0 if the current binding should be overridden.
|
||||||
// Return -1 if the current binding (including no binding) should be kept.
|
// Return -1 if the current binding (including no binding) should be kept.
|
||||||
virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
// Should return a value >= 0 if the current set should be overriden.
|
// Should return a value >= 0 if the current set should be overridden.
|
||||||
// Return -1 if the current set (including no set) should be kept.
|
// Return -1 if the current set (including no set) should be kept.
|
||||||
virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Should return true if the resulting/current setup would be okay.
|
||||||
|
// Basic idea is to do aliasing checks and reject invalid semantic names.
|
||||||
|
virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Should return a value >= 0 if the current location should be overridden.
|
||||||
|
// Return -1 if the current location (including no location) should be kept.
|
||||||
|
virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Should return a value >= 0 if the current component index should be overridden.
|
||||||
|
// Return -1 if the current component index (including no index) should be kept.
|
||||||
|
virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Should return a value >= 0 if the current color index should be overridden.
|
||||||
|
// Return -1 if the current color index (including no index) should be kept.
|
||||||
|
virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Notification of a uniform variable
|
||||||
|
virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Notification of a in or out variable
|
||||||
|
virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
||||||
|
// Called by mapIO when it has finished the notify pass
|
||||||
|
virtual void endNotifications() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make one TProgram per set of shaders that will get linked together. Add all
|
// Make one TProgram per set of shaders that will get linked together. Add all
|
||||||
@@ -510,10 +556,12 @@ public:
|
|||||||
int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
|
int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
|
||||||
int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices()
|
int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices()
|
||||||
int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
|
int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
|
||||||
|
int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter.
|
||||||
int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
|
int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
|
||||||
int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
|
int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
|
||||||
int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
|
int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
|
||||||
int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
|
int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
|
||||||
|
unsigned getLocalSize(int dim) const; // return dim'th local size
|
||||||
const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib()
|
const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib()
|
||||||
int getAttributeType(int index) const; // can be used for glGetActiveAttrib()
|
int getAttributeType(int index) const; // can be used for glGetActiveAttrib()
|
||||||
const TType* getUniformTType(int index) const; // returns a TType*
|
const TType* getUniformTType(int index) const; // returns a TType*
|
||||||
|
|||||||
Reference in New Issue
Block a user