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.h1
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.KHR.h3
-rw-r--r--thirdparty/glslang/SPIRV/GlslangToSpv.cpp312
-rw-r--r--thirdparty/glslang/SPIRV/SPVRemapper.cpp10
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.cpp29
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.h14
-rw-r--r--thirdparty/glslang/SPIRV/SpvTools.cpp20
-rw-r--r--thirdparty/glslang/SPIRV/SpvTools.h11
-rw-r--r--thirdparty/glslang/SPIRV/disassemble.cpp1
-rw-r--r--thirdparty/glslang/SPIRV/doc.cpp68
-rw-r--r--thirdparty/glslang/SPIRV/spirv.hpp52
-rw-r--r--thirdparty/glslang/SPIRV/spvIR.h1
12 files changed, 402 insertions, 120 deletions
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
index 6eb0eeeada..20b9e54014 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
@@ -36,5 +36,6 @@ 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_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 d783a8f299..9610c6eeee 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
@@ -48,4 +48,7 @@ static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shade
static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
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";
+
#endif // #ifndef GLSLextKHR_H
diff --git a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
index c85541603f..1adebef878 100644
--- a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
+++ b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
@@ -149,6 +149,7 @@ protected:
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
+ spv::Decoration TranslateNonUniformDecoration(const spv::Builder::AccessChain::CoherentFlags& coherentFlags);
spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type);
spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
@@ -189,6 +190,7 @@ protected:
bool originalParam(glslang::TStorageQualifier, const glslang::TType&, bool implicitThisParam);
void makeFunctions(const glslang::TIntermSequence&);
void makeGlobalInitializers(const glslang::TIntermSequence&);
+ void collectRayTracingLinkerObjects();
void visitFunctions(const glslang::TIntermSequence&);
void handleFunctionEntry(const glslang::TIntermAggregate* node);
void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
@@ -272,6 +274,9 @@ protected:
// requiring local translation to and from SPIR-V type on every access.
// Maps <builtin-variable-id -> AST-required-type-id>
std::unordered_map<spv::Id, spv::Id> forceType;
+
+ // Used later for generating OpTraceKHR/OpExecuteCallableKHR
+ std::unordered_map<unsigned int, glslang::TIntermSymbol *> locationToSymbol[2];
};
//
@@ -539,6 +544,20 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl
return spv::DecorationMax;
}
+// If lvalue flags contains nonUniform, return SPIR-V NonUniform decoration.
+spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(
+ const spv::Builder::AccessChain::CoherentFlags& coherentFlags)
+{
+#ifndef GLSLANG_WEB
+ if (coherentFlags.isNonUniform()) {
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
+ builder.addCapability(spv::CapabilityShaderNonUniformEXT);
+ return spv::DecorationNonUniformEXT;
+ } else
+#endif
+ return spv::DecorationMax;
+}
+
spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{
@@ -614,6 +633,7 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere
flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler;
#endif
+ flags.nonUniform = type.getQualifier().nonUniform;
return flags;
}
@@ -709,13 +729,20 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInCullDistance;
case glslang::EbvViewportIndex:
- builder.addCapability(spv::CapabilityMultiViewport);
+ if (glslangIntermediate->getStage() == EShLangGeometry ||
+ glslangIntermediate->getStage() == EShLangFragment) {
+ builder.addCapability(spv::CapabilityMultiViewport);
+ }
if (glslangIntermediate->getStage() == EShLangVertex ||
glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) {
- builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
- builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
+ if (builder.getSpvVersion() < spv::Spv_1_5) {
+ builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
+ builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
+ }
+ else
+ builder.addCapability(spv::CapabilityShaderViewportIndex);
}
return spv::BuiltInViewportIndex;
@@ -734,13 +761,19 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
if (glslangIntermediate->getStage() == EShLangMeshNV) {
return spv::BuiltInLayer;
}
- builder.addCapability(spv::CapabilityGeometry);
+ if (glslangIntermediate->getStage() == EShLangGeometry ||
+ glslangIntermediate->getStage() == EShLangFragment) {
+ builder.addCapability(spv::CapabilityGeometry);
+ }
if (glslangIntermediate->getStage() == EShLangVertex ||
glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) {
- builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
- builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
+ if (builder.getSpvVersion() < spv::Spv_1_5) {
+ builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
+ builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
+ } else
+ builder.addCapability(spv::CapabilityShaderLayer);
}
return spv::BuiltInLayer;
@@ -769,6 +802,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
builder.addCapability(spv::CapabilityStencilExportEXT);
return spv::BuiltInFragStencilRefEXT;
+ case glslang::EbvShadingRateKHR:
+ builder.addExtension(spv::E_SPV_KHR_fragment_shading_rate);
+ builder.addCapability(spv::CapabilityFragmentShadingRateKHR);
+ return spv::BuiltInShadingRateKHR;
+
+ case glslang::EbvPrimitiveShadingRateKHR:
+ builder.addExtension(spv::E_SPV_KHR_fragment_shading_rate);
+ builder.addCapability(spv::CapabilityFragmentShadingRateKHR);
+ return spv::BuiltInPrimitiveShadingRateKHR;
+
case glslang::EbvInvocationId: return spv::BuiltInInvocationId;
case glslang::EbvTessLevelInner: return spv::BuiltInTessLevelInner;
case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter;
@@ -963,7 +1006,17 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
case glslang::EbvInstanceCustomIndex:
return spv::BuiltInInstanceCustomIndexKHR;
case glslang::EbvHitT:
- return spv::BuiltInHitTKHR;
+ {
+ // this is a GLSL alias of RayTmax
+ // in SPV_NV_ray_tracing it has a dedicated builtin
+ // but in SPV_KHR_ray_tracing it gets mapped to RayTmax
+ auto& extensions = glslangIntermediate->getRequestedExtensions();
+ if (extensions.find("GL_NV_ray_tracing") != extensions.end()) {
+ return spv::BuiltInHitTNV;
+ } else {
+ return spv::BuiltInRayTmaxKHR;
+ }
+ }
case glslang::EbvHitKind:
return spv::BuiltInHitKindKHR;
case glslang::EbvObjectToWorld:
@@ -1071,6 +1124,10 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
builder.addCapability(spv::CapabilityStorageImageExtendedFormats);
break;
+ case glslang::ElfR64ui:
+ case glslang::ElfR64i:
+ builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
+ builder.addCapability(spv::CapabilityInt64ImageEXT);
default:
break;
}
@@ -1117,6 +1174,8 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
case glslang::ElfRg8ui: return spv::ImageFormatRg8ui;
case glslang::ElfR16ui: return spv::ImageFormatR16ui;
case glslang::ElfR8ui: return spv::ImageFormatR8ui;
+ case glslang::ElfR64ui: return spv::ImageFormatR64ui;
+ case glslang::ElfR64i: return spv::ImageFormatR64i;
default: return spv::ImageFormatMax;
}
}
@@ -1187,7 +1246,7 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type)
{
if (type.getBasicType() == glslang::EbtRayQuery)
- return spv::StorageClassFunction;
+ return spv::StorageClassPrivate;
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput())
@@ -1353,6 +1412,8 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
if (parent.writeonly)
child.writeonly = true;
#endif
+ if (parent.nonUniform)
+ child.nonUniform = true;
}
bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier)
@@ -1454,7 +1515,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
}
if (glslangIntermediate->getLayoutPrimitiveCulling()) {
- builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
+ builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
}
unsigned int mode;
@@ -1621,7 +1682,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
{
auto& extensions = glslangIntermediate->getRequestedExtensions();
if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
- builder.addCapability(spv::CapabilityRayTracingProvisionalKHR);
+ builder.addCapability(spv::CapabilityRayTracingKHR);
builder.addExtension("SPV_KHR_ray_tracing");
}
else {
@@ -1710,6 +1771,12 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
if (symbol->getType().getQualifier().isSpecConstant())
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
+#ifdef ENABLE_HLSL
+ // Skip symbol handling if it is string-typed
+ if (symbol->getBasicType() == glslang::EbtString)
+ return;
+#endif
+
// getSymbolId() will set up all the IO decorations on the first call.
// Formal function parameters were mapped during makeFunctions().
spv::Id id = getSymbolId(symbol);
@@ -1852,9 +1919,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
// do the operation
+ spv::Builder::AccessChain::CoherentFlags coherentFlags = TranslateCoherent(node->getLeft()->getType());
+ coherentFlags |= TranslateCoherent(node->getRight()->getType());
OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
TranslateNoContractionDecoration(node->getType().getQualifier()),
- TranslateNonUniformDecoration(node->getType().getQualifier()) };
+ TranslateNonUniformDecoration(coherentFlags) };
rValue = createBinaryOperation(node->getOp(), decorations,
convertGlslangToSpvType(node->getType()), leftRValue, rValue,
node->getType().getBasicType());
@@ -1885,13 +1954,16 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
if (! node->getLeft()->getType().isArray() &&
node->getLeft()->getType().isVector() &&
node->getOp() == glslang::EOpIndexDirect) {
+ // Swizzle is uniform so propagate uniform into access chain
+ spv::Builder::AccessChain::CoherentFlags coherentFlags = TranslateCoherent(node->getLeft()->getType());
+ coherentFlags.nonUniform = 0;
// This is essentially a hard-coded vector swizzle of size 1,
// so short circuit the access-chain stuff with a swizzle.
std::vector<unsigned> swizzle;
swizzle.push_back(glslangIndex);
int dummySize;
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
- TranslateCoherent(node->getLeft()->getType()),
+ coherentFlags,
glslangIntermediate->getBaseAlignmentScalar(
node->getLeft()->getType(), dummySize));
} else {
@@ -1922,9 +1994,14 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
}
}
+ // Struct reference propagates uniform lvalue
+ spv::Builder::AccessChain::CoherentFlags coherentFlags =
+ TranslateCoherent(node->getLeft()->getType());
+ coherentFlags.nonUniform = 0;
+
// normal case for indexing array or structure or block
builder.accessChainPush(builder.makeIntConstant(spvIndex),
- TranslateCoherent(node->getLeft()->getType()),
+ coherentFlags,
node->getLeft()->getType().getBufferReferenceAlignment());
// Add capabilities here for accessing PointSize and clip/cull distance.
@@ -1958,15 +2035,20 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
// restore the saved access chain
builder.setAccessChain(partial);
+ // Only if index is nonUniform should we propagate nonUniform into access chain
+ spv::Builder::AccessChain::CoherentFlags index_flags = TranslateCoherent(node->getRight()->getType());
+ spv::Builder::AccessChain::CoherentFlags coherent_flags = TranslateCoherent(node->getLeft()->getType());
+ coherent_flags.nonUniform = index_flags.nonUniform;
+
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) {
int dummySize;
- builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()),
- TranslateCoherent(node->getLeft()->getType()),
+ builder.accessChainPushComponent(
+ index, convertGlslangToSpvType(node->getLeft()->getType()), coherent_flags,
glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
dummySize));
} else
- builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()),
- node->getLeft()->getType().getBufferReferenceAlignment());
+ builder.accessChainPush(index, coherent_flags,
+ node->getLeft()->getType().getBufferReferenceAlignment());
}
return false;
case glslang::EOpVectorSwizzle:
@@ -2050,8 +2132,9 @@ std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuil
// these require changing a 64-bit scaler -> a vector of 32-bit components
if (glslangType.isVector())
break;
- std::pair<spv::Id, spv::Id> ret(builder.makeVectorType(builder.makeUintType(32), 4),
- builder.makeUintType(64));
+ spv::Id ivec4_type = builder.makeVectorType(builder.makeUintType(32), 4);
+ spv::Id uint64_type = builder.makeUintType(64);
+ std::pair<spv::Id, spv::Id> ret(ivec4_type, uint64_type);
return ret;
}
// There are no SPIR-V builtins defined for these and map onto original non-transposed
@@ -2090,7 +2173,7 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
// handle 32-bit v.xy* -> 64-bit
builder.clearAccessChain();
builder.setAccessChainLValue(object);
- object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId);
+ object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, spv::DecorationMax, objectTypeId);
std::vector<spv::Id> components;
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 0));
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 1));
@@ -2106,7 +2189,7 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
// and we insert a transpose after loading the original non-transposed builtins
builder.clearAccessChain();
builder.setAccessChainLValue(object);
- object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId);
+ object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, spv::DecorationMax, objectTypeId);
return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object);
} else {
@@ -2292,7 +2375,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// The result of operation is always stored, but conditionally the
// consumed result. The consumed result is always an r-value.
- builder.accessChainStore(result);
+ builder.accessChainStore(result,
+ TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags));
builder.clearAccessChain();
if (node->getOp() == glslang::EOpPreIncrement ||
node->getOp() == glslang::EOpPreDecrement)
@@ -2421,6 +2505,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
// anything else gets there, so visit out of order, doing them all now.
makeGlobalInitializers(node->getAsAggregate()->getSequence());
+ //Pre process linker objects for ray tracing stages
+ if (glslangIntermediate->isRayTracingStage())
+ collectRayTracingLinkerObjects();
+
// Initializers are done, don't want to visit again, but functions and link objects need to be processed,
// so do them manually.
visitFunctions(node->getAsAggregate()->getSequence());
@@ -2611,6 +2699,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
else
constructed = builder.createConstructor(precision, arguments, resultType());
+ if (node->getType().getQualifier().isNonUniform()) {
+ builder.addDecoration(constructed, spv::DecorationNonUniformEXT);
+ }
+
builder.clearAccessChain();
builder.setAccessChainRValue(constructed);
@@ -2726,10 +2818,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
binOp = node->getOp();
break;
- case glslang::EOpIgnoreIntersection:
- case glslang::EOpTerminateRay:
- case glslang::EOpTrace:
- case glslang::EOpExecuteCallable:
+ case glslang::EOpIgnoreIntersectionNV:
+ case glslang::EOpTerminateRayNV:
+ case glslang::EOpTraceNV:
+ case glslang::EOpTraceKHR:
+ case glslang::EOpExecuteCallableNV:
+ case glslang::EOpExecuteCallableKHR:
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
noReturnValue = true;
break;
@@ -2738,7 +2832,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpRayQueryGenerateIntersection:
case glslang::EOpRayQueryConfirmIntersection:
builder.addExtension("SPV_KHR_ray_query");
- builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ builder.addCapability(spv::CapabilityRayQueryKHR);
noReturnValue = true;
break;
case glslang::EOpRayQueryProceed:
@@ -2761,7 +2855,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpRayQueryGetIntersectionObjectToWorld:
case glslang::EOpRayQueryGetIntersectionWorldToObject:
builder.addExtension("SPV_KHR_ray_query");
- builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ builder.addCapability(spv::CapabilityRayQueryKHR);
break;
case glslang::EOpCooperativeMatrixLoad:
case glslang::EOpCooperativeMatrixStore:
@@ -3014,11 +3108,18 @@ 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 {
+ } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
+ (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
+ const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1;
+ const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1;
+ 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 {
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
- }
-
+ }
}
}
@@ -3089,7 +3190,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
builder.setAccessChain(complexLvalues[i]);
- builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision));
+ builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision),
+ TranslateNonUniformDecoration(complexLvalues[i].coherentFlags));
}
}
@@ -3420,7 +3522,11 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
switch (node->getFlowOp()) {
case glslang::EOpKill:
- builder.makeDiscard();
+ builder.makeStatementTerminator(spv::OpKill, "post-discard");
+ break;
+ case glslang::EOpTerminateInvocation:
+ builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
+ builder.makeStatementTerminator(spv::OpTerminateInvocation, "post-terminate-invocation");
break;
case glslang::EOpBreak:
if (breakForLoop.top())
@@ -3457,6 +3563,12 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
break;
+ case glslang::EOpTerminateRayKHR:
+ builder.makeStatementTerminator(spv::OpTerminateRayKHR, "post-terminateRayKHR");
+ break;
+ case glslang::EOpIgnoreIntersectionKHR:
+ builder.makeStatementTerminator(spv::OpIgnoreIntersectionKHR, "post-ignoreIntersectionKHR");
+ break;
#endif
default:
@@ -3564,6 +3676,12 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
return builder.makeFloatType(16);
+ case glslang::EbtInt64: return builder.makeIntType(64);
+ builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
+ builder.addCapability(spv::CapabilityFloat16ImageAMD);
+ case glslang::EbtUint64: return builder.makeUintType(64);
+ builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
+ builder.addCapability(spv::CapabilityFloat16ImageAMD);
#endif
default:
assert(0);
@@ -3670,10 +3788,36 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = builder.makeUintType(32);
break;
case glslang::EbtAccStruct:
+ switch (glslangIntermediate->getStage()) {
+ case EShLangRayGen:
+ case EShLangIntersect:
+ case EShLangAnyHit:
+ case EShLangClosestHit:
+ case EShLangMiss:
+ case EShLangCallable:
+ // these all should have the RayTracingNV/KHR capability already
+ break;
+ default:
+ {
+ auto& extensions = glslangIntermediate->getRequestedExtensions();
+ if (extensions.find("GL_EXT_ray_query") != extensions.end()) {
+ builder.addExtension(spv::E_SPV_KHR_ray_query);
+ builder.addCapability(spv::CapabilityRayQueryKHR);
+ }
+ }
+ break;
+ }
spvType = builder.makeAccelerationStructureType();
break;
case glslang::EbtRayQuery:
- spvType = builder.makeRayQueryType();
+ {
+ auto& extensions = glslangIntermediate->getRequestedExtensions();
+ if (extensions.find("GL_EXT_ray_query") != extensions.end()) {
+ builder.addExtension(spv::E_SPV_KHR_ray_query);
+ builder.addCapability(spv::CapabilityRayQueryKHR);
+ }
+ spvType = builder.makeRayQueryType();
+ }
break;
case glslang::EbtReference:
{
@@ -3929,6 +4073,8 @@ 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++) {
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
int member = i;
@@ -3981,7 +4127,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
// just track whether a member needs to be decorated.
// Ignore member locations if the container is an array, as that's
// ill-specified and decisions have been made to not allow this.
- if (! type.isArray() && memberQualifier.hasLocation())
+ if (!memberLocationInvalid && memberQualifier.hasLocation())
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
if (qualifier.hasLocation()) // track for upcoming inheritance
@@ -4087,6 +4233,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
alignment |= type.getBufferReferenceAlignment();
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
+ TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags),
TranslateNonUniformDecoration(type.getQualifier()),
nominalTypeId,
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
@@ -4154,7 +4301,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
unsigned int alignment = builder.getAccessChain().alignment;
alignment |= type.getBufferReferenceAlignment();
- builder.accessChainStore(rvalue,
+ builder.accessChainStore(rvalue, TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags),
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
~spv::MemoryAccessMakePointerVisibleKHRMask),
TranslateMemoryScope(coherentFlags), alignment);
@@ -4542,7 +4689,39 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen
}
}
}
+// Walk over all linker objects to create a map for payload and callable data linker objects
+// and their location to be used during codegen for OpTraceKHR and OpExecuteCallableKHR
+// This is done here since it is possible that these linker objects are not be referenced in the AST
+void TGlslangToSpvTraverser::collectRayTracingLinkerObjects()
+{
+ glslang::TIntermAggregate* linkerObjects = glslangIntermediate->findLinkerObjects();
+ for (auto& objSeq : linkerObjects->getSequence()) {
+ auto objNode = objSeq->getAsSymbolNode();
+ if (objNode != nullptr) {
+ if (objNode->getQualifier().hasLocation()) {
+ unsigned int location = objNode->getQualifier().layoutLocation;
+ auto st = objNode->getQualifier().storage;
+ int set;
+ switch (st)
+ {
+ case glslang::EvqPayload:
+ case glslang::EvqPayloadIn:
+ set = 0;
+ break;
+ case glslang::EvqCallableData:
+ case glslang::EvqCallableDataIn:
+ set = 1;
+ break;
+ default:
+ set = -1;
+ }
+ if (set != -1)
+ locationToSymbol[set].insert(std::make_pair(location, objNode));
+ }
+ }
+ }
+}
// Process all the functions, while skipping initializers.
void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions)
{
@@ -4686,8 +4865,10 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
}
if (lvalue) {
- arguments.push_back(builder.accessChainGetLValue());
+ spv::Id lvalue_id = builder.accessChainGetLValue();
+ arguments.push_back(lvalue_id);
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
+ builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags));
lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType());
} else
#endif
@@ -4750,12 +4931,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint;
+ if (builder.isSampledImage(params.sampler) &&
+ ((cracked.query && node->getOp() != glslang::EOpTextureQueryLod) || cracked.fragMask || cracked.fetch)) {
+ params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
+ if (imageType.getQualifier().isNonUniform()) {
+ builder.addDecoration(params.sampler, spv::DecorationNonUniformEXT);
+ }
+ }
// Check for queries
if (cracked.query) {
- // OpImageQueryLod works on a sampled image, for other queries the image has to be extracted first
- if (node->getOp() != glslang::EOpTextureQueryLod && builder.isSampledImage(params.sampler))
- params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
-
switch (node->getOp()) {
case glslang::EOpImageQuerySize:
case glslang::EOpTextureQuerySize:
@@ -5009,10 +5193,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
auto opIt = arguments.begin();
std::vector<spv::Id> operands;
- // Extract the image if necessary
- if (builder.isSampledImage(params.sampler))
- params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
-
operands.push_back(params.sampler);
++opIt;
@@ -5073,13 +5253,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
bias = true;
}
- // See if the sampler param should really be just the SPV image part
- if (cracked.fetch) {
- // a fetch needs to have the image extracted first
- if (builder.isSampledImage(params.sampler))
- params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
- }
-
#ifndef GLSLANG_WEB
if (cracked.gather) {
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
@@ -5239,7 +5412,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
- i+1));
+ i+1), TranslateNonUniformDecoration(imageType.getQualifier()));
}
return builder.createCompositeExtract(res, resultType(), 0);
}
@@ -5375,6 +5548,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
// 3. Make the call.
spv::Id result = builder.createFunctionCall(function, spvArgs);
builder.setPrecision(result, TranslatePrecisionDecoration(node->getType()));
+ builder.addDecoration(result, TranslateNonUniformDecoration(node->getType().getQualifier()));
// 4. Copy back out an "out" arguments.
lValueCount = 0;
@@ -5384,6 +5558,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
else if (writableParam(qualifiers[a])) {
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision);
+ builder.addDecoration(copy, TranslateNonUniformDecoration(argTypes[a]->getQualifier()));
builder.setAccessChain(lValues[lValueCount]);
multiTypeStore(*argTypes[a], copy);
}
@@ -6171,6 +6346,11 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
case glslang::EOpConstructReference:
unaryOp = spv::OpBitcast;
break;
+
+ case glslang::EOpConvUint64ToAccStruct:
+ case glslang::EOpConvUvec2ToAccStruct:
+ unaryOp = spv::OpConvertUToAccelerationStructureKHR;
+ break;
#endif
case glslang::EOpCopyObject:
@@ -7757,10 +7937,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
typeId = builder.makeBoolType();
opCode = spv::OpReportIntersectionKHR;
break;
- case glslang::EOpTrace:
+ case glslang::EOpTraceNV:
+ builder.createNoResultOp(spv::OpTraceNV, operands);
+ return 0;
+ case glslang::EOpTraceKHR:
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0;
- case glslang::EOpExecuteCallable:
+ case glslang::EOpExecuteCallableNV:
+ builder.createNoResultOp(spv::OpExecuteCallableNV, operands);
+ return 0;
+ case glslang::EOpExecuteCallableKHR:
builder.createNoResultOp(spv::OpExecuteCallableKHR, operands);
return 0;
@@ -8048,11 +8234,11 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
return builder.setPrecision(id, precision);
}
- case glslang::EOpIgnoreIntersection:
- builder.createNoResultOp(spv::OpIgnoreIntersectionKHR);
+ case glslang::EOpIgnoreIntersectionNV:
+ builder.createNoResultOp(spv::OpIgnoreIntersectionNV);
return 0;
- case glslang::EOpTerminateRay:
- builder.createNoResultOp(spv::OpTerminateRayKHR);
+ case glslang::EOpTerminateRayNV:
+ builder.createNoResultOp(spv::OpTerminateRayNV);
return 0;
case glslang::EOpRayQueryInitialize:
builder.createNoResultOp(spv::OpRayQueryInitializeKHR);
@@ -8180,7 +8366,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
}
#ifndef GLSLANG_WEB
- if (symbol->getType().isImage()) {
+ // Subgroup builtins which have input storage class are volatile for ray tracing stages.
+ if (symbol->getType().isImage() || symbol->getQualifier().isPipeInput()) {
std::vector<spv::Decoration> memory;
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory,
glslangIntermediate->usingVulkanMemoryModel());
@@ -8188,9 +8375,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, memory[i]);
}
- // nonuniform
- builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier()));
-
if (builtIn == spv::BuiltInSampleMask) {
spv::Decoration decoration;
// GL_NV_sample_mask_override_coverage extension
diff --git a/thirdparty/glslang/SPIRV/SPVRemapper.cpp b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
index 1adc6a3042..56d7f431a7 100644
--- a/thirdparty/glslang/SPIRV/SPVRemapper.cpp
+++ b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
@@ -830,7 +830,15 @@ namespace spv {
[&](spv::Id& id) {
if (thisOpCode != spv::OpNop) {
++idCounter;
- const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117;
+ const std::uint32_t hashval =
+ // Explicitly cast operands to unsigned int to avoid integer
+ // promotion to signed int followed by integer overflow,
+ // which would result in undefined behavior.
+ static_cast<unsigned int>(opCounter[thisOpCode])
+ * thisOpCode
+ * 50047
+ + idCounter
+ + static_cast<unsigned int>(fnId) * 117;
if (isOldIdUnmapped(id))
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.cpp b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
index 9680331469..c8fbcc450e 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.cpp
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
@@ -621,13 +621,13 @@ Id Builder::makeAccelerationStructureType()
Id Builder::makeRayQueryType()
{
Instruction *type;
- if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) {
- type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR);
- groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type);
+ if (groupedTypes[OpTypeRayQueryKHR].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryKHR);
+ groupedTypes[OpTypeRayQueryKHR].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
} else {
- type = groupedTypes[OpTypeRayQueryProvisionalKHR].back();
+ type = groupedTypes[OpTypeRayQueryKHR].back();
}
return type->getResultId();
@@ -1447,10 +1447,10 @@ void Builder::leaveFunction()
}
// Comments in header
-void Builder::makeDiscard()
+void Builder::makeStatementTerminator(spv::Op opcode, const char *name)
{
- buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpKill)));
- createAndSetNoPredecessorBlock("post-discard");
+ buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
+ createAndSetNoPredecessorBlock(name);
}
// Comments in header
@@ -2761,12 +2761,14 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
}
// Comments in header
-void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
assert(accessChain.isRValue == false);
transferAccessChainSwizzle(true);
Id base = collapseAccessChain();
+ addDecoration(base, nonUniform);
+
Id source = rvalue;
// dynamic component should be gone
@@ -2789,8 +2791,9 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
}
// Comments in header
-Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType,
- spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+Id Builder::accessChainLoad(Decoration precision, Decoration l_nonUniform,
+ Decoration r_nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess,
+ spv::Scope scope, unsigned int alignment)
{
Id id;
@@ -2854,9 +2857,9 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
// Buffer accesses need the access chain decorated, and this is where
// loaded image types get decorated. TODO: This should maybe move to
// createImageTextureFunctionCall.
- addDecoration(id, nonUniform);
+ addDecoration(id, l_nonUniform);
id = createLoad(id, precision, memoryAccess, scope, alignment);
- addDecoration(id, nonUniform);
+ addDecoration(id, r_nonUniform);
}
// Done, unless there are swizzles to do
@@ -2877,7 +2880,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
if (accessChain.component != NoResult)
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
- addDecoration(id, nonUniform);
+ addDecoration(id, r_nonUniform);
return id;
}
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.h b/thirdparty/glslang/SPIRV/SpvBuilder.h
index 077945e77b..911ea58b12 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.h
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.h
@@ -357,8 +357,9 @@ public:
// Generate all the code needed to finish up a function.
void leaveFunction();
- // Create a discard.
- void makeDiscard();
+ // Create block terminator instruction for certain statements like
+ // discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT
+ void makeStatementTerminator(spv::Op opcode, const char *name);
// Create a global or function local or IO variable.
Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
@@ -624,6 +625,7 @@ public:
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
#else
bool isVolatile() const { return volatil; }
+ bool isNonUniform() const { return nonUniform; }
bool anyCoherent() const {
return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
subgroupcoherent || shadercallcoherent;
@@ -638,6 +640,7 @@ public:
unsigned nonprivate : 1;
unsigned volatil : 1;
unsigned isImage : 1;
+ unsigned nonUniform : 1;
void clear() {
coherent = 0;
@@ -649,6 +652,7 @@ public:
nonprivate = 0;
volatil = 0;
isImage = 0;
+ nonUniform = 0;
}
CoherentFlags operator |=(const CoherentFlags &other) {
@@ -661,6 +665,7 @@ public:
nonprivate |= other.nonprivate;
volatil |= other.volatil;
isImage |= other.isImage;
+ nonUniform |= other.nonUniform;
return *this;
}
#endif
@@ -721,11 +726,12 @@ public:
}
// use accessChain and swizzle to store value
- void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
+ void accessChainStore(Id rvalue, Decoration nonUniform,
+ spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value
- Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType,
+ Id accessChainLoad(Decoration precision, Decoration l_nonUniform, Decoration r_nonUniform, Id ResultType,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
unsigned int alignment = 0);
diff --git a/thirdparty/glslang/SPIRV/SpvTools.cpp b/thirdparty/glslang/SPIRV/SpvTools.cpp
index 112ac33c5c..16d051a9b2 100644
--- a/thirdparty/glslang/SPIRV/SpvTools.cpp
+++ b/thirdparty/glslang/SPIRV/SpvTools.cpp
@@ -44,7 +44,6 @@
#include "SpvTools.h"
#include "spirv-tools/optimizer.hpp"
-#include "spirv-tools/libspirv.h"
namespace glslang {
@@ -114,11 +113,18 @@ void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
out << std::endl;
}
-// Use the SPIRV-Tools disassembler to print SPIR-V.
+// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
{
+ SpirvToolsDisassemble(out, spirv, spv_target_env::SPV_ENV_UNIVERSAL_1_3);
+}
+
+// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
+void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
+ spv_target_env requested_context)
+{
// disassemble
- spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
+ spv_context context = spvContextCreate(requested_context);
spv_text text;
spv_diagnostic diagnostic = nullptr;
spvBinaryToText(context, spirv.data(), spirv.size(),
@@ -174,10 +180,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
// line information into all SPIR-V instructions. This avoids loss of
// information when instructions are deleted or moved. Later, remove
// redundant information to minimize final SPRIR-V size.
- if (options->generateDebugInfo) {
- optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
- }
- else if (options->stripDebugInfo) {
+ if (options->stripDebugInfo) {
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
}
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
@@ -207,9 +210,6 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
}
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
- if (options->generateDebugInfo) {
- optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
- }
spvtools::OptimizerOptions spvOptOptions;
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
diff --git a/thirdparty/glslang/SPIRV/SpvTools.h b/thirdparty/glslang/SPIRV/SpvTools.h
index 7779dfa779..3fb3cbacd3 100644
--- a/thirdparty/glslang/SPIRV/SpvTools.h
+++ b/thirdparty/glslang/SPIRV/SpvTools.h
@@ -41,9 +41,10 @@
#ifndef GLSLANG_SPV_TOOLS_H
#define GLSLANG_SPV_TOOLS_H
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
#include <vector>
#include <ostream>
+#include "spirv-tools/libspirv.h"
#endif
#include "glslang/MachineIndependent/localintermediate.h"
@@ -62,11 +63,15 @@ struct SpvOptions {
bool validate;
};
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
-// Use the SPIRV-Tools disassembler to print SPIR-V.
+// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
+// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
+void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
+ spv_target_env requested_context);
+
// Apply the SPIRV-Tools validator to generated SPIR-V.
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, bool prelegalization);
diff --git a/thirdparty/glslang/SPIRV/disassemble.cpp b/thirdparty/glslang/SPIRV/disassemble.cpp
index a95ded49d2..73c988c5b3 100644
--- a/thirdparty/glslang/SPIRV/disassemble.cpp
+++ b/thirdparty/glslang/SPIRV/disassemble.cpp
@@ -46,7 +46,6 @@
#include "disassemble.h"
#include "doc.h"
-#include "SpvTools.h"
namespace spv {
extern "C" {
diff --git a/thirdparty/glslang/SPIRV/doc.cpp b/thirdparty/glslang/SPIRV/doc.cpp
index 1d052f8c29..5327f2212d 100644
--- a/thirdparty/glslang/SPIRV/doc.cpp
+++ b/thirdparty/glslang/SPIRV/doc.cpp
@@ -372,6 +372,8 @@ const char* BuiltInString(int builtIn)
case 4424: return "BaseVertex";
case 4425: return "BaseInstance";
case 4426: return "DrawIndex";
+ case 4432: return "PrimitiveShadingRateKHR";
+ case 4444: return "ShadingRateKHR";
case 5014: return "FragStencilRefEXT";
case 4992: return "BaryCoordNoPerspAMD";
@@ -393,7 +395,7 @@ const char* BuiltInString(int builtIn)
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
case BuiltInWorldToObjectKHR: return "WorldToObjectKHR";
- case BuiltInHitTKHR: return "HitTKHR";
+ case BuiltInHitTNV: return "HitTNV";
case BuiltInHitKindKHR: return "HitKindKHR";
case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR";
case BuiltInViewportMaskNV: return "ViewportMaskNV";
@@ -521,6 +523,8 @@ const char* ImageFormatString(int format)
case 37: return "Rg8ui";
case 38: return "R16ui";
case 39: return "R8ui";
+ case 40: return "R64ui";
+ case 41: return "R64i";
default:
return "Bad";
@@ -911,9 +915,9 @@ const char* CapabilityString(int info)
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
case CapabilityRayTracingNV: return "RayTracingNV";
- case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
- case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR";
- case CapabilityRayTraversalPrimitiveCullingProvisionalKHR: return "RayTraversalPrimitiveCullingProvisionalKHR";
+ case CapabilityRayTracingKHR: return "RayTracingKHR";
+ case CapabilityRayQueryKHR: return "RayQueryKHR";
+ case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
@@ -952,8 +956,11 @@ const char* CapabilityString(int info)
case CapabilityFragmentShaderPixelInterlockEXT: return "CapabilityFragmentShaderPixelInterlockEXT";
case CapabilityFragmentShaderShadingRateInterlockEXT: return "CapabilityFragmentShaderShadingRateInterlockEXT";
+ case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR";
+
case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT";
case CapabilityShaderClockKHR: return "ShaderClockKHR";
+ case CapabilityInt64ImageEXT: return "Int64ImageEXT";
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
@@ -1329,6 +1336,8 @@ const char* OpcodeString(int op)
case 365: return "OpGroupNonUniformQuadBroadcast";
case 366: return "OpGroupNonUniformQuadSwap";
+ case OpTerminateInvocation: return "OpTerminateInvocation";
+
case 4421: return "OpSubgroupBallotKHR";
case 4422: return "OpSubgroupFirstInvocationKHR";
case 4428: return "OpSubgroupAllKHR";
@@ -1355,17 +1364,23 @@ const char* OpcodeString(int op)
case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE";
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
+ case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
+ case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
+ case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
+ case OpTerminateRayNV: return "OpTerminateRayNV";
+ case OpTerminateRayKHR: return "OpTerminateRayKHR";
+ case OpTraceNV: return "OpTraceNV";
+ case OpTraceRayKHR: return "OpTraceRayKHR";
+ case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
+ case OpExecuteCallableNV: return "OpExecuteCallableNV";
+ case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
+ case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR";
+
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
- case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
- case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
- case OpTerminateRayKHR: return "OpTerminateRayKHR";
- case OpTraceRayKHR: return "OpTraceRayKHR";
- case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
- case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
- case OpTypeRayQueryProvisionalKHR: return "OpTypeRayQueryProvisionalKHR";
+ case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR";
case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR";
case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR";
case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR";
@@ -1497,6 +1512,7 @@ void Parameterize()
InstructionDesc[OpBranchConditional].setResultAndType(false, false);
InstructionDesc[OpSwitch].setResultAndType(false, false);
InstructionDesc[OpKill].setResultAndType(false, false);
+ InstructionDesc[OpTerminateInvocation].setResultAndType(false, false);
InstructionDesc[OpReturn].setResultAndType(false, false);
InstructionDesc[OpReturnValue].setResultAndType(false, false);
InstructionDesc[OpUnreachable].setResultAndType(false, false);
@@ -2761,7 +2777,20 @@ void Parameterize()
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
- InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'NV Acceleration Structure'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'");
+ InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
+ InstructionDesc[OpTraceNV].setResultAndType(false, false);
+
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'");
@@ -2777,17 +2806,28 @@ void Parameterize()
InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'");
InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'");
+ InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false);
+
InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false);
+ InstructionDesc[OpTerminateRayNV].setResultAndType(false, false);
+
InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false);
+ InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index");
+ InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
+ InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
+
InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index");
- InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData ID");
+ InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData");
InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false);
+ InstructionDesc[OpConvertUToAccelerationStructureKHR].operands.push(OperandId, "Value");
+ InstructionDesc[OpConvertUToAccelerationStructureKHR].setResultAndType(true, true);
+
// Ray Query
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
- InstructionDesc[OpTypeRayQueryProvisionalKHR].setResultAndType(true, false);
+ InstructionDesc[OpTypeRayQueryKHR].setResultAndType(true, false);
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'");
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'");
diff --git a/thirdparty/glslang/SPIRV/spirv.hpp b/thirdparty/glslang/SPIRV/spirv.hpp
index 35482ea5e2..43dd2aaeec 100644
--- a/thirdparty/glslang/SPIRV/spirv.hpp
+++ b/thirdparty/glslang/SPIRV/spirv.hpp
@@ -50,11 +50,11 @@ namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10500
-#define SPV_REVISION 3
+#define SPV_REVISION 4
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010500;
-static const unsigned int Revision = 3;
+static const unsigned int Revision = 4;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@@ -274,6 +274,8 @@ enum ImageFormat {
ImageFormatRg8ui = 37,
ImageFormatR16ui = 38,
ImageFormatR8ui = 39,
+ ImageFormatR64ui = 40,
+ ImageFormatR64i = 41,
ImageFormatMax = 0x7fffffff,
};
@@ -558,8 +560,10 @@ enum BuiltIn {
BuiltInBaseVertex = 4424,
BuiltInBaseInstance = 4425,
BuiltInDrawIndex = 4426,
+ BuiltInPrimitiveShadingRateKHR = 4432,
BuiltInDeviceIndex = 4438,
BuiltInViewIndex = 4440,
+ BuiltInShadingRateKHR = 4444,
BuiltInBaryCoordNoPerspAMD = 4992,
BuiltInBaryCoordNoPerspCentroidAMD = 4993,
BuiltInBaryCoordNoPerspSampleAMD = 4994,
@@ -610,7 +614,6 @@ enum BuiltIn {
BuiltInObjectToWorldNV = 5330,
BuiltInWorldToObjectKHR = 5331,
BuiltInWorldToObjectNV = 5331,
- BuiltInHitTKHR = 5332,
BuiltInHitTNV = 5332,
BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
@@ -870,6 +873,7 @@ enum Capability {
CapabilityGroupNonUniformQuad = 68,
CapabilityShaderLayer = 69,
CapabilityShaderViewportIndex = 70,
+ CapabilityFragmentShadingRateKHR = 4422,
CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427,
CapabilitySubgroupVoteKHR = 4431,
@@ -894,12 +898,15 @@ enum Capability {
CapabilityRoundingModeRTE = 4467,
CapabilityRoundingModeRTZ = 4468,
CapabilityRayQueryProvisionalKHR = 4471,
- CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
+ CapabilityRayQueryKHR = 4472,
+ CapabilityRayTraversalPrimitiveCullingKHR = 4478,
+ CapabilityRayTracingKHR = 4479,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
CapabilityStencilExportEXT = 5013,
CapabilityImageReadWriteLodAMD = 5015,
+ CapabilityInt64ImageEXT = 5016,
CapabilityShaderClockKHR = 5055,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
@@ -1024,6 +1031,22 @@ enum RayQueryCandidateIntersectionType {
RayQueryCandidateIntersectionTypeMax = 0x7fffffff,
};
+enum FragmentShadingRateShift {
+ FragmentShadingRateVertical2PixelsShift = 0,
+ FragmentShadingRateVertical4PixelsShift = 1,
+ FragmentShadingRateHorizontal2PixelsShift = 2,
+ FragmentShadingRateHorizontal4PixelsShift = 3,
+ FragmentShadingRateMax = 0x7fffffff,
+};
+
+enum FragmentShadingRateMask {
+ FragmentShadingRateMaskNone = 0,
+ FragmentShadingRateVertical2PixelsMask = 0x00000001,
+ FragmentShadingRateVertical4PixelsMask = 0x00000002,
+ FragmentShadingRateHorizontal2PixelsMask = 0x00000004,
+ FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
+};
+
enum Op {
OpNop = 0,
OpUndef = 1,
@@ -1369,13 +1392,19 @@ enum Op {
OpPtrEqual = 401,
OpPtrNotEqual = 402,
OpPtrDiff = 403,
+ OpTerminateInvocation = 4416,
OpSubgroupBallotKHR = 4421,
OpSubgroupFirstInvocationKHR = 4422,
OpSubgroupAllKHR = 4428,
OpSubgroupAnyKHR = 4429,
OpSubgroupAllEqualKHR = 4430,
OpSubgroupReadInvocationKHR = 4432,
- OpTypeRayQueryProvisionalKHR = 4472,
+ OpTraceRayKHR = 4445,
+ OpExecuteCallableKHR = 4446,
+ OpConvertUToAccelerationStructureKHR = 4447,
+ OpIgnoreIntersectionKHR = 4448,
+ OpTerminateRayKHR = 4449,
+ OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
OpRayQueryGenerateIntersectionKHR = 4475,
@@ -1398,15 +1427,11 @@ enum Op {
OpWritePackedPrimitiveIndices4x8NV = 5299,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
- OpIgnoreIntersectionKHR = 5335,
OpIgnoreIntersectionNV = 5335,
- OpTerminateRayKHR = 5336,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
- OpTraceRayKHR = 5337,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
- OpExecuteCallableKHR = 5344,
OpExecuteCallableNV = 5344,
OpTypeCooperativeMatrixNV = 5358,
OpCooperativeMatrixLoadNV = 5359,
@@ -1939,13 +1964,19 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
case OpPtrDiff: *hasResult = true; *hasResultType = true; break;
+ case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break;
case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
- case OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; break;
+ case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
+ case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
+ case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
+ case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;
+ case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
@@ -2164,6 +2195,7 @@ inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
+inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); }
} // end namespace spv
diff --git a/thirdparty/glslang/SPIRV/spvIR.h b/thirdparty/glslang/SPIRV/spvIR.h
index 868b9bf82d..486e80d000 100644
--- a/thirdparty/glslang/SPIRV/spvIR.h
+++ b/thirdparty/glslang/SPIRV/spvIR.h
@@ -263,6 +263,7 @@ public:
case OpBranchConditional:
case OpSwitch:
case OpKill:
+ case OpTerminateInvocation:
case OpReturn:
case OpReturnValue:
case OpUnreachable: