From 8317e6c6833c22f5d7890fcec185beebc4b9c5ab Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 18 Aug 2019 23:58:08 -0600 Subject: [PATCH] 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. --- SPIRV/GlslangToSpv.cpp | 49 ++++++++++++-------------- SPIRV/SpvBuilder.h | 6 ++++ SPIRV/SpvPostProcess.cpp | 4 +-- StandAlone/StandAlone.cpp | 8 +++-- glslang/MachineIndependent/localintermediate.h | 6 ++++ glslang/Public/ShaderLang.h | 1 + 6 files changed, 43 insertions(+), 31 deletions(-) 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 @@ protected: 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 getForcedType(spv::BuiltIn, const glslang::TType&); spv::Id translateForcedType(spv::Id object); spv::Id createCompositeConstruct(spv::Id typeId, std::vector constituents); @@ -517,7 +512,7 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl { #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 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI 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 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI 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 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI 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 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T } 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 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp // 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 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl 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 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* 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 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* 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 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* 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 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty 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 @@ typedef enum { 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 @@ public: 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(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 @@ void Builder::postProcess() 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 @@ void ProcessArguments(std::vector>& workItem } 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 @@ void usage() " --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 @@ public: 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 @@ typedef enum { 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 { -- 2.7.4