summaryrefslogtreecommitdiff
path: root/thirdparty/glslang/SPIRV
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/glslang/SPIRV')
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.EXT.h2
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.KHR.h2
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.NV.h3
-rw-r--r--thirdparty/glslang/SPIRV/GlslangToSpv.cpp548
-rw-r--r--thirdparty/glslang/SPIRV/SPVRemapper.cpp3
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.cpp124
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.h4
-rw-r--r--thirdparty/glslang/SPIRV/SpvPostProcess.cpp32
-rw-r--r--thirdparty/glslang/SPIRV/SpvTools.cpp3
-rw-r--r--thirdparty/glslang/SPIRV/doc.cpp41
-rw-r--r--thirdparty/glslang/SPIRV/spirv.hpp115
11 files changed, 791 insertions, 86 deletions
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
index 20b9e54014..f48f1304d6 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
@@ -36,6 +36,8 @@ static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fu
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
+static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add";
+static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max";
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
#endif // #ifndef GLSLextEXT_H
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h b/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
index 9610c6eeee..5eb3e94482 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
@@ -50,5 +50,7 @@ static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_t
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
+static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
+static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
#endif // #ifndef GLSLextKHR_H
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.NV.h b/thirdparty/glslang/SPIRV/GLSL.ext.NV.h
index 50146da104..93c98bf626 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.NV.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.NV.h
@@ -69,6 +69,9 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
//SPV_NV_raytracing
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
+//SPV_NV_ray_tracing_motion_blur
+const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
+
//SPV_NV_shading_rate
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
diff --git a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
index 1adebef878..c323bcdb09 100644
--- a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
+++ b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
@@ -160,6 +160,7 @@ protected:
spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const;
spv::StorageClass TranslateStorageClass(const glslang::TType&);
+ void TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>&, std::vector<unsigned>&) const;
void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType);
spv::Id getSampledType(const glslang::TSampler&);
@@ -178,6 +179,7 @@ protected:
spv::Id accessChainLoad(const glslang::TType& type);
void accessChainStore(const glslang::TType& type, spv::Id rvalue);
void multiTypeStore(const glslang::TType&, spv::Id rValue);
+ spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId);
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
@@ -255,17 +257,17 @@ protected:
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
spv::Id stdBuiltins;
spv::Id nonSemanticDebugPrintf;
- std::unordered_map<const char*, spv::Id> extBuiltinMap;
+ std::unordered_map<std::string, spv::Id> extBuiltinMap;
- std::unordered_map<int, spv::Id> symbolValues;
- std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues,
+ std::unordered_map<long long, spv::Id> symbolValues;
+ std::unordered_set<long long> rValueParameters; // set of formal function parameters passed as rValues,
// rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap;
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
// for mapping glslang block indices to spv indices (e.g., due to hidden members):
- std::unordered_map<int, std::vector<int>> memberRemapper;
+ std::unordered_map<long long, std::vector<int>> memberRemapper;
// for mapping glslang symbol struct to symbol Id
- std::unordered_map<const glslang::TTypeList*, int> glslangTypeToIdMap;
+ std::unordered_map<const glslang::TTypeList*, long long> glslangTypeToIdMap;
std::stack<bool> breakForLoop; // false means break for switch
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
// Map pointee types for EbtReference to their forward pointers
@@ -380,6 +382,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
+ case glslang::EvqShared: return spv::DecorationBlock;
#ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::DecorationBlock;
case glslang::EvqPayloadIn: return spv::DecorationBlock;
@@ -436,6 +439,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
break;
case glslang::EbtBlock:
switch (type.getQualifier().storage) {
+ case glslang::EvqShared:
case glslang::EvqUniform:
case glslang::EvqBuffer:
switch (type.getQualifier().layoutPacking) {
@@ -1029,6 +1033,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInIncomingRayFlagsKHR;
case glslang::EbvGeometryIndex:
return spv::BuiltInRayGeometryIndexKHR;
+ case glslang::EbvCurrentRayTimeNV:
+ builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+ builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+ return spv::BuiltInCurrentRayTimeNV;
// barycentrics
case glslang::EbvBaryCoordNV:
@@ -1247,6 +1255,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
{
if (type.getBasicType() == glslang::EbtRayQuery)
return spv::StorageClassPrivate;
+#ifndef GLSLANG_WEB
+ if (type.getQualifier().isSpirvByReference())
+ return spv::StorageClassFunction;
+#endif
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput())
@@ -1278,6 +1290,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
return spv::StorageClassUniformConstant;
}
+ if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) {
+ builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout);
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR);
+ return spv::StorageClassWorkgroup;
+ }
+
switch (type.getQualifier().storage) {
case glslang::EvqGlobal: return spv::StorageClassPrivate;
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
@@ -1289,6 +1307,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR;
case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
+ case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
#endif
default:
assert(0);
@@ -1298,6 +1317,52 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
return spv::StorageClassFunction;
}
+// Translate glslang constants to SPIR-V literals
+void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>& constants,
+ std::vector<unsigned>& literals) const
+{
+ for (auto constant : constants) {
+ if (constant->getBasicType() == glslang::EbtFloat) {
+ float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
+ unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
+ literals.push_back(literal);
+ } else if (constant->getBasicType() == glslang::EbtInt) {
+ unsigned literal = constant->getConstArray()[0].getIConst();
+ literals.push_back(literal);
+ } else if (constant->getBasicType() == glslang::EbtUint) {
+ unsigned literal = constant->getConstArray()[0].getUConst();
+ literals.push_back(literal);
+ } else if (constant->getBasicType() == glslang::EbtBool) {
+ unsigned literal = constant->getConstArray()[0].getBConst();
+ literals.push_back(literal);
+ } else if (constant->getBasicType() == glslang::EbtString) {
+ auto str = constant->getConstArray()[0].getSConst()->c_str();
+ unsigned literal = 0;
+ char* literalPtr = reinterpret_cast<char*>(&literal);
+ unsigned charCount = 0;
+ char ch = 0;
+ do {
+ ch = *(str++);
+ *(literalPtr++) = ch;
+ ++charCount;
+ if (charCount == 4) {
+ literals.push_back(literal);
+ literalPtr = reinterpret_cast<char*>(&literal);
+ charCount = 0;
+ }
+ } while (ch != 0);
+
+ // Partial literal is padded with 0
+ if (charCount > 0) {
+ for (; charCount < 4; ++charCount)
+ *(literalPtr++) = 0;
+ literals.push_back(literal);
+ }
+ } else
+ assert(0); // Unexpected type
+ }
+}
+
// Add capabilities pertaining to how an array is indexed.
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
const glslang::TType& indexType)
@@ -1485,7 +1550,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
- builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
}
if (glslangIntermediate->usingVulkanMemoryModel()) {
@@ -1518,6 +1583,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
}
+#ifndef GLSLANG_WEB
+ if (glslangIntermediate->getSubgroupUniformControlFlow()) {
+ builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
+ }
+#endif
+
unsigned int mode;
switch (glslangIntermediate->getStage()) {
case EShLangVertex:
@@ -1543,15 +1615,16 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
}
- if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
+ if (glslangIntermediate->isDepthReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
#ifndef GLSLANG_WEB
switch(glslangIntermediate->getDepth()) {
- case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
- case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
- default: mode = spv::ExecutionModeMax; break;
+ case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
+ case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
+ case glslang::EldUnchanged: mode = spv::ExecutionModeDepthUnchanged; break;
+ default: mode = spv::ExecutionModeMax; break;
}
if (mode != spv::ExecutionModeMax)
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
@@ -1719,6 +1792,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
default:
break;
}
+
+#ifndef GLSLANG_WEB
+ //
+ // Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
+ //
+ if (glslangIntermediate->hasSpirvRequirement()) {
+ const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement();
+
+ // Add SPIR-V extension requirement
+ for (auto& extension : spirvRequirement.extensions)
+ builder.addExtension(extension.c_str());
+
+ // Add SPIR-V capability requirement
+ for (auto capability : spirvRequirement.capabilities)
+ builder.addCapability(static_cast<spv::Capability>(capability));
+ }
+
+ //
+ // Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics)
+ //
+ if (glslangIntermediate->hasSpirvExecutionMode()) {
+ const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode();
+
+ // Add spirv_execution_mode
+ for (auto& mode : spirvExecutionMode.modes) {
+ if (!mode.second.empty()) {
+ std::vector<unsigned> literals;
+ TranslateLiterals(mode.second, literals);
+ builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first), literals);
+ } else
+ builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first));
+ }
+
+ // Add spirv_execution_mode_id
+ for (auto& modeId : spirvExecutionMode.modeIds) {
+ std::vector<spv::Id> operandIds;
+ assert(!modeId.second.empty());
+ for (auto extraOperand : modeId.second) {
+ int nextConst = 0;
+ spv::Id operandId = createSpvConstantFromConstUnionArray(
+ extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
+ operandIds.push_back(operandId);
+ }
+ builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
+ }
+ }
+#endif
}
// Finish creating SPV, after the traversal is complete.
@@ -1986,7 +2106,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
{
// This may be, e.g., an anonymous block-member selection, which generally need
// index remapping due to hidden members in anonymous blocks.
- int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()];
+ long long glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()];
if (memberRemapper.find(glslangId) != memberRemapper.end()) {
std::vector<int>& remapper = memberRemapper[glslangId];
assert(remapper.size() > 0);
@@ -2116,6 +2236,49 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
}
}
+spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type,
+ spv::Id nominalTypeId,
+ spv::Id loadedId)
+{
+ if (builder.isScalarType(nominalTypeId)) {
+ // Conversion for bool
+ spv::Id boolType = builder.makeBoolType();
+ if (nominalTypeId != boolType)
+ return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
+ } else if (builder.isVectorType(nominalTypeId)) {
+ // Conversion for bvec
+ int vecSize = builder.getNumTypeComponents(nominalTypeId);
+ spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
+ if (nominalTypeId != bvecType)
+ loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
+ makeSmearedConstant(builder.makeUintConstant(0), vecSize));
+ } else if (builder.isArrayType(nominalTypeId)) {
+ // Conversion for bool array
+ spv::Id boolArrayTypeId = convertGlslangToSpvType(type);
+ if (nominalTypeId != boolArrayTypeId)
+ {
+ // Use OpCopyLogical from SPIR-V 1.4 if available.
+ if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
+ return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId);
+
+ glslang::TType glslangElementType(type, 0);
+ spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId);
+ std::vector<spv::Id> constituents;
+ for (int index = 0; index < type.getOuterArraySize(); ++index) {
+ // get the element
+ spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index);
+
+ // recursively convert it
+ spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue);
+ constituents.push_back(elementConvertedValue);
+ }
+ return builder.createCompositeConstruct(boolArrayTypeId, constituents);
+ }
+ }
+
+ return loadedId;
+}
+
// Figure out what, if any, type changes are needed when accessing a specific built-in.
// Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
// Also see comment for 'forceType', regarding tracking SPIR-V-required types.
@@ -2292,7 +2455,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
node->getOp() == glslang::EOpAtomicCounterDecrement ||
node->getOp() == glslang::EOpAtomicCounter ||
- node->getOp() == glslang::EOpInterpolateAtCentroid ||
+ (node->getOp() == glslang::EOpInterpolateAtCentroid &&
+ glslangIntermediate->getSource() != glslang::EShSourceHlsl) ||
node->getOp() == glslang::EOpRayQueryProceed ||
node->getOp() == glslang::EOpRayQueryGetRayTMin ||
node->getOp() == glslang::EOpRayQueryGetRayFlags ||
@@ -2300,10 +2464,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
node->getOp() == glslang::EOpRayQueryTerminate ||
- node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
+ node->getOp() == glslang::EOpRayQueryConfirmIntersection ||
+ (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) {
operand = builder.accessChainGetLValue(); // Special case l-value operands
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
+ } else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
+ // Will be translated to a literal value, make a placeholder here
+ operand = spv::NoResult;
} else
#endif
{
@@ -2324,6 +2492,38 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
node->getOperand()->getBasicType(), lvalueCoherentFlags);
+#ifndef GLSLANG_WEB
+ // it could be attached to a SPIR-V intruction
+ if (!result) {
+ if (node->getOp() == glslang::EOpSpirvInst) {
+ const auto& spirvInst = node->getSpirvInstruction();
+ if (spirvInst.set == "") {
+ spv::IdImmediate idImmOp = {true, operand};
+ if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
+ // Translate the constant to a literal value
+ std::vector<unsigned> literals;
+ glslang::TVector<const glslang::TIntermConstantUnion*> constants;
+ constants.push_back(operandNode->getAsConstantUnion());
+ TranslateLiterals(constants, literals);
+ idImmOp = {false, literals[0]};
+ }
+
+ if (node->getBasicType() == glslang::EbtVoid)
+ builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), {idImmOp});
+ else
+ result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), {idImmOp});
+ } else {
+ result = builder.createBuiltinCall(
+ resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
+ spirvInst.id, {operand});
+ }
+
+ if (node->getBasicType() == glslang::EbtVoid)
+ return false; // done with this node
+ }
+ }
+#endif
+
if (result) {
if (invertedType) {
result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
@@ -2775,6 +2975,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break;
case glslang::EOpAtomicAdd:
+ case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
case glslang::EOpAtomicAnd:
@@ -2821,6 +3022,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpIgnoreIntersectionNV:
case glslang::EOpTerminateRayNV:
case glslang::EOpTraceNV:
+ case glslang::EOpTraceRayMotionNV:
case glslang::EOpTraceKHR:
case glslang::EOpExecuteCallableNV:
case glslang::EOpExecuteCallableKHR:
@@ -2946,6 +3148,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break;
case glslang::EOpAtomicAdd:
+ case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
case glslang::EOpAtomicAnd:
@@ -2966,7 +3169,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpInterpolateAtOffset:
case glslang::EOpInterpolateAtVertex:
if (arg == 0) {
- lvalue = true;
+ // If GLSL, use the address of the interpolant argument.
+ // If HLSL, use an internal version of OpInterolates that takes
+ // the rvalue of the interpolant. A fixup pass in spirv-opt
+ // legalization will remove the OpLoad and convert to an lvalue.
+ // Had to do this because legalization will only propagate a
+ // builtin into an rvalue.
+ lvalue = glslangIntermediate->getSource() != glslang::EShSourceHlsl;
// Does it need a swizzle inversion? If so, evaluation is inverted;
// operate first on the swizzle base, then apply the swizzle.
@@ -3012,6 +3221,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
if (arg == 1)
lvalue = true;
break;
+ case glslang::EOpSpirvInst:
+ if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference())
+ lvalue = true;
+ break;
#endif
default:
break;
@@ -3109,15 +3322,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
} else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
+ (arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) ||
(arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
- const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1;
- const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1;
+ const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1);
+ const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0;
+
const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst();
auto itNode = locationToSymbol[set].find(location);
visitSymbol(itNode->second);
spv::Id symId = getSymbolId(itNode->second);
operands.push_back(symId);
- } else {
+#ifndef GLSLANG_WEB
+ } else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
+ // Will be translated to a literal value, make a placeholder here
+ operands.push_back(spv::NoResult);
+#endif
+ } else {
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
}
}
@@ -3155,8 +3375,38 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
#endif
if (atomic) {
// Handle all atomics
- result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(),
+ glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore)
+ ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
+ result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
lvalueCoherentFlags);
+#ifndef GLSLANG_WEB
+ } else if (node->getOp() == glslang::EOpSpirvInst) {
+ const auto& spirvInst = node->getSpirvInstruction();
+ if (spirvInst.set == "") {
+ std::vector<spv::IdImmediate> idImmOps;
+ for (int i = 0; i < glslangOperands.size(); ++i) {
+ if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
+ // Translate the constant to a literal value
+ std::vector<unsigned> literals;
+ glslang::TVector<const glslang::TIntermConstantUnion*> constants;
+ constants.push_back(glslangOperands[i]->getAsConstantUnion());
+ TranslateLiterals(constants, literals);
+ idImmOps.push_back({false, literals[0]});
+ } else
+ idImmOps.push_back({true, operands[i]});
+ }
+
+ if (node->getBasicType() == glslang::EbtVoid)
+ builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), idImmOps);
+ else
+ result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), idImmOps);
+ } else {
+ result = builder.createBuiltinCall(
+ resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
+ spirvInst.id, operands);
+ }
+ noReturnValue = node->getBasicType() == glslang::EbtVoid;
+#endif
} else if (node->getOp() == glslang::EOpDebugPrintf) {
if (!nonSemanticDebugPrintf) {
nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
@@ -3437,6 +3687,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
{
+#ifndef GLSLANG_WEB
+ if (node->getQualifier().isSpirvLiteral())
+ return; // Translated to a literal value, skip further processing
+#endif
+
int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
@@ -3623,6 +3878,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
break;
#endif
default:
+ if (storageClass == spv::StorageClassWorkgroup &&
+ node->getType().getBasicType() == glslang::EbtBlock) {
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
+ break;
+ }
if (node->getType().contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16);
if (node->getType().contains16BitInt())
@@ -3641,6 +3901,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
} else if (storageClass == spv::StorageClassStorageBuffer) {
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
+ } else if (storageClass == spv::StorageClassWorkgroup &&
+ node->getType().getBasicType() == glslang::EbtBlock) {
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
} else {
builder.addCapability(spv::CapabilityInt8);
}
@@ -3652,13 +3915,14 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
spv::Id initializer = spv::NoResult;
- if (node->getType().getQualifier().storage == glslang::EvqUniform &&
- !node->getConstArray().empty()) {
- int nextConst = 0;
- initializer = createSpvConstantFromConstUnionArray(node->getType(),
- node->getConstArray(),
- nextConst,
- false /* specConst */);
+ if (node->getType().getQualifier().storage == glslang::EvqUniform && !node->getConstArray().empty()) {
+ int nextConst = 0;
+ initializer = createSpvConstantFromConstUnionArray(node->getType(),
+ node->getConstArray(),
+ nextConst,
+ false /* specConst */);
+ } else if (node->getType().getQualifier().isNullInit()) {
+ initializer = builder.makeNullConstant(spvType);
}
return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
@@ -3876,6 +4140,77 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case glslang::EbtString:
// no type used for OpString
return 0;
+#ifndef GLSLANG_WEB
+ case glslang::EbtSpirvType: {
+ // GL_EXT_spirv_intrinsics
+ const auto& spirvType = type.getSpirvType();
+ const auto& spirvInst = spirvType.spirvInst;
+
+ std::vector<spv::Id> operands;
+ for (const auto& typeParam : spirvType.typeParams) {
+ if (typeParam.isConstant) {
+ // Constant expression
+ if (typeParam.constant->isLiteral()) {
+ if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
+ float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
+ unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
+ operands.push_back(literal);
+ } else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
+ unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
+ operands.push_back(literal);
+ } else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
+ unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
+ operands.push_back(literal);
+ } else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
+ unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
+ operands.push_back(literal);
+ } else if (typeParam.constant->getBasicType() == glslang::EbtString) {
+ auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
+ unsigned literal = 0;
+ char* literalPtr = reinterpret_cast<char*>(&literal);
+ unsigned charCount = 0;
+ char ch = 0;
+ do {
+ ch = *(str++);
+ *(literalPtr++) = ch;
+ ++charCount;
+ if (charCount == 4) {
+ operands.push_back(literal);
+ literalPtr = reinterpret_cast<char*>(&literal);
+ charCount = 0;
+ }
+ } while (ch != 0);
+
+ // Partial literal is padded with 0
+ if (charCount > 0) {
+ for (; charCount < 4; ++charCount)
+ *(literalPtr++) = 0;
+ operands.push_back(literal);
+ }
+ } else
+ assert(0); // Unexpected type
+ } else {
+ int nextConst = 0;
+ spv::Id constant = createSpvConstantFromConstUnionArray(
+ typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
+ operands.push_back(constant);
+ }
+ } else {
+ // Type specifier
+ spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
+ operands.push_back(typeId);
+ }
+ }
+
+ if (spirvInst.set == "")
+ spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
+ else {
+ spvType = builder.createBuiltinCall(
+ spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
+ }
+ break;
+ }
+#endif
default:
assert(0);
break;
@@ -4072,7 +4407,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
{
// Name and decorate the non-hidden members
int offset = -1;
- int locationOffset = 0; // for use within the members of this struct
bool memberLocationInvalid = type.isArrayOfArrays() ||
(type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false));
for (int i = 0; i < (int)glslangMembers->size(); i++) {
@@ -4130,10 +4464,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
if (!memberLocationInvalid && memberQualifier.hasLocation())
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
- if (qualifier.hasLocation()) // track for upcoming inheritance
- locationOffset += glslangIntermediate->computeTypeLocationSize(
- glslangMember, glslangIntermediate->getStage());
-
// component, XFB, others
if (glslangMember.getQualifier().hasComponent())
builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
@@ -4189,6 +4519,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
}
+
+ //
+ // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
+ //
+ if (glslangMember.getQualifier().hasSprivDecorate()) {
+ const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
+
+ // Add spirv_decorate
+ for (auto& decorate : spirvDecorate.decorates) {
+ if (!decorate.second.empty()) {
+ std::vector<unsigned> literals;
+ TranslateLiterals(decorate.second, literals);
+ builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
+ }
+ else
+ builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
+ }
+
+ // spirv_decorate_id not applied to members
+ assert(spirvDecorate.decorateIds.empty());
+
+ // Add spirv_decorate_string
+ for (auto& decorateString : spirvDecorate.decorateStrings) {
+ std::vector<const char*> strings;
+ assert(!decorateString.second.empty());
+ for (auto extraOperand : decorateString.second) {
+ const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
+ strings.push_back(string);
+ }
+ builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
+ }
+ }
#endif
}
@@ -4207,6 +4569,8 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
if (specNode != nullptr) {
builder.clearAccessChain();
+ SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
+ spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
specNode->traverse(this);
return accessChainLoad(specNode->getAsTyped()->getType());
}
@@ -4242,19 +4606,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
// Need to convert to abstract types when necessary
if (type.getBasicType() == glslang::EbtBool) {
- if (builder.isScalarType(nominalTypeId)) {
- // Conversion for bool
- spv::Id boolType = builder.makeBoolType();
- if (nominalTypeId != boolType)
- loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
- } else if (builder.isVectorType(nominalTypeId)) {
- // Conversion for bvec
- int vecSize = builder.getNumTypeComponents(nominalTypeId);
- spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
- if (nominalTypeId != bvecType)
- loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
- makeSmearedConstant(builder.makeUintConstant(0), vecSize));
- }
+ loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
}
return loadedId;
@@ -4406,6 +4758,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
// has to be a uniform or buffer block or task in/out blocks
if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer &&
+ type.getQualifier().storage != glslang::EvqShared &&
!type.getQualifier().isTaskMemory())
return glslang::ElpNone;
@@ -4575,6 +4928,9 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
return paramType.getBasicType() == glslang::EbtBlock;
return paramType.containsOpaque() || // sampler, etc.
+#ifndef GLSLANG_WEB
+ paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
+#endif
(paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
}
@@ -4968,7 +5324,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
int components = node->getType().getVectorSize();
- if (node->getOp() == glslang::EOpTextureFetch) {
+ if (node->getOp() == glslang::EOpImageLoad ||
+ node->getOp() == glslang::EOpImageLoadLod ||
+ node->getOp() == glslang::EOpTextureFetch ||
+ node->getOp() == glslang::EOpTextureFetchOffset) {
// These must produce 4 components, per SPIR-V spec. We'll add a conversion constructor if needed.
// This will only happen through the HLSL path for operator[], so we do not have to handle e.g.
// the EOpTexture/Proj/Lod/etc family. It would be harmless to do so, but would need more logic
@@ -5530,7 +5889,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
++lValueCount;
} else {
// process r-value, which involves a copy for a type mismatch
- if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
+ if (function->getParamType(a) != builder.getTypeId(rValues[rValueCount]) ||
TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
{
spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
@@ -6813,9 +7172,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
break;
case glslang::EOpConvPtrToUvec2:
case glslang::EOpConvUvec2ToPtr:
- if (builder.isVector(operand))
- builder.promoteIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer,
- spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
convOp = spv::OpBitcast;
break;
#endif
@@ -6864,29 +7220,58 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
case glslang::EOpImageAtomicAdd:
case glslang::EOpAtomicCounterAdd:
opCode = spv::OpAtomicIAdd;
- if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+ if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
opCode = spv::OpAtomicFAddEXT;
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
- if (typeProxy == glslang::EbtFloat)
+ if (typeProxy == glslang::EbtFloat16) {
+ builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
+ builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
+ } else if (typeProxy == glslang::EbtFloat) {
builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
- else
+ } else {
builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+ }
}
break;
+ case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicCounterSubtract:
opCode = spv::OpAtomicISub;
break;
case glslang::EOpAtomicMin:
case glslang::EOpImageAtomicMin:
case glslang::EOpAtomicCounterMin:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
- spv::OpAtomicUMin : spv::OpAtomicSMin;
+ if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+ opCode = spv::OpAtomicFMinEXT;
+ builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+ if (typeProxy == glslang::EbtFloat16)
+ builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+ else if (typeProxy == glslang::EbtFloat)
+ builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+ else
+ builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+ } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
+ opCode = spv::OpAtomicUMin;
+ } else {
+ opCode = spv::OpAtomicSMin;
+ }
break;
case glslang::EOpAtomicMax:
case glslang::EOpImageAtomicMax:
case glslang::EOpAtomicCounterMax:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
- spv::OpAtomicUMax : spv::OpAtomicSMax;
+ if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+ opCode = spv::OpAtomicFMaxEXT;
+ builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+ if (typeProxy == glslang::EbtFloat16)
+ builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+ else if (typeProxy == glslang::EbtFloat)
+ builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+ else
+ builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+ } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
+ opCode = spv::OpAtomicUMax;
+ } else {
+ opCode = spv::OpAtomicSMax;
+ }
break;
case glslang::EOpAtomicAnd:
case glslang::EOpImageAtomicAnd:
@@ -6995,6 +7380,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
+ if (builder.getConstantScalar(scopeId) == spv::ScopeQueueFamily) {
+ builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
+ }
+
if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
}
@@ -7940,6 +8329,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
case glslang::EOpTraceNV:
builder.createNoResultOp(spv::OpTraceNV, operands);
return 0;
+ case glslang::EOpTraceRayMotionNV:
+ builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+ builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+ builder.createNoResultOp(spv::OpTraceRayMotionNV, operands);
+ return 0;
case glslang::EOpTraceKHR:
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0;
@@ -7991,7 +8385,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
break;
case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
- typeId = builder.makeIntType(32);
+ typeId = builder.makeUintType(32);
opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
break;
case glslang::EOpRayQueryGetIntersectionGeometryIndex:
@@ -8424,6 +8818,48 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
}
+
+ //
+ // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
+ //
+ if (symbol->getType().getQualifier().hasSprivDecorate()) {
+ const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
+
+ // Add spirv_decorate
+ for (auto& decorate : spirvDecorate.decorates) {
+ if (!decorate.second.empty()) {
+ std::vector<unsigned> literals;
+ TranslateLiterals(decorate.second, literals);
+ builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
+ }
+ else
+ builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
+ }
+
+ // Add spirv_decorate_id
+ for (auto& decorateId : spirvDecorate.decorateIds) {
+ std::vector<spv::Id> operandIds;
+ assert(!decorateId.second.empty());
+ for (auto extraOperand : decorateId.second) {
+ int nextConst = 0;
+ spv::Id operandId = createSpvConstantFromConstUnionArray(
+ extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
+ operandIds.push_back(operandId);
+ }
+ builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
+ }
+
+ // Add spirv_decorate_string
+ for (auto& decorateString : spirvDecorate.decorateStrings) {
+ std::vector<const char*> strings;
+ assert(!decorateString.second.empty());
+ for (auto extraOperand : decorateString.second) {
+ const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
+ strings.push_back(string);
+ }
+ builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
+ }
+ }
#endif
return id;
diff --git a/thirdparty/glslang/SPIRV/SPVRemapper.cpp b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
index 56d7f431a7..56d6d5d4a5 100644
--- a/thirdparty/glslang/SPIRV/SPVRemapper.cpp
+++ b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
@@ -544,6 +544,9 @@ namespace spv {
// Extended instructions: currently, assume everything is an ID.
// TODO: add whatever data we need for exceptions to that
if (opCode == spv::OpExtInst) {
+
+ idFn(asId(word)); // Instruction set is an ID that also needs to be mapped
+
word += 2; // instruction set, and instruction from set
numOperands -= 2;
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.cpp b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
index c8fbcc450e..e83306ebcb 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.cpp
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
@@ -743,6 +743,26 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
}
}
+// Figure out the final resulting type of the access chain.
+Id Builder::getResultingAccessChainType() const
+{
+ assert(accessChain.base != NoResult);
+ Id typeId = getTypeId(accessChain.base);
+
+ assert(isPointerType(typeId));
+ typeId = getContainedTypeId(typeId);
+
+ for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
+ if (isStructType(typeId)) {
+ assert(isConstantScalar(accessChain.indexChain[i]));
+ typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i]));
+ } else
+ typeId = getContainedTypeId(typeId, accessChain.indexChain[i]);
+ }
+
+ return typeId;
+}
+
// Return the immediately contained type of a given composite type.
Id Builder::getContainedTypeId(Id typeId) const
{
@@ -869,6 +889,30 @@ bool Builder::isSpecConstantOpCode(Op opcode) const
}
}
+Id Builder::makeNullConstant(Id typeId)
+{
+ Instruction* constant;
+
+ // See if we already made it.
+ Id existing = NoResult;
+ for (int i = 0; i < (int)nullConstants.size(); ++i) {
+ constant = nullConstants[i];
+ if (constant->getTypeId() == typeId)
+ existing = constant->getResultId();
+ }
+
+ if (existing != NoResult)
+ return existing;
+
+ // Make it
+ Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull);
+ constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
+ nullConstants.push_back(c);
+ module.mapInstruction(c);
+
+ return c->getResultId();
+}
+
Id Builder::makeBoolConstant(bool b, bool specConstant)
{
Id typeId = makeBoolType();
@@ -1561,16 +1605,7 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
{
// Figure out the final resulting type.
- spv::Id typeId = getTypeId(base);
- assert(isPointerType(typeId) && offsets.size() > 0);
- typeId = getContainedTypeId(typeId);
- for (int i = 0; i < (int)offsets.size(); ++i) {
- if (isStructType(typeId)) {
- assert(isConstantScalar(offsets[i]));
- typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
- } else
- typeId = getContainedTypeId(typeId, offsets[i]);
- }
+ Id typeId = getResultingAccessChainType();
typeId = makePointer(storageClass, typeId);
// Make the instruction
@@ -2519,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
int row = 0;
int col = 0;
- for (int arg = 0; arg < (int)sources.size(); ++arg) {
+ for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) {
Id argComp = sources[arg];
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
if (getNumComponents(sources[arg]) > 1) {
@@ -2531,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
row = 0;
col++;
}
+ if (col == numCols) {
+ // If more components are provided than fit the matrix, discard the rest.
+ break;
+ }
}
}
}
@@ -2766,28 +2805,59 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce
assert(accessChain.isRValue == false);
transferAccessChainSwizzle(true);
- Id base = collapseAccessChain();
- addDecoration(base, nonUniform);
- Id source = rvalue;
+ // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores.
+ if (accessChain.swizzle.size() > 0 &&
+ getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() &&
+ accessChain.component == NoResult) {
+ for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
+ accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
+ accessChain.instr = NoResult;
- // dynamic component should be gone
- assert(accessChain.component == NoResult);
+ Id base = collapseAccessChain();
+ addDecoration(base, nonUniform);
- // If swizzle still exists, it is out-of-order or not full, we must load the target vector,
- // extract and insert elements to perform writeMask and/or swizzle.
- if (accessChain.swizzle.size() > 0) {
- Id tempBaseId = createLoad(base, spv::NoPrecision);
- source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
- }
+ accessChain.indexChain.pop_back();
+ accessChain.instr = NoResult;
+
+ // dynamic component should be gone
+ assert(accessChain.component == NoResult);
+
+ Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i);
+
+ // take LSB of alignment
+ alignment = alignment & ~(alignment & (alignment-1));
+ if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
+ memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+ }
- // take LSB of alignment
- alignment = alignment & ~(alignment & (alignment-1));
- if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
- memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+ createStore(source, base, memoryAccess, scope, alignment);
+ }
}
+ else {
+ Id base = collapseAccessChain();
+ addDecoration(base, nonUniform);
+
+ Id source = rvalue;
+
+ // dynamic component should be gone
+ assert(accessChain.component == NoResult);
+
+ // If swizzle still exists, it may be out-of-order, we must load the target vector,
+ // extract and insert elements to perform writeMask and/or swizzle.
+ if (accessChain.swizzle.size() > 0) {
+ Id tempBaseId = createLoad(base, spv::NoPrecision);
+ source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
+ }
- createStore(source, base, memoryAccess, scope, alignment);
+ // take LSB of alignment
+ alignment = alignment & ~(alignment & (alignment-1));
+ if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
+ memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+ }
+
+ createStore(source, base, memoryAccess, scope, alignment);
+ }
}
// Comments in header
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.h b/thirdparty/glslang/SPIRV/SpvBuilder.h
index 911ea58b12..251b9ee823 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.h
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.h
@@ -202,6 +202,7 @@ public:
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
ImageFormat getImageTypeFormat(Id typeId) const
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
+ Id getResultingAccessChainType() const;
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
@@ -293,6 +294,7 @@ public:
}
// For making new constants (will return old constant if the requested one was already made).
+ Id makeNullConstant(Id typeId);
Id makeBoolConstant(bool b, bool specConstant = false);
Id makeInt8Constant(int i, bool specConstant = false)
{ return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
@@ -838,6 +840,8 @@ public:
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
// map type opcodes to type instructions
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
+ // list of OpConstantNull instructions
+ std::vector<Instruction*> nullConstants;
// stack of switches
std::stack<Block*> switchMerges;
diff --git a/thirdparty/glslang/SPIRV/SpvPostProcess.cpp b/thirdparty/glslang/SPIRV/SpvPostProcess.cpp
index d40174d172..23d7b5a461 100644
--- a/thirdparty/glslang/SPIRV/SpvPostProcess.cpp
+++ b/thirdparty/glslang/SPIRV/SpvPostProcess.cpp
@@ -436,6 +436,38 @@ void Builder::postProcessFeatures() {
}
}
}
+
+ // If any Vulkan memory model-specific functionality is used, update the
+ // OpMemoryModel to match.
+ if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
+ memoryModel = spv::MemoryModelVulkanKHR;
+ addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
+ }
+
+ // Add Aliased decoration if there's more than one Workgroup Block variable.
+ if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
+ assert(entryPoints.size() == 1);
+ auto &ep = entryPoints[0];
+
+ std::vector<Id> workgroup_variables;
+ for (int i = 0; i < (int)ep->getNumOperands(); i++) {
+ if (!ep->isIdOperand(i))
+ continue;
+
+ const Id id = ep->getIdOperand(i);
+ const Instruction *instr = module.getInstruction(id);
+ if (instr->getOpCode() != spv::OpVariable)
+ continue;
+
+ if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
+ workgroup_variables.push_back(id);
+ }
+
+ if (workgroup_variables.size() > 1) {
+ for (size_t i = 0; i < workgroup_variables.size(); i++)
+ addDecoration(workgroup_variables[i], spv::DecorationAliased);
+ }
+ }
}
#endif
diff --git a/thirdparty/glslang/SPIRV/SpvTools.cpp b/thirdparty/glslang/SPIRV/SpvTools.cpp
index 16d051a9b2..8acf9b139a 100644
--- a/thirdparty/glslang/SPIRV/SpvTools.cpp
+++ b/thirdparty/glslang/SPIRV/SpvTools.cpp
@@ -153,6 +153,8 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
spv_validator_options options = spvValidatorOptionsCreate();
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
+ spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
+ spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidateWithOptions(context, options, &binary, &diagnostic);
// report
@@ -205,6 +207,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
+ optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
if (options->optimizeSize) {
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
}
diff --git a/thirdparty/glslang/SPIRV/doc.cpp b/thirdparty/glslang/SPIRV/doc.cpp
index 5327f2212d..dbdf7077a6 100644
--- a/thirdparty/glslang/SPIRV/doc.cpp
+++ b/thirdparty/glslang/SPIRV/doc.cpp
@@ -188,6 +188,7 @@ const char* ExecutionModeString(int mode)
case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
+ case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
@@ -425,6 +426,7 @@ const char* BuiltInString(int builtIn)
case BuiltInSMCountNV: return "SMCountNV";
case BuiltInWarpIDNV: return "WarpIDNV";
case BuiltInSMIDNV: return "SMIDNV";
+ case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV";
default: return "Bad";
}
@@ -915,8 +917,10 @@ const char* CapabilityString(int info)
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
case CapabilityRayTracingNV: return "RayTracingNV";
+ case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
case CapabilityRayTracingKHR: return "RayTracingKHR";
case CapabilityRayQueryKHR: return "RayQueryKHR";
+ case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
@@ -964,8 +968,16 @@ const char* CapabilityString(int info)
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
+ case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT";
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
+ case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT";
+ case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT";
+ case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT";
+
+ case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
+ case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
+ case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
default: return "Bad";
}
@@ -1346,6 +1358,8 @@ const char* OpcodeString(int op)
case 4432: return "OpSubgroupReadInvocationKHR";
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
+ case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
+ case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD";
@@ -1370,6 +1384,7 @@ const char* OpcodeString(int op)
case OpTerminateRayNV: return "OpTerminateRayNV";
case OpTerminateRayKHR: return "OpTerminateRayKHR";
case OpTraceNV: return "OpTraceNV";
+ case OpTraceRayMotionNV: return "OpTraceRayMotionNV";
case OpTraceRayKHR: return "OpTraceRayKHR";
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
case OpExecuteCallableNV: return "OpExecuteCallableNV";
@@ -2336,6 +2351,16 @@ void Parameterize()
InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'");
+ InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'");
+ InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+ InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'");
+
+ InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'");
+ InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+ InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'");
+
InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
@@ -2714,7 +2739,7 @@ void Parameterize()
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
- InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'");
+ InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'");
InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
@@ -2790,6 +2815,20 @@ void Parameterize()
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
InstructionDesc[OpTraceNV].setResultAndType(false, false);
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'");
+ InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false);
+
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
diff --git a/thirdparty/glslang/SPIRV/spirv.hpp b/thirdparty/glslang/SPIRV/spirv.hpp
index 43dd2aaeec..e0fe24980d 100644
--- a/thirdparty/glslang/SPIRV/spirv.hpp
+++ b/thirdparty/glslang/SPIRV/spirv.hpp
@@ -150,6 +150,7 @@ enum ExecutionMode {
ExecutionModeSubgroupsPerWorkgroupId = 37,
ExecutionModeLocalSizeId = 38,
ExecutionModeLocalSizeHintId = 39,
+ ExecutionModeSubgroupUniformControlFlowKHR = 4421,
ExecutionModePostDepthCoverage = 4446,
ExecutionModeDenormPreserve = 4459,
ExecutionModeDenormFlushToZero = 4460,
@@ -168,10 +169,16 @@ enum ExecutionMode {
ExecutionModeSampleInterlockUnorderedEXT = 5369,
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
+ ExecutionModeSharedLocalMemorySizeINTEL = 5618,
+ ExecutionModeRoundingModeRTPINTEL = 5620,
+ ExecutionModeRoundingModeRTNINTEL = 5621,
+ ExecutionModeFloatingPointModeALTINTEL = 5622,
+ ExecutionModeFloatingPointModeIEEEINTEL = 5623,
ExecutionModeMaxWorkgroupSizeINTEL = 5893,
ExecutionModeMaxWorkDimINTEL = 5894,
ExecutionModeNoGlobalOffsetINTEL = 5895,
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
+ ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
ExecutionModeMax = 0x7fffffff,
};
@@ -204,6 +211,8 @@ enum StorageClass {
StorageClassPhysicalStorageBuffer = 5349,
StorageClassPhysicalStorageBufferEXT = 5349,
StorageClassCodeSectionINTEL = 5605,
+ StorageClassDeviceOnlyINTEL = 5936,
+ StorageClassHostOnlyINTEL = 5937,
StorageClassMax = 0x7fffffff,
};
@@ -374,6 +383,8 @@ enum FPFastMathModeShift {
FPFastMathModeNSZShift = 2,
FPFastMathModeAllowRecipShift = 3,
FPFastMathModeFastShift = 4,
+ FPFastMathModeAllowContractFastINTELShift = 16,
+ FPFastMathModeAllowReassocINTELShift = 17,
FPFastMathModeMax = 0x7fffffff,
};
@@ -384,6 +395,8 @@ enum FPFastMathModeMask {
FPFastMathModeNSZMask = 0x00000004,
FPFastMathModeAllowRecipMask = 0x00000008,
FPFastMathModeFastMask = 0x00000010,
+ FPFastMathModeAllowContractFastINTELMask = 0x00010000,
+ FPFastMathModeAllowReassocINTELMask = 0x00020000,
};
enum FPRoundingMode {
@@ -397,6 +410,7 @@ enum FPRoundingMode {
enum LinkageType {
LinkageTypeExport = 0,
LinkageTypeImport = 1,
+ LinkageTypeLinkOnceODR = 2,
LinkageTypeMax = 0x7fffffff,
};
@@ -484,12 +498,22 @@ enum Decoration {
DecorationRestrictPointerEXT = 5355,
DecorationAliasedPointer = 5356,
DecorationAliasedPointerEXT = 5356,
+ DecorationSIMTCallINTEL = 5599,
DecorationReferencedIndirectlyINTEL = 5602,
+ DecorationClobberINTEL = 5607,
+ DecorationSideEffectsINTEL = 5608,
+ DecorationVectorComputeVariableINTEL = 5624,
+ DecorationFuncParamIOKindINTEL = 5625,
+ DecorationVectorComputeFunctionINTEL = 5626,
+ DecorationStackCallINTEL = 5627,
+ DecorationGlobalVariableOffsetINTEL = 5628,
DecorationCounterBuffer = 5634,
DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635,
DecorationUserSemantic = 5635,
DecorationUserTypeGOOGLE = 5636,
+ DecorationFunctionRoundingModeINTEL = 5822,
+ DecorationFunctionDenormModeINTEL = 5823,
DecorationRegisterINTEL = 5825,
DecorationMemoryINTEL = 5826,
DecorationNumbanksINTEL = 5827,
@@ -502,6 +526,17 @@ enum Decoration {
DecorationMergeINTEL = 5834,
DecorationBankBitsINTEL = 5835,
DecorationForcePow2DepthINTEL = 5836,
+ DecorationBurstCoalesceINTEL = 5899,
+ DecorationCacheSizeINTEL = 5900,
+ DecorationDontStaticallyCoalesceINTEL = 5901,
+ DecorationPrefetchINTEL = 5902,
+ DecorationStallEnableINTEL = 5905,
+ DecorationFuseLoopsInFunctionINTEL = 5907,
+ DecorationBufferLocationINTEL = 5921,
+ DecorationIOPipeStorageINTEL = 5944,
+ DecorationFunctionFloatingPointModeINTEL = 6080,
+ DecorationSingleElementVectorINTEL = 6085,
+ DecorationVectorComputeCallableFunctionINTEL = 6087,
DecorationMax = 0x7fffffff,
};
@@ -617,6 +652,7 @@ enum BuiltIn {
BuiltInHitTNV = 5332,
BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
+ BuiltInCurrentRayTimeNV = 5334,
BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352,
@@ -656,6 +692,7 @@ enum LoopControlShift {
LoopControlLoopCoalesceINTELShift = 20,
LoopControlMaxInterleavingINTELShift = 21,
LoopControlSpeculatedIterationsINTELShift = 22,
+ LoopControlNoFusionINTELShift = 23,
LoopControlMax = 0x7fffffff,
};
@@ -677,6 +714,7 @@ enum LoopControlMask {
LoopControlLoopCoalesceINTELMask = 0x00100000,
LoopControlMaxInterleavingINTELMask = 0x00200000,
LoopControlSpeculatedIterationsINTELMask = 0x00400000,
+ LoopControlNoFusionINTELMask = 0x00800000,
};
enum FunctionControlShift {
@@ -876,6 +914,9 @@ enum Capability {
CapabilityFragmentShadingRateKHR = 4422,
CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427,
+ CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,
+ CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
+ CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
CapabilitySubgroupVoteKHR = 4431,
CapabilityStorageBuffer16BitAccess = 4433,
CapabilityStorageUniformBufferBlock16 = 4433,
@@ -948,6 +989,7 @@ enum Capability {
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilityRayTracingNV = 5340,
+ CapabilityRayTracingMotionBlurNV = 5341,
CapabilityVulkanMemoryModel = 5345,
CapabilityVulkanMemoryModelKHR = 5345,
CapabilityVulkanMemoryModelDeviceScope = 5346,
@@ -966,21 +1008,42 @@ enum Capability {
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
+ CapabilityRoundToInfinityINTEL = 5582,
+ CapabilityFloatingPointModeINTEL = 5583,
CapabilityIntegerFunctions2INTEL = 5584,
CapabilityFunctionPointersINTEL = 5603,
CapabilityIndirectReferencesINTEL = 5604,
+ CapabilityAsmINTEL = 5606,
+ CapabilityAtomicFloat32MinMaxEXT = 5612,
+ CapabilityAtomicFloat64MinMaxEXT = 5613,
+ CapabilityAtomicFloat16MinMaxEXT = 5616,
+ CapabilityVectorComputeINTEL = 5617,
+ CapabilityVectorAnyINTEL = 5619,
+ CapabilityExpectAssumeKHR = 5629,
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
+ CapabilityVariableLengthArrayINTEL = 5817,
+ CapabilityFunctionFloatControlINTEL = 5821,
CapabilityFPGAMemoryAttributesINTEL = 5824,
+ CapabilityFPFastMathModeINTEL = 5837,
+ CapabilityArbitraryPrecisionIntegersINTEL = 5844,
CapabilityUnstructuredLoopControlsINTEL = 5886,
CapabilityFPGALoopControlsINTEL = 5888,
CapabilityKernelAttributesINTEL = 5892,
CapabilityFPGAKernelAttributesINTEL = 5897,
+ CapabilityFPGAMemoryAccessesINTEL = 5898,
+ CapabilityFPGAClusterAttributesINTEL = 5904,
+ CapabilityLoopFuseINTEL = 5906,
+ CapabilityFPGABufferLocationINTEL = 5920,
+ CapabilityUSMStorageClassesINTEL = 5935,
+ CapabilityIOPipesINTEL = 5943,
CapabilityBlockingPipesINTEL = 5945,
CapabilityFPGARegINTEL = 5948,
CapabilityAtomicFloat32AddEXT = 6033,
CapabilityAtomicFloat64AddEXT = 6034,
+ CapabilityLongConstantCompositeINTEL = 6089,
+ CapabilityAtomicFloat16AddEXT = 6095,
CapabilityMax = 0x7fffffff,
};
@@ -1047,6 +1110,18 @@ enum FragmentShadingRateMask {
FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
};
+enum FPDenormMode {
+ FPDenormModePreserve = 0,
+ FPDenormModeFlushToZero = 1,
+ FPDenormModeMax = 0x7fffffff,
+};
+
+enum FPOperationMode {
+ FPOperationModeIEEE = 0,
+ FPOperationModeALT = 1,
+ FPOperationModeMax = 0x7fffffff,
+};
+
enum Op {
OpNop = 0,
OpUndef = 1,
@@ -1430,6 +1505,8 @@ enum Op {
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
@@ -1466,8 +1543,15 @@ enum Op {
OpUSubSatINTEL = 5596,
OpIMul32x16INTEL = 5597,
OpUMul32x16INTEL = 5598,
- OpFunctionPointerINTEL = 5600,
+ OpConstFunctionPointerINTEL = 5600,
OpFunctionPointerCallINTEL = 5601,
+ OpAsmTargetINTEL = 5609,
+ OpAsmINTEL = 5610,
+ OpAsmCallINTEL = 5611,
+ OpAtomicFMinEXT = 5614,
+ OpAtomicFMaxEXT = 5615,
+ OpAssumeTrueKHR = 5630,
+ OpExpectKHR = 5631,
OpDecorateString = 5632,
OpDecorateStringGOOGLE = 5632,
OpMemberDecorateString = 5633,
@@ -1590,7 +1674,12 @@ enum Op {
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+ OpVariableLengthArrayINTEL = 5818,
+ OpSaveMemoryINTEL = 5819,
+ OpRestoreMemoryINTEL = 5820,
OpLoopControlINTEL = 5887,
+ OpPtrCastToCrossWorkgroupINTEL = 5934,
+ OpCrossWorkgroupCastToPtrINTEL = 5938,
OpReadPipeBlockingINTEL = 5946,
OpWritePipeBlockingINTEL = 5947,
OpFPGARegINTEL = 5949,
@@ -1612,6 +1701,10 @@ enum Op {
OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
OpAtomicFAddEXT = 6035,
+ OpTypeBufferSurfaceINTEL = 6086,
+ OpTypeStructContinuedINTEL = 6090,
+ OpConstantCompositeContinuedINTEL = 6091,
+ OpSpecConstantCompositeContinuedINTEL = 6092,
OpMax = 0x7fffffff,
};
@@ -2001,6 +2094,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case OpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
@@ -2036,8 +2131,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
- case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;
+ case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;
+ case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;
+ case OpExpectKHR: *hasResult = true; *hasResultType = true; break;
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2158,7 +2260,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2180,6 +2287,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
+ case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;
+ case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */