SPV: Support SPIR-V 1.5; five extensions no longer need OpExtension.
The generalization to addIncorporatedExtension() also fixed a 1.3
corner case with SPV_KHR_16bit_storage.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 2c9fcd8..4edd8f6 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -217,11 +217,6 @@
bool isTrivial(const glslang::TIntermTyped* node);
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
spv::Id getExtBuiltins(const char* name);
- void addPre13Extension(const char* ext)
- {
- if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
- builder.addExtension(ext);
- }
std::pair<spv::Id, spv::Id> getForcedType(spv::BuiltIn, const glslang::TType&);
spv::Id translateForcedType(spv::Id object);
spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
@@ -517,7 +512,7 @@
{
#ifndef GLSLANG_WEB
if (qualifier.isNonUniform()) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderNonUniformEXT);
return spv::DecorationNonUniformEXT;
} else
@@ -701,7 +696,7 @@
glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) {
- builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer);
+ builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
}
return spv::BuiltInViewportIndex;
@@ -726,23 +721,23 @@
glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) {
- builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer);
+ builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
}
return spv::BuiltInLayer;
case glslang::EbvBaseVertex:
- addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseVertex;
case glslang::EbvBaseInstance:
- addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseInstance;
case glslang::EbvDrawId:
- addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInDrawIndex;
@@ -874,12 +869,12 @@
return spv::BuiltInBaryCoordPullModelAMD;
case glslang::EbvDeviceIndex:
- addPre13Extension(spv::E_SPV_KHR_device_group);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_device_group, spv::Spv_1_3);
builder.addCapability(spv::CapabilityDeviceGroup);
return spv::BuiltInDeviceIndex;
case glslang::EbvViewIndex:
- addPre13Extension(spv::E_SPV_KHR_multiview);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_multiview, spv::Spv_1_3);
builder.addCapability(spv::CapabilityMultiView);
return spv::BuiltInViewIndex;
@@ -1192,7 +1187,7 @@
}
if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) {
- addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_storage_buffer_storage_class, spv::Spv_1_3);
return spv::StorageClassStorageBuffer;
}
@@ -1253,13 +1248,13 @@
// assume a dynamically uniform index
if (baseType.getBasicType() == glslang::EbtSampler) {
if (baseType.getQualifier().hasAttachment()) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT);
} else if (baseType.isImage() && baseType.getSampler().isBuffer()) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);
} else if (baseType.isTexture() && baseType.getSampler().isBuffer()) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);
}
}
@@ -1404,13 +1399,13 @@
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
- builder.addExtension(spv::E_SPV_EXT_physical_storage_buffer);
+ builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
};
if (glslangIntermediate->usingVulkanMemoryModel()) {
memoryModel = spv::MemoryModelVulkanKHR;
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
- builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
builder.setMemoryModel(addressingModel, memoryModel);
@@ -3242,11 +3237,11 @@
switch (storageClass) {
case spv::StorageClassInput:
case spv::StorageClassOutput:
- addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
builder.addCapability(spv::CapabilityStorageInputOutput16);
break;
case spv::StorageClassUniform:
- addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
if (node->getType().getQualifier().storage == glslang::EvqBuffer)
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
else
@@ -3254,12 +3249,12 @@
break;
#ifndef GLSLANG_WEB
case spv::StorageClassPushConstant:
- addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
builder.addCapability(spv::CapabilityStoragePushConstant16);
break;
case spv::StorageClassStorageBuffer:
case spv::StorageClassPhysicalStorageBufferEXT:
- addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
break;
#endif
@@ -3274,13 +3269,13 @@
if (node->getType().contains8BitInt()) {
if (storageClass == spv::StorageClassPushConstant) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStoragePushConstant8);
} else if (storageClass == spv::StorageClassUniform) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess);
} else if (storageClass == spv::StorageClassStorageBuffer) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
} else {
builder.addCapability(spv::CapabilityInt8);
@@ -3537,7 +3532,7 @@
else {
#ifndef GLSLANG_WEB
if (!lastBufferBlockMember) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
}
spvType = builder.makeRuntimeArray(spvType);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index a99a0c3..bef7d3d 100644
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -67,6 +67,7 @@
Spv_1_2 = (1 << 16) | (2 << 8),
Spv_1_3 = (1 << 16) | (3 << 8),
Spv_1_4 = (1 << 16) | (4 << 8),
+ Spv_1_5 = (1 << 16) | (5 << 8),
} SpvVersion;
class Builder {
@@ -105,6 +106,11 @@
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
void setEmitOpLines() { emitOpLines = true; }
void addExtension(const char* ext) { extensions.insert(ext); }
+ void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion)
+ {
+ if (getSpvVersion() < static_cast<unsigned>(incorporatedVersion))
+ addExtension(ext);
+ }
void addInclude(const std::string& name, const std::string& text)
{
spv::Id incId = getStringId(name);
diff --git a/SPIRV/SpvPostProcess.cpp b/SPIRV/SpvPostProcess.cpp
index 18765a3..832ee3e 100644
--- a/SPIRV/SpvPostProcess.cpp
+++ b/SPIRV/SpvPostProcess.cpp
@@ -363,12 +363,12 @@
Instruction* type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
- addExtension(spv::E_SPV_KHR_8bit_storage);
+ addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
addCapability(spv::CapabilityStorageBuffer8BitAccess);
}
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
- addExtension(spv::E_SPV_KHR_16bit_storage);
+ addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
addCapability(spv::CapabilityStorageBuffer16BitAccess);
}
}
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 9fa311b..4be3a4f 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -615,8 +615,12 @@
} else if (strcmp(argv[1], "spirv1.4") == 0) {
TargetLanguage = glslang::EShTargetSpv;
TargetVersion = glslang::EShTargetSpv_1_4;
+ } else if (strcmp(argv[1], "spirv1.5") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_5;
} else
- Error("--target-env expected one of: vulkan1.0, vulkan1.1, opengl, spirv1.0, spirv1.1, spirv1.2, or spirv1.3");
+ Error("--target-env expected one of: vulkan1.0, vulkan1.1, opengl,\n"
+ "spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5");
}
bumpArg();
} else if (lowerword == "variable-name" || // synonyms
@@ -1618,7 +1622,7 @@
" --stdin read from stdin instead of from a file;\n"
" requires providing the shader stage using -S\n"
" --target-env {vulkan1.0 | vulkan1.1 | opengl | \n"
- " spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3}\n"
+ " spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 | spirv1.5}\n"
" set execution environment that emitted code\n"
" will execute in (versus source language\n"
" semantics selected by --client) defaults:\n"
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 77ed7c3..b2f6918 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -308,6 +308,12 @@
case EShTargetSpv_1_3:
processes.addProcess("target-env spirv1.3");
break;
+ case EShTargetSpv_1_4:
+ processes.addProcess("target-env spirv1.4");
+ break;
+ case EShTargetSpv_1_5:
+ processes.addProcess("target-env spirv1.5");
+ break;
default:
processes.addProcess("target-env spirvUnknown");
break;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index a3103c6..a071d78 100755
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -156,6 +156,7 @@
EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
+ EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
} EShTargetLanguageVersion;
struct TInputLanguage {