|
@@ -149,6 +149,7 @@ protected:
|
|
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
|
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
|
spv::Decoration TranslateNonUniformDecoration(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::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type);
|
|
spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
|
|
spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
|
|
spv::ImageOperandsMask TranslateImageOperands(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);
|
|
bool originalParam(glslang::TStorageQualifier, const glslang::TType&, bool implicitThisParam);
|
|
void makeFunctions(const glslang::TIntermSequence&);
|
|
void makeFunctions(const glslang::TIntermSequence&);
|
|
void makeGlobalInitializers(const glslang::TIntermSequence&);
|
|
void makeGlobalInitializers(const glslang::TIntermSequence&);
|
|
|
|
+ void collectRayTracingLinkerObjects();
|
|
void visitFunctions(const glslang::TIntermSequence&);
|
|
void visitFunctions(const glslang::TIntermSequence&);
|
|
void handleFunctionEntry(const glslang::TIntermAggregate* node);
|
|
void handleFunctionEntry(const glslang::TIntermAggregate* node);
|
|
void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
|
|
void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
|
|
@@ -253,17 +255,17 @@ protected:
|
|
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
|
|
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
|
|
spv::Id stdBuiltins;
|
|
spv::Id stdBuiltins;
|
|
spv::Id nonSemanticDebugPrintf;
|
|
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
|
|
// rather than a pointer
|
|
std::unordered_map<std::string, spv::Function*> functionMap;
|
|
std::unordered_map<std::string, spv::Function*> functionMap;
|
|
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
|
|
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):
|
|
// 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
|
|
// 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::stack<bool> breakForLoop; // false means break for switch
|
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
|
// Map pointee types for EbtReference to their forward pointers
|
|
// Map pointee types for EbtReference to their forward pointers
|
|
@@ -272,6 +274,9 @@ protected:
|
|
// requiring local translation to and from SPIR-V type on every access.
|
|
// requiring local translation to and from SPIR-V type on every access.
|
|
// Maps <builtin-variable-id -> AST-required-type-id>
|
|
// Maps <builtin-variable-id -> AST-required-type-id>
|
|
std::unordered_map<spv::Id, spv::Id> forceType;
|
|
std::unordered_map<spv::Id, spv::Id> forceType;
|
|
|
|
+
|
|
|
|
+ // Used later for generating OpTraceKHR/OpExecuteCallableKHR
|
|
|
|
+ std::unordered_map<unsigned int, glslang::TIntermSymbol *> locationToSymbol[2];
|
|
};
|
|
};
|
|
|
|
|
|
//
|
|
//
|
|
@@ -375,6 +380,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
|
|
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
|
|
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
|
|
case glslang::EvqVaryingIn: return spv::DecorationBlock;
|
|
case glslang::EvqVaryingIn: return spv::DecorationBlock;
|
|
case glslang::EvqVaryingOut: return spv::DecorationBlock;
|
|
case glslang::EvqVaryingOut: return spv::DecorationBlock;
|
|
|
|
+ case glslang::EvqShared: return spv::DecorationBlock;
|
|
#ifndef GLSLANG_WEB
|
|
#ifndef GLSLANG_WEB
|
|
case glslang::EvqPayload: return spv::DecorationBlock;
|
|
case glslang::EvqPayload: return spv::DecorationBlock;
|
|
case glslang::EvqPayloadIn: return spv::DecorationBlock;
|
|
case glslang::EvqPayloadIn: return spv::DecorationBlock;
|
|
@@ -431,6 +437,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
|
|
break;
|
|
break;
|
|
case glslang::EbtBlock:
|
|
case glslang::EbtBlock:
|
|
switch (type.getQualifier().storage) {
|
|
switch (type.getQualifier().storage) {
|
|
|
|
+ case glslang::EvqShared:
|
|
case glslang::EvqUniform:
|
|
case glslang::EvqUniform:
|
|
case glslang::EvqBuffer:
|
|
case glslang::EvqBuffer:
|
|
switch (type.getQualifier().layoutPacking) {
|
|
switch (type.getQualifier().layoutPacking) {
|
|
@@ -539,6 +546,20 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl
|
|
return spv::DecorationMax;
|
|
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(
|
|
spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(
|
|
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
|
|
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
|
|
{
|
|
{
|
|
@@ -614,6 +635,7 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere
|
|
flags.volatil;
|
|
flags.volatil;
|
|
flags.isImage = type.getBasicType() == glslang::EbtSampler;
|
|
flags.isImage = type.getBasicType() == glslang::EbtSampler;
|
|
#endif
|
|
#endif
|
|
|
|
+ flags.nonUniform = type.getQualifier().nonUniform;
|
|
return flags;
|
|
return flags;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -709,13 +731,20 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|
return spv::BuiltInCullDistance;
|
|
return spv::BuiltInCullDistance;
|
|
|
|
|
|
case glslang::EbvViewportIndex:
|
|
case glslang::EbvViewportIndex:
|
|
- builder.addCapability(spv::CapabilityMultiViewport);
|
|
|
|
|
|
+ if (glslangIntermediate->getStage() == EShLangGeometry ||
|
|
|
|
+ glslangIntermediate->getStage() == EShLangFragment) {
|
|
|
|
+ builder.addCapability(spv::CapabilityMultiViewport);
|
|
|
|
+ }
|
|
if (glslangIntermediate->getStage() == EShLangVertex ||
|
|
if (glslangIntermediate->getStage() == EShLangVertex ||
|
|
glslangIntermediate->getStage() == EShLangTessControl ||
|
|
glslangIntermediate->getStage() == EShLangTessControl ||
|
|
glslangIntermediate->getStage() == EShLangTessEvaluation) {
|
|
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;
|
|
return spv::BuiltInViewportIndex;
|
|
|
|
|
|
@@ -734,13 +763,19 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|
if (glslangIntermediate->getStage() == EShLangMeshNV) {
|
|
if (glslangIntermediate->getStage() == EShLangMeshNV) {
|
|
return spv::BuiltInLayer;
|
|
return spv::BuiltInLayer;
|
|
}
|
|
}
|
|
- builder.addCapability(spv::CapabilityGeometry);
|
|
|
|
|
|
+ if (glslangIntermediate->getStage() == EShLangGeometry ||
|
|
|
|
+ glslangIntermediate->getStage() == EShLangFragment) {
|
|
|
|
+ builder.addCapability(spv::CapabilityGeometry);
|
|
|
|
+ }
|
|
if (glslangIntermediate->getStage() == EShLangVertex ||
|
|
if (glslangIntermediate->getStage() == EShLangVertex ||
|
|
glslangIntermediate->getStage() == EShLangTessControl ||
|
|
glslangIntermediate->getStage() == EShLangTessControl ||
|
|
glslangIntermediate->getStage() == EShLangTessEvaluation) {
|
|
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;
|
|
return spv::BuiltInLayer;
|
|
|
|
|
|
@@ -769,6 +804,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|
builder.addCapability(spv::CapabilityStencilExportEXT);
|
|
builder.addCapability(spv::CapabilityStencilExportEXT);
|
|
return spv::BuiltInFragStencilRefEXT;
|
|
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::EbvInvocationId: return spv::BuiltInInvocationId;
|
|
case glslang::EbvTessLevelInner: return spv::BuiltInTessLevelInner;
|
|
case glslang::EbvTessLevelInner: return spv::BuiltInTessLevelInner;
|
|
case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter;
|
|
case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter;
|
|
@@ -963,7 +1008,17 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|
case glslang::EbvInstanceCustomIndex:
|
|
case glslang::EbvInstanceCustomIndex:
|
|
return spv::BuiltInInstanceCustomIndexKHR;
|
|
return spv::BuiltInInstanceCustomIndexKHR;
|
|
case glslang::EbvHitT:
|
|
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:
|
|
case glslang::EbvHitKind:
|
|
return spv::BuiltInHitKindKHR;
|
|
return spv::BuiltInHitKindKHR;
|
|
case glslang::EbvObjectToWorld:
|
|
case glslang::EbvObjectToWorld:
|
|
@@ -1071,6 +1126,10 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
|
|
builder.addCapability(spv::CapabilityStorageImageExtendedFormats);
|
|
builder.addCapability(spv::CapabilityStorageImageExtendedFormats);
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ case glslang::ElfR64ui:
|
|
|
|
+ case glslang::ElfR64i:
|
|
|
|
+ builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
|
|
|
+ builder.addCapability(spv::CapabilityInt64ImageEXT);
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1117,6 +1176,8 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
|
|
case glslang::ElfRg8ui: return spv::ImageFormatRg8ui;
|
|
case glslang::ElfRg8ui: return spv::ImageFormatRg8ui;
|
|
case glslang::ElfR16ui: return spv::ImageFormatR16ui;
|
|
case glslang::ElfR16ui: return spv::ImageFormatR16ui;
|
|
case glslang::ElfR8ui: return spv::ImageFormatR8ui;
|
|
case glslang::ElfR8ui: return spv::ImageFormatR8ui;
|
|
|
|
+ case glslang::ElfR64ui: return spv::ImageFormatR64ui;
|
|
|
|
+ case glslang::ElfR64i: return spv::ImageFormatR64i;
|
|
default: return spv::ImageFormatMax;
|
|
default: return spv::ImageFormatMax;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1187,7 +1248,7 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
|
|
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type)
|
|
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type)
|
|
{
|
|
{
|
|
if (type.getBasicType() == glslang::EbtRayQuery)
|
|
if (type.getBasicType() == glslang::EbtRayQuery)
|
|
- return spv::StorageClassFunction;
|
|
|
|
|
|
+ return spv::StorageClassPrivate;
|
|
if (type.getQualifier().isPipeInput())
|
|
if (type.getQualifier().isPipeInput())
|
|
return spv::StorageClassInput;
|
|
return spv::StorageClassInput;
|
|
if (type.getQualifier().isPipeOutput())
|
|
if (type.getQualifier().isPipeOutput())
|
|
@@ -1219,6 +1280,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
|
return spv::StorageClassUniformConstant;
|
|
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) {
|
|
switch (type.getQualifier().storage) {
|
|
case glslang::EvqGlobal: return spv::StorageClassPrivate;
|
|
case glslang::EvqGlobal: return spv::StorageClassPrivate;
|
|
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
|
|
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
|
|
@@ -1353,6 +1420,8 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
|
|
if (parent.writeonly)
|
|
if (parent.writeonly)
|
|
child.writeonly = true;
|
|
child.writeonly = true;
|
|
#endif
|
|
#endif
|
|
|
|
+ if (parent.nonUniform)
|
|
|
|
+ child.nonUniform = true;
|
|
}
|
|
}
|
|
|
|
|
|
bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier)
|
|
bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier)
|
|
@@ -1424,7 +1493,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|
|
|
|
|
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
|
|
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
|
|
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
|
|
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);
|
|
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
|
|
}
|
|
}
|
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
|
@@ -1454,7 +1523,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|
}
|
|
}
|
|
|
|
|
|
if (glslangIntermediate->getLayoutPrimitiveCulling()) {
|
|
if (glslangIntermediate->getLayoutPrimitiveCulling()) {
|
|
- builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
|
|
|
|
|
|
+ builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
|
|
}
|
|
}
|
|
|
|
|
|
unsigned int mode;
|
|
unsigned int mode;
|
|
@@ -1482,15 +1551,16 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
|
|
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
|
|
}
|
|
}
|
|
|
|
|
|
- if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
|
|
|
|
|
|
+ if (glslangIntermediate->isDepthReplacing())
|
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
|
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
|
|
|
|
|
|
#ifndef GLSLANG_WEB
|
|
#ifndef GLSLANG_WEB
|
|
|
|
|
|
switch(glslangIntermediate->getDepth()) {
|
|
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)
|
|
if (mode != spv::ExecutionModeMax)
|
|
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
|
|
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
|
|
@@ -1621,7 +1691,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|
{
|
|
{
|
|
auto& extensions = glslangIntermediate->getRequestedExtensions();
|
|
auto& extensions = glslangIntermediate->getRequestedExtensions();
|
|
if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
|
|
if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
|
|
- builder.addCapability(spv::CapabilityRayTracingProvisionalKHR);
|
|
|
|
|
|
+ builder.addCapability(spv::CapabilityRayTracingKHR);
|
|
builder.addExtension("SPV_KHR_ray_tracing");
|
|
builder.addExtension("SPV_KHR_ray_tracing");
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
@@ -1710,6 +1780,12 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
|
if (symbol->getType().getQualifier().isSpecConstant())
|
|
if (symbol->getType().getQualifier().isSpecConstant())
|
|
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
|
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.
|
|
// getSymbolId() will set up all the IO decorations on the first call.
|
|
// Formal function parameters were mapped during makeFunctions().
|
|
// Formal function parameters were mapped during makeFunctions().
|
|
spv::Id id = getSymbolId(symbol);
|
|
spv::Id id = getSymbolId(symbol);
|
|
@@ -1852,9 +1928,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
|
|
spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
|
|
|
|
|
|
// do the operation
|
|
// do the operation
|
|
|
|
+ spv::Builder::AccessChain::CoherentFlags coherentFlags = TranslateCoherent(node->getLeft()->getType());
|
|
|
|
+ coherentFlags |= TranslateCoherent(node->getRight()->getType());
|
|
OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
|
|
OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
|
|
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
|
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
|
- TranslateNonUniformDecoration(node->getType().getQualifier()) };
|
|
|
|
|
|
+ TranslateNonUniformDecoration(coherentFlags) };
|
|
rValue = createBinaryOperation(node->getOp(), decorations,
|
|
rValue = createBinaryOperation(node->getOp(), decorations,
|
|
convertGlslangToSpvType(node->getType()), leftRValue, rValue,
|
|
convertGlslangToSpvType(node->getType()), leftRValue, rValue,
|
|
node->getType().getBasicType());
|
|
node->getType().getBasicType());
|
|
@@ -1885,13 +1963,16 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
if (! node->getLeft()->getType().isArray() &&
|
|
if (! node->getLeft()->getType().isArray() &&
|
|
node->getLeft()->getType().isVector() &&
|
|
node->getLeft()->getType().isVector() &&
|
|
node->getOp() == glslang::EOpIndexDirect) {
|
|
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,
|
|
// This is essentially a hard-coded vector swizzle of size 1,
|
|
// so short circuit the access-chain stuff with a swizzle.
|
|
// so short circuit the access-chain stuff with a swizzle.
|
|
std::vector<unsigned> swizzle;
|
|
std::vector<unsigned> swizzle;
|
|
swizzle.push_back(glslangIndex);
|
|
swizzle.push_back(glslangIndex);
|
|
int dummySize;
|
|
int dummySize;
|
|
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
|
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
|
- TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
|
|
+ coherentFlags,
|
|
glslangIntermediate->getBaseAlignmentScalar(
|
|
glslangIntermediate->getBaseAlignmentScalar(
|
|
node->getLeft()->getType(), dummySize));
|
|
node->getLeft()->getType(), dummySize));
|
|
} else {
|
|
} else {
|
|
@@ -1914,7 +1995,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
{
|
|
{
|
|
// This may be, e.g., an anonymous block-member selection, which generally need
|
|
// This may be, e.g., an anonymous block-member selection, which generally need
|
|
// index remapping due to hidden members in anonymous blocks.
|
|
// 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()) {
|
|
if (memberRemapper.find(glslangId) != memberRemapper.end()) {
|
|
std::vector<int>& remapper = memberRemapper[glslangId];
|
|
std::vector<int>& remapper = memberRemapper[glslangId];
|
|
assert(remapper.size() > 0);
|
|
assert(remapper.size() > 0);
|
|
@@ -1922,9 +2003,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
|
|
// normal case for indexing array or structure or block
|
|
builder.accessChainPush(builder.makeIntConstant(spvIndex),
|
|
builder.accessChainPush(builder.makeIntConstant(spvIndex),
|
|
- TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
|
|
+ coherentFlags,
|
|
node->getLeft()->getType().getBufferReferenceAlignment());
|
|
node->getLeft()->getType().getBufferReferenceAlignment());
|
|
|
|
|
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
|
@@ -1958,15 +2044,20 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
// restore the saved access chain
|
|
// restore the saved access chain
|
|
builder.setAccessChain(partial);
|
|
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()) {
|
|
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) {
|
|
int dummySize;
|
|
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(),
|
|
glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
|
|
dummySize));
|
|
dummySize));
|
|
} else
|
|
} else
|
|
- builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
- node->getLeft()->getType().getBufferReferenceAlignment());
|
|
|
|
|
|
+ builder.accessChainPush(index, coherent_flags,
|
|
|
|
+ node->getLeft()->getType().getBufferReferenceAlignment());
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
case glslang::EOpVectorSwizzle:
|
|
case glslang::EOpVectorSwizzle:
|
|
@@ -2050,8 +2141,9 @@ std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuil
|
|
// these require changing a 64-bit scaler -> a vector of 32-bit components
|
|
// these require changing a 64-bit scaler -> a vector of 32-bit components
|
|
if (glslangType.isVector())
|
|
if (glslangType.isVector())
|
|
break;
|
|
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;
|
|
return ret;
|
|
}
|
|
}
|
|
// There are no SPIR-V builtins defined for these and map onto original non-transposed
|
|
// There are no SPIR-V builtins defined for these and map onto original non-transposed
|
|
@@ -2090,7 +2182,7 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
|
|
// handle 32-bit v.xy* -> 64-bit
|
|
// handle 32-bit v.xy* -> 64-bit
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
builder.setAccessChainLValue(object);
|
|
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;
|
|
std::vector<spv::Id> components;
|
|
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 0));
|
|
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 0));
|
|
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 1));
|
|
components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 1));
|
|
@@ -2106,7 +2198,7 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
|
|
// and we insert a transpose after loading the original non-transposed builtins
|
|
// and we insert a transpose after loading the original non-transposed builtins
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
builder.setAccessChainLValue(object);
|
|
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);
|
|
return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object);
|
|
|
|
|
|
} else {
|
|
} else {
|
|
@@ -2292,7 +2384,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|
|
|
|
|
// The result of operation is always stored, but conditionally the
|
|
// The result of operation is always stored, but conditionally the
|
|
// consumed result. The consumed result is always an r-value.
|
|
// consumed result. The consumed result is always an r-value.
|
|
- builder.accessChainStore(result);
|
|
|
|
|
|
+ builder.accessChainStore(result,
|
|
|
|
+ TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags));
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
if (node->getOp() == glslang::EOpPreIncrement ||
|
|
if (node->getOp() == glslang::EOpPreIncrement ||
|
|
node->getOp() == glslang::EOpPreDecrement)
|
|
node->getOp() == glslang::EOpPreDecrement)
|
|
@@ -2421,6 +2514,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
// anything else gets there, so visit out of order, doing them all now.
|
|
// anything else gets there, so visit out of order, doing them all now.
|
|
makeGlobalInitializers(node->getAsAggregate()->getSequence());
|
|
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,
|
|
// Initializers are done, don't want to visit again, but functions and link objects need to be processed,
|
|
// so do them manually.
|
|
// so do them manually.
|
|
visitFunctions(node->getAsAggregate()->getSequence());
|
|
visitFunctions(node->getAsAggregate()->getSequence());
|
|
@@ -2611,6 +2708,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
else
|
|
else
|
|
constructed = builder.createConstructor(precision, arguments, resultType());
|
|
constructed = builder.createConstructor(precision, arguments, resultType());
|
|
|
|
|
|
|
|
+ if (node->getType().getQualifier().isNonUniform()) {
|
|
|
|
+ builder.addDecoration(constructed, spv::DecorationNonUniformEXT);
|
|
|
|
+ }
|
|
|
|
+
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
builder.setAccessChainRValue(constructed);
|
|
builder.setAccessChainRValue(constructed);
|
|
|
|
|
|
@@ -2683,6 +2784,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
break;
|
|
break;
|
|
|
|
|
|
case glslang::EOpAtomicAdd:
|
|
case glslang::EOpAtomicAdd:
|
|
|
|
+ case glslang::EOpAtomicSubtract:
|
|
case glslang::EOpAtomicMin:
|
|
case glslang::EOpAtomicMin:
|
|
case glslang::EOpAtomicMax:
|
|
case glslang::EOpAtomicMax:
|
|
case glslang::EOpAtomicAnd:
|
|
case glslang::EOpAtomicAnd:
|
|
@@ -2726,10 +2828,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
binOp = node->getOp();
|
|
binOp = node->getOp();
|
|
break;
|
|
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:
|
|
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
|
|
noReturnValue = true;
|
|
noReturnValue = true;
|
|
break;
|
|
break;
|
|
@@ -2738,7 +2842,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
case glslang::EOpRayQueryGenerateIntersection:
|
|
case glslang::EOpRayQueryGenerateIntersection:
|
|
case glslang::EOpRayQueryConfirmIntersection:
|
|
case glslang::EOpRayQueryConfirmIntersection:
|
|
builder.addExtension("SPV_KHR_ray_query");
|
|
builder.addExtension("SPV_KHR_ray_query");
|
|
- builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
|
|
|
|
|
|
+ builder.addCapability(spv::CapabilityRayQueryKHR);
|
|
noReturnValue = true;
|
|
noReturnValue = true;
|
|
break;
|
|
break;
|
|
case glslang::EOpRayQueryProceed:
|
|
case glslang::EOpRayQueryProceed:
|
|
@@ -2761,7 +2865,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
case glslang::EOpRayQueryGetIntersectionObjectToWorld:
|
|
case glslang::EOpRayQueryGetIntersectionObjectToWorld:
|
|
case glslang::EOpRayQueryGetIntersectionWorldToObject:
|
|
case glslang::EOpRayQueryGetIntersectionWorldToObject:
|
|
builder.addExtension("SPV_KHR_ray_query");
|
|
builder.addExtension("SPV_KHR_ray_query");
|
|
- builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
|
|
|
|
|
|
+ builder.addCapability(spv::CapabilityRayQueryKHR);
|
|
break;
|
|
break;
|
|
case glslang::EOpCooperativeMatrixLoad:
|
|
case glslang::EOpCooperativeMatrixLoad:
|
|
case glslang::EOpCooperativeMatrixStore:
|
|
case glslang::EOpCooperativeMatrixStore:
|
|
@@ -2852,6 +2956,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
break;
|
|
break;
|
|
|
|
|
|
case glslang::EOpAtomicAdd:
|
|
case glslang::EOpAtomicAdd:
|
|
|
|
+ case glslang::EOpAtomicSubtract:
|
|
case glslang::EOpAtomicMin:
|
|
case glslang::EOpAtomicMin:
|
|
case glslang::EOpAtomicMax:
|
|
case glslang::EOpAtomicMax:
|
|
case glslang::EOpAtomicAnd:
|
|
case glslang::EOpAtomicAnd:
|
|
@@ -3014,11 +3119,18 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
)) {
|
|
)) {
|
|
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
|
|
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
|
|
operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
|
|
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()));
|
|
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3054,7 +3166,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
#endif
|
|
#endif
|
|
if (atomic) {
|
|
if (atomic) {
|
|
// Handle all atomics
|
|
// 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);
|
|
lvalueCoherentFlags);
|
|
} else if (node->getOp() == glslang::EOpDebugPrintf) {
|
|
} else if (node->getOp() == glslang::EOpDebugPrintf) {
|
|
if (!nonSemanticDebugPrintf) {
|
|
if (!nonSemanticDebugPrintf) {
|
|
@@ -3089,7 +3203,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
|
|
|
|
for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
|
|
for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
|
|
builder.setAccessChain(complexLvalues[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 +3535,11 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
|
|
|
|
|
switch (node->getFlowOp()) {
|
|
switch (node->getFlowOp()) {
|
|
case glslang::EOpKill:
|
|
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;
|
|
break;
|
|
case glslang::EOpBreak:
|
|
case glslang::EOpBreak:
|
|
if (breakForLoop.top())
|
|
if (breakForLoop.top())
|
|
@@ -3457,6 +3576,12 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
|
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
|
|
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
|
|
builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
|
|
builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
|
|
break;
|
|
break;
|
|
|
|
+ case glslang::EOpTerminateRayKHR:
|
|
|
|
+ builder.makeStatementTerminator(spv::OpTerminateRayKHR, "post-terminateRayKHR");
|
|
|
|
+ break;
|
|
|
|
+ case glslang::EOpIgnoreIntersectionKHR:
|
|
|
|
+ builder.makeStatementTerminator(spv::OpIgnoreIntersectionKHR, "post-ignoreIntersectionKHR");
|
|
|
|
+ break;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -3511,6 +3636,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
default:
|
|
default:
|
|
|
|
+ if (storageClass == spv::StorageClassWorkgroup &&
|
|
|
|
+ node->getType().getBasicType() == glslang::EbtBlock) {
|
|
|
|
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
if (node->getType().contains16BitFloat())
|
|
if (node->getType().contains16BitFloat())
|
|
builder.addCapability(spv::CapabilityFloat16);
|
|
builder.addCapability(spv::CapabilityFloat16);
|
|
if (node->getType().contains16BitInt())
|
|
if (node->getType().contains16BitInt())
|
|
@@ -3529,6 +3659,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|
} else if (storageClass == spv::StorageClassStorageBuffer) {
|
|
} else if (storageClass == spv::StorageClassStorageBuffer) {
|
|
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
|
|
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
|
|
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
|
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
|
|
|
+ } else if (storageClass == spv::StorageClassWorkgroup &&
|
|
|
|
+ node->getType().getBasicType() == glslang::EbtBlock) {
|
|
|
|
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
|
|
} else {
|
|
} else {
|
|
builder.addCapability(spv::CapabilityInt8);
|
|
builder.addCapability(spv::CapabilityInt8);
|
|
}
|
|
}
|
|
@@ -3540,13 +3673,14 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|
|
|
|
|
spv::Id initializer = spv::NoResult;
|
|
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);
|
|
return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
|
|
@@ -3564,6 +3698,12 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
|
|
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
|
|
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
|
|
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
|
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
|
return builder.makeFloatType(16);
|
|
return builder.makeFloatType(16);
|
|
|
|
+ case glslang::EbtInt64: return builder.makeIntType(64);
|
|
|
|
+ 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
|
|
#endif
|
|
default:
|
|
default:
|
|
assert(0);
|
|
assert(0);
|
|
@@ -3670,10 +3810,36 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|
spvType = builder.makeUintType(32);
|
|
spvType = builder.makeUintType(32);
|
|
break;
|
|
break;
|
|
case glslang::EbtAccStruct:
|
|
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();
|
|
spvType = builder.makeAccelerationStructureType();
|
|
break;
|
|
break;
|
|
case glslang::EbtRayQuery:
|
|
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;
|
|
break;
|
|
case glslang::EbtReference:
|
|
case glslang::EbtReference:
|
|
{
|
|
{
|
|
@@ -3929,6 +4095,8 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|
// Name and decorate the non-hidden members
|
|
// Name and decorate the non-hidden members
|
|
int offset = -1;
|
|
int offset = -1;
|
|
int locationOffset = 0; // for use within the members of this struct
|
|
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++) {
|
|
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
|
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
|
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
|
int member = i;
|
|
int member = i;
|
|
@@ -3981,7 +4149,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|
// just track whether a member needs to be decorated.
|
|
// just track whether a member needs to be decorated.
|
|
// Ignore member locations if the container is an array, as that's
|
|
// Ignore member locations if the container is an array, as that's
|
|
// ill-specified and decisions have been made to not allow this.
|
|
// 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);
|
|
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
|
|
|
|
|
if (qualifier.hasLocation()) // track for upcoming inheritance
|
|
if (qualifier.hasLocation()) // track for upcoming inheritance
|
|
@@ -4087,6 +4255,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
|
alignment |= type.getBufferReferenceAlignment();
|
|
alignment |= type.getBufferReferenceAlignment();
|
|
|
|
|
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
|
|
|
+ TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags),
|
|
TranslateNonUniformDecoration(type.getQualifier()),
|
|
TranslateNonUniformDecoration(type.getQualifier()),
|
|
nominalTypeId,
|
|
nominalTypeId,
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
|
@@ -4154,7 +4323,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
|
|
unsigned int alignment = builder.getAccessChain().alignment;
|
|
unsigned int alignment = builder.getAccessChain().alignment;
|
|
alignment |= type.getBufferReferenceAlignment();
|
|
alignment |= type.getBufferReferenceAlignment();
|
|
|
|
|
|
- builder.accessChainStore(rvalue,
|
|
|
|
|
|
+ builder.accessChainStore(rvalue, TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags),
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
|
|
~spv::MemoryAccessMakePointerVisibleKHRMask),
|
|
~spv::MemoryAccessMakePointerVisibleKHRMask),
|
|
TranslateMemoryScope(coherentFlags), alignment);
|
|
TranslateMemoryScope(coherentFlags), alignment);
|
|
@@ -4259,6 +4428,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
|
|
// has to be a uniform or buffer block or task in/out blocks
|
|
// has to be a uniform or buffer block or task in/out blocks
|
|
if (type.getQualifier().storage != glslang::EvqUniform &&
|
|
if (type.getQualifier().storage != glslang::EvqUniform &&
|
|
type.getQualifier().storage != glslang::EvqBuffer &&
|
|
type.getQualifier().storage != glslang::EvqBuffer &&
|
|
|
|
+ type.getQualifier().storage != glslang::EvqShared &&
|
|
!type.getQualifier().isTaskMemory())
|
|
!type.getQualifier().isTaskMemory())
|
|
return glslang::ElpNone;
|
|
return glslang::ElpNone;
|
|
|
|
|
|
@@ -4542,7 +4712,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.
|
|
// Process all the functions, while skipping initializers.
|
|
void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions)
|
|
void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions)
|
|
{
|
|
{
|
|
@@ -4686,8 +4888,10 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
|
|
}
|
|
}
|
|
|
|
|
|
if (lvalue) {
|
|
if (lvalue) {
|
|
- arguments.push_back(builder.accessChainGetLValue());
|
|
|
|
|
|
+ spv::Id lvalue_id = builder.accessChainGetLValue();
|
|
|
|
+ arguments.push_back(lvalue_id);
|
|
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
|
|
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
|
|
|
|
+ builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags));
|
|
lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType());
|
|
lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType());
|
|
} else
|
|
} else
|
|
#endif
|
|
#endif
|
|
@@ -4750,12 +4954,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|
|
|
|
|
const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint;
|
|
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
|
|
// Check for queries
|
|
if (cracked.query) {
|
|
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()) {
|
|
switch (node->getOp()) {
|
|
case glslang::EOpImageQuerySize:
|
|
case glslang::EOpImageQuerySize:
|
|
case glslang::EOpTextureQuerySize:
|
|
case glslang::EOpTextureQuerySize:
|
|
@@ -5009,10 +5216,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|
auto opIt = arguments.begin();
|
|
auto opIt = arguments.begin();
|
|
std::vector<spv::Id> operands;
|
|
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);
|
|
operands.push_back(params.sampler);
|
|
++opIt;
|
|
++opIt;
|
|
|
|
|
|
@@ -5073,13 +5276,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|
bias = true;
|
|
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
|
|
#ifndef GLSLANG_WEB
|
|
if (cracked.gather) {
|
|
if (cracked.gather) {
|
|
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
|
|
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
|
|
@@ -5239,7 +5435,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|
|
|
|
|
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
|
|
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
|
|
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
|
|
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
|
|
- i+1));
|
|
|
|
|
|
+ i+1), TranslateNonUniformDecoration(imageType.getQualifier()));
|
|
}
|
|
}
|
|
return builder.createCompositeExtract(res, resultType(), 0);
|
|
return builder.createCompositeExtract(res, resultType(), 0);
|
|
}
|
|
}
|
|
@@ -5375,6 +5571,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
|
// 3. Make the call.
|
|
// 3. Make the call.
|
|
spv::Id result = builder.createFunctionCall(function, spvArgs);
|
|
spv::Id result = builder.createFunctionCall(function, spvArgs);
|
|
builder.setPrecision(result, TranslatePrecisionDecoration(node->getType()));
|
|
builder.setPrecision(result, TranslatePrecisionDecoration(node->getType()));
|
|
|
|
+ builder.addDecoration(result, TranslateNonUniformDecoration(node->getType().getQualifier()));
|
|
|
|
|
|
// 4. Copy back out an "out" arguments.
|
|
// 4. Copy back out an "out" arguments.
|
|
lValueCount = 0;
|
|
lValueCount = 0;
|
|
@@ -5384,6 +5581,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
|
else if (writableParam(qualifiers[a])) {
|
|
else if (writableParam(qualifiers[a])) {
|
|
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
|
|
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
|
|
spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision);
|
|
spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision);
|
|
|
|
+ builder.addDecoration(copy, TranslateNonUniformDecoration(argTypes[a]->getQualifier()));
|
|
builder.setAccessChain(lValues[lValueCount]);
|
|
builder.setAccessChain(lValues[lValueCount]);
|
|
multiTypeStore(*argTypes[a], copy);
|
|
multiTypeStore(*argTypes[a], copy);
|
|
}
|
|
}
|
|
@@ -6171,6 +6369,11 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
|
|
case glslang::EOpConstructReference:
|
|
case glslang::EOpConstructReference:
|
|
unaryOp = spv::OpBitcast;
|
|
unaryOp = spv::OpBitcast;
|
|
break;
|
|
break;
|
|
|
|
+
|
|
|
|
+ case glslang::EOpConvUint64ToAccStruct:
|
|
|
|
+ case glslang::EOpConvUvec2ToAccStruct:
|
|
|
|
+ unaryOp = spv::OpConvertUToAccelerationStructureKHR;
|
|
|
|
+ break;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
case glslang::EOpCopyObject:
|
|
case glslang::EOpCopyObject:
|
|
@@ -6633,9 +6836,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
|
|
break;
|
|
break;
|
|
case glslang::EOpConvPtrToUvec2:
|
|
case glslang::EOpConvPtrToUvec2:
|
|
case glslang::EOpConvUvec2ToPtr:
|
|
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;
|
|
convOp = spv::OpBitcast;
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
@@ -6693,6 +6893,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|
builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
|
|
builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case glslang::EOpAtomicSubtract:
|
|
case glslang::EOpAtomicCounterSubtract:
|
|
case glslang::EOpAtomicCounterSubtract:
|
|
opCode = spv::OpAtomicISub;
|
|
opCode = spv::OpAtomicISub;
|
|
break;
|
|
break;
|
|
@@ -6815,6 +7016,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (builder.getConstantScalar(scopeId) == spv::ScopeQueueFamily) {
|
|
|
|
+ builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
|
|
if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
|
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
|
}
|
|
}
|
|
@@ -7757,10 +7962,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|
typeId = builder.makeBoolType();
|
|
typeId = builder.makeBoolType();
|
|
opCode = spv::OpReportIntersectionKHR;
|
|
opCode = spv::OpReportIntersectionKHR;
|
|
break;
|
|
break;
|
|
- case glslang::EOpTrace:
|
|
|
|
|
|
+ case glslang::EOpTraceNV:
|
|
|
|
+ builder.createNoResultOp(spv::OpTraceNV, operands);
|
|
|
|
+ return 0;
|
|
|
|
+ case glslang::EOpTraceKHR:
|
|
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
|
|
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
|
|
return 0;
|
|
return 0;
|
|
- case glslang::EOpExecuteCallable:
|
|
|
|
|
|
+ case glslang::EOpExecuteCallableNV:
|
|
|
|
+ builder.createNoResultOp(spv::OpExecuteCallableNV, operands);
|
|
|
|
+ return 0;
|
|
|
|
+ case glslang::EOpExecuteCallableKHR:
|
|
builder.createNoResultOp(spv::OpExecuteCallableKHR, operands);
|
|
builder.createNoResultOp(spv::OpExecuteCallableKHR, operands);
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -7805,7 +8016,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|
opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
|
|
opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
|
|
break;
|
|
break;
|
|
case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
|
|
case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
|
|
- typeId = builder.makeIntType(32);
|
|
|
|
|
|
+ typeId = builder.makeUintType(32);
|
|
opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
|
|
opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
|
|
break;
|
|
break;
|
|
case glslang::EOpRayQueryGetIntersectionGeometryIndex:
|
|
case glslang::EOpRayQueryGetIntersectionGeometryIndex:
|
|
@@ -8048,11 +8259,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);
|
|
spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
|
|
return builder.setPrecision(id, precision);
|
|
return builder.setPrecision(id, precision);
|
|
}
|
|
}
|
|
- case glslang::EOpIgnoreIntersection:
|
|
|
|
- builder.createNoResultOp(spv::OpIgnoreIntersectionKHR);
|
|
|
|
|
|
+ case glslang::EOpIgnoreIntersectionNV:
|
|
|
|
+ builder.createNoResultOp(spv::OpIgnoreIntersectionNV);
|
|
return 0;
|
|
return 0;
|
|
- case glslang::EOpTerminateRay:
|
|
|
|
- builder.createNoResultOp(spv::OpTerminateRayKHR);
|
|
|
|
|
|
+ case glslang::EOpTerminateRayNV:
|
|
|
|
+ builder.createNoResultOp(spv::OpTerminateRayNV);
|
|
return 0;
|
|
return 0;
|
|
case glslang::EOpRayQueryInitialize:
|
|
case glslang::EOpRayQueryInitialize:
|
|
builder.createNoResultOp(spv::OpRayQueryInitializeKHR);
|
|
builder.createNoResultOp(spv::OpRayQueryInitializeKHR);
|
|
@@ -8180,7 +8391,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|
}
|
|
}
|
|
|
|
|
|
#ifndef GLSLANG_WEB
|
|
#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;
|
|
std::vector<spv::Decoration> memory;
|
|
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory,
|
|
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory,
|
|
glslangIntermediate->usingVulkanMemoryModel());
|
|
glslangIntermediate->usingVulkanMemoryModel());
|
|
@@ -8188,9 +8400,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|
builder.addDecoration(id, memory[i]);
|
|
builder.addDecoration(id, memory[i]);
|
|
}
|
|
}
|
|
|
|
|
|
- // nonuniform
|
|
|
|
- builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier()));
|
|
|
|
-
|
|
|
|
if (builtIn == spv::BuiltInSampleMask) {
|
|
if (builtIn == spv::BuiltInSampleMask) {
|
|
spv::Decoration decoration;
|
|
spv::Decoration decoration;
|
|
// GL_NV_sample_mask_override_coverage extension
|
|
// GL_NV_sample_mask_override_coverage extension
|