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.
This commit is contained in:
John Kessenich 2019-08-18 23:58:08 -06:00
parent aaff6cddd0
commit 8317e6c683
6 changed files with 43 additions and 31 deletions

View File

@ -217,11 +217,6 @@ protected:
bool isTrivial(const glslang::TIntermTyped* node); bool isTrivial(const glslang::TIntermTyped* node);
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right); spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
spv::Id getExtBuiltins(const char* name); 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&); std::pair<spv::Id, spv::Id> getForcedType(spv::BuiltIn, const glslang::TType&);
spv::Id translateForcedType(spv::Id object); spv::Id translateForcedType(spv::Id object);
spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents); spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
@ -517,7 +512,7 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl
{ {
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (qualifier.isNonUniform()) { if (qualifier.isNonUniform()) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderNonUniformEXT); builder.addCapability(spv::CapabilityShaderNonUniformEXT);
return spv::DecorationNonUniformEXT; return spv::DecorationNonUniformEXT;
} else } else
@ -701,7 +696,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) { 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); builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
} }
return spv::BuiltInViewportIndex; return spv::BuiltInViewportIndex;
@ -726,23 +721,23 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessControl ||
glslangIntermediate->getStage() == EShLangTessEvaluation) { 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); builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);
} }
return spv::BuiltInLayer; return spv::BuiltInLayer;
case glslang::EbvBaseVertex: 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); builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseVertex; return spv::BuiltInBaseVertex;
case glslang::EbvBaseInstance: 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); builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseInstance; return spv::BuiltInBaseInstance;
case glslang::EbvDrawId: 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); builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInDrawIndex; return spv::BuiltInDrawIndex;
@ -874,12 +869,12 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInBaryCoordPullModelAMD; return spv::BuiltInBaryCoordPullModelAMD;
case glslang::EbvDeviceIndex: 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); builder.addCapability(spv::CapabilityDeviceGroup);
return spv::BuiltInDeviceIndex; return spv::BuiltInDeviceIndex;
case glslang::EbvViewIndex: case glslang::EbvViewIndex:
addPre13Extension(spv::E_SPV_KHR_multiview); builder.addIncorporatedExtension(spv::E_SPV_KHR_multiview, spv::Spv_1_3);
builder.addCapability(spv::CapabilityMultiView); builder.addCapability(spv::CapabilityMultiView);
return spv::BuiltInViewIndex; return spv::BuiltInViewIndex;
@ -1192,7 +1187,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
} }
if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) { 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; return spv::StorageClassStorageBuffer;
} }
@ -1253,13 +1248,13 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
// assume a dynamically uniform index // assume a dynamically uniform index
if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getBasicType() == glslang::EbtSampler) {
if (baseType.getQualifier().hasAttachment()) { if (baseType.getQualifier().hasAttachment()) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT); builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT);
} else if (baseType.isImage() && baseType.getSampler().isBuffer()) { } 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); builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);
} else if (baseType.isTexture() && baseType.getSampler().isBuffer()) { } 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); builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);
} }
} }
@ -1404,13 +1399,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
if (glslangIntermediate->usingPhysicalStorageBuffer()) { if (glslangIntermediate->usingPhysicalStorageBuffer()) {
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT; 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); builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
}; };
if (glslangIntermediate->usingVulkanMemoryModel()) { if (glslangIntermediate->usingVulkanMemoryModel()) {
memoryModel = spv::MemoryModelVulkanKHR; memoryModel = spv::MemoryModelVulkanKHR;
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); 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); builder.setMemoryModel(addressingModel, memoryModel);
@ -3242,11 +3237,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
switch (storageClass) { switch (storageClass) {
case spv::StorageClassInput: case spv::StorageClassInput:
case spv::StorageClassOutput: 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); builder.addCapability(spv::CapabilityStorageInputOutput16);
break; break;
case spv::StorageClassUniform: 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) if (node->getType().getQualifier().storage == glslang::EvqBuffer)
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
else else
@ -3254,12 +3249,12 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
break; break;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
case spv::StorageClassPushConstant: 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); builder.addCapability(spv::CapabilityStoragePushConstant16);
break; break;
case spv::StorageClassStorageBuffer: case spv::StorageClassStorageBuffer:
case spv::StorageClassPhysicalStorageBufferEXT: 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); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
break; break;
#endif #endif
@ -3274,13 +3269,13 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
if (node->getType().contains8BitInt()) { if (node->getType().contains8BitInt()) {
if (storageClass == spv::StorageClassPushConstant) { 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); builder.addCapability(spv::CapabilityStoragePushConstant8);
} else if (storageClass == spv::StorageClassUniform) { } 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); builder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess);
} else if (storageClass == spv::StorageClassStorageBuffer) { } 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); builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
} else { } else {
builder.addCapability(spv::CapabilityInt8); builder.addCapability(spv::CapabilityInt8);
@ -3537,7 +3532,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
else { else {
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (!lastBufferBlockMember) { if (!lastBufferBlockMember) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT); builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
} }
spvType = builder.makeRuntimeArray(spvType); spvType = builder.makeRuntimeArray(spvType);

View File

@ -67,6 +67,7 @@ typedef enum {
Spv_1_2 = (1 << 16) | (2 << 8), Spv_1_2 = (1 << 16) | (2 << 8),
Spv_1_3 = (1 << 16) | (3 << 8), Spv_1_3 = (1 << 16) | (3 << 8),
Spv_1_4 = (1 << 16) | (4 << 8), Spv_1_4 = (1 << 16) | (4 << 8),
Spv_1_5 = (1 << 16) | (5 << 8),
} SpvVersion; } SpvVersion;
class Builder { class Builder {
@ -105,6 +106,11 @@ public:
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); } void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
void setEmitOpLines() { emitOpLines = true; } void setEmitOpLines() { emitOpLines = true; }
void addExtension(const char* ext) { extensions.insert(ext); } 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) void addInclude(const std::string& name, const std::string& text)
{ {
spv::Id incId = getStringId(name); spv::Id incId = getStringId(name);

View File

@ -363,12 +363,12 @@ void Builder::postProcess()
Instruction* type = groupedTypes[OpTypePointer][t]; Instruction* type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { 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); addCapability(spv::CapabilityStorageBuffer8BitAccess);
} }
if (containsType(type->getIdOperand(1), OpTypeInt, 16) || if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
containsType(type->getIdOperand(1), OpTypeFloat, 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); addCapability(spv::CapabilityStorageBuffer16BitAccess);
} }
} }

View File

@ -615,8 +615,12 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
} else if (strcmp(argv[1], "spirv1.4") == 0) { } else if (strcmp(argv[1], "spirv1.4") == 0) {
TargetLanguage = glslang::EShTargetSpv; TargetLanguage = glslang::EShTargetSpv;
TargetVersion = glslang::EShTargetSpv_1_4; TargetVersion = glslang::EShTargetSpv_1_4;
} else if (strcmp(argv[1], "spirv1.5") == 0) {
TargetLanguage = glslang::EShTargetSpv;
TargetVersion = glslang::EShTargetSpv_1_5;
} else } 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(); bumpArg();
} else if (lowerword == "variable-name" || // synonyms } else if (lowerword == "variable-name" || // synonyms
@ -1618,7 +1622,7 @@ void usage()
" --stdin read from stdin instead of from a file;\n" " --stdin read from stdin instead of from a file;\n"
" requires providing the shader stage using -S\n" " requires providing the shader stage using -S\n"
" --target-env {vulkan1.0 | vulkan1.1 | opengl | \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" " set execution environment that emitted code\n"
" will execute in (versus source language\n" " will execute in (versus source language\n"
" semantics selected by --client) defaults:\n" " semantics selected by --client) defaults:\n"

View File

@ -308,6 +308,12 @@ public:
case EShTargetSpv_1_3: case EShTargetSpv_1_3:
processes.addProcess("target-env spirv1.3"); processes.addProcess("target-env spirv1.3");
break; break;
case EShTargetSpv_1_4:
processes.addProcess("target-env spirv1.4");
break;
case EShTargetSpv_1_5:
processes.addProcess("target-env spirv1.5");
break;
default: default:
processes.addProcess("target-env spirvUnknown"); processes.addProcess("target-env spirvUnknown");
break; break;

View File

@ -156,6 +156,7 @@ typedef enum {
EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2 EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
} EShTargetLanguageVersion; } EShTargetLanguageVersion;
struct TInputLanguage { struct TInputLanguage {