VK_KHR_spirv_1_4 enables SPIR-V 1.4 modules
authorDavid Neto <dneto@google.com>
Fri, 29 Mar 2019 15:23:49 +0000 (11:23 -0400)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 10 Oct 2019 13:21:13 +0000 (09:21 -0400)
In Vulkan 1.1, VK_KHR_spirv_1_4 enables SPIR-V 1.4 modules for assembly
and validation.  This is true even if the underlying Vulkan version doesn't
natively support SPIR-V 1.4.

Deprecates vk::getMaxSpirvVersionForGlsl and vk::getMaxSpirvVersionForAsm
in favour of unified vk::getMaxSpirvVersionForVulkan.

Components: Vulkan

VK-GL-CTS issue: 1712, 1711

Change-Id: I850ab4ec3a0d88485e838d4263d751b2d6e18c08
(cherry picked from commit a7db98c20a6dd4e2366e4fc3ddd368a1fa08b98e)
(cherry picked from commit 0d79d48c0d39989393062af77b475771bba97f80)

external/vulkancts/framework/vulkan/vkPrograms.cpp
external/vulkancts/framework/vulkan/vkPrograms.hpp
external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
external/vulkancts/framework/vulkan/vkSpirVProgram.hpp
external/vulkancts/framework/vulkan/vkValidatorOptions.hpp
external/vulkancts/modules/vulkan/vktTestPackage.cpp

index b470c1ef9da9277ed89d687014ebab569f29c352..03d85b2c6a690eea0e36e6852e18d6942d247393 100644 (file)
@@ -744,8 +744,8 @@ vk::SpirvVersion getBaselineSpirvVersion (const deUint32 /* vulkanVersion */)
        return vk::SPIRV_VERSION_1_0;
 }
 
-// Max supported versions for each vulkan version, without requiring a Vulkan extension.
-vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion)
+// Max supported versions for each Vulkan version, without requiring a Vulkan extension.
+vk::SpirvVersion getMaxSpirvVersionForVulkan (const deUint32 vulkanVersion)
 {
        vk::SpirvVersion        result                  = vk::SPIRV_VERSION_LAST;
 
@@ -760,19 +760,14 @@ vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion)
        return result;
 }
 
-vk::SpirvVersion getMaxSpirvVersionForGlsl (const deUint32 vulkanVersion)
+vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion)
 {
-       vk::SpirvVersion        result                  = vk::SPIRV_VERSION_LAST;
-
-       deUint32 vulkanVersionMajorMinor = VK_MAKE_VERSION(VK_VERSION_MAJOR(vulkanVersion), VK_VERSION_MINOR(vulkanVersion), 0);
-       if (vulkanVersionMajorMinor == VK_API_VERSION_1_0)
-               result = vk::SPIRV_VERSION_1_0;
-       else if (vulkanVersionMajorMinor >= VK_API_VERSION_1_1)
-               result = vk::SPIRV_VERSION_1_3;
-
-       DE_ASSERT(result < vk::SPIRV_VERSION_LAST);
+       return getMaxSpirvVersionForVulkan(vulkanVersion);
+}
 
-       return result;
+vk::SpirvVersion getMaxSpirvVersionForGlsl (const deUint32 vulkanVersion)
+{
+       return getMaxSpirvVersionForVulkan(vulkanVersion);
 }
 
 SpirvVersion extractSpirvVersion (const ProgramBinary& binary)
index cca650d202fb8b95e6ab60d1b9a4c3d672d8da74..fe434696721d6c05498abf2d4cb194715ac2e2c6 100644 (file)
@@ -218,7 +218,11 @@ Move<VkShaderModule>       createShaderModule      (const DeviceInterface& deviceInterface,
 glu::ShaderType                        getGluShaderType        (VkShaderStageFlagBits shaderStage);
 VkShaderStageFlagBits  getVkShaderStage        (glu::ShaderType shaderType);
 
+// Returns the max SPIR-V version usable with a given Vulkan version, without requiring an extension.
+vk::SpirvVersion               getMaxSpirvVersionForVulkan     (const deUint32 vulkanVersion);
+// Deprecated. Use getMaxSpirvVersionForVulkan instead.
 vk::SpirvVersion               getMaxSpirvVersionForAsm        (const deUint32 vulkanVersion);
+// Deprecated. Use getMaxSpirvVersionForVulkan instead.
 vk::SpirvVersion               getMaxSpirvVersionForGlsl       (const deUint32 vulkanVersion);
 vk::SpirvVersion               getBaselineSpirvVersion         (const deUint32 vulkanVersion);
 SpirvVersion                   extractSpirvVersion                     (const ProgramBinary& binary);
index f2c9c5841aa8bdef8c978f00eb709e8df80ca795..4f8d2bb60d5ce2324db38144bbab409877b11ebb 100644 (file)
@@ -35,13 +35,16 @@ namespace vk
 using std::string;
 using std::vector;
 
-// Convert a Vulkan version number to a SPIRV-Tools target environment enum.
-static spv_target_env mapVulkanVersionToSpirvToolsEnv(deUint32 vulkanVersion)
+// Returns the SPIRV-Tools target environment enum for the given dEQP Spirv validator options object.
+// Do this here instead of as a method on SpirvValidatorOptions because only this file has access to
+// the SPIRV-Tools headers.
+static spv_target_env getSpirvToolsEnvForValidatorOptions(SpirvValidatorOptions opts)
 {
-       switch (vulkanVersion)
+       const bool allow_1_4 = opts.supports_VK_KHR_spirv_1_4;
+       switch (opts.vulkanVersion)
        {
                case VK_MAKE_VERSION(1, 0, 0): return SPV_ENV_VULKAN_1_0;
-               case VK_MAKE_VERSION(1, 1, 0): return SPV_ENV_VULKAN_1_1;
+               case VK_MAKE_VERSION(1, 1, 0): return allow_1_4 ? SPV_ENV_VULKAN_1_1_SPIRV_1_4 : SPV_ENV_VULKAN_1_1;
                default:
                        break;
        }
@@ -59,6 +62,7 @@ static spv_target_env mapTargetSpvEnvironment(SpirvVersion spirvVersion)
                case SPIRV_VERSION_1_1: result = SPV_ENV_UNIVERSAL_1_1; break;  //!< SPIR-V 1.1
                case SPIRV_VERSION_1_2: result = SPV_ENV_UNIVERSAL_1_2; break;  //!< SPIR-V 1.2
                case SPIRV_VERSION_1_3: result = SPV_ENV_UNIVERSAL_1_3; break;  //!< SPIR-V 1.3
+               case SPIRV_VERSION_1_4: result = SPV_ENV_UNIVERSAL_1_4; break;  //!< SPIR-V 1.4
                default:                                TCU_THROW(InternalError, "Unknown SPIR-V version");
        }
 
@@ -143,7 +147,7 @@ void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::os
 
 bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, const SpirvValidatorOptions &val_options)
 {
-       const spv_context               context         = spvContextCreate(mapVulkanVersionToSpirvToolsEnv(val_options.vulkanVersion));
+       const spv_context               context         = spvContextCreate(getSpirvToolsEnvForValidatorOptions(val_options));
        spv_diagnostic                  diagnostic      = DE_NULL;
        spv_validator_options   options         = DE_NULL;
        spv_text                                disasmText      = DE_NULL;
index 6f9d449a6f8e36e7ae25dec2b36c97b1fafb1f5d..63c145c3e3d9875bf791e6a0a6b33e0578f002ba 100644 (file)
@@ -39,22 +39,27 @@ namespace vk
 
 struct SpirVAsmBuildOptions
 {
-       deUint32        vulkanVersion;
+       deUint32                vulkanVersion;
        SpirvVersion    targetVersion;
+       bool                    supports_VK_KHR_spirv_1_4;
 
        SpirVAsmBuildOptions (deUint32 vulkanVersion_, SpirvVersion targetVersion_)
-               : vulkanVersion (vulkanVersion_)
-               , targetVersion (targetVersion_)
+               : vulkanVersion                         (vulkanVersion_)
+               , targetVersion                         (targetVersion_)
+               , supports_VK_KHR_spirv_1_4     (false)
        {}
 
        SpirVAsmBuildOptions (void)
-               : vulkanVersion (VK_MAKE_VERSION(1, 0, 0))
-               , targetVersion (SPIRV_VERSION_1_0)
+               : vulkanVersion                         (VK_MAKE_VERSION(1, 0, 0))
+               , targetVersion                         (SPIRV_VERSION_1_0)
+               , supports_VK_KHR_spirv_1_4     (false)
        {}
 
        SpirvValidatorOptions getSpirvValidatorOptions() const
        {
-               return SpirvValidatorOptions(vulkanVersion);
+               SpirvValidatorOptions result(vulkanVersion);
+               result.supports_VK_KHR_spirv_1_4 = supports_VK_KHR_spirv_1_4;
+               return result;
        }
 };
 
index 53649466424d154af892bebe5e4be9ca77782014..e14b4c7367aab8744f6938b3b20bef8ffda82526 100644 (file)
@@ -45,7 +45,7 @@ struct SpirvValidatorOptions
        };
 
        SpirvValidatorOptions(deUint32 the_vulkan_version = VK_MAKE_VERSION(1, 0, 0), BlockLayoutRules the_layout = kDefaultBlockLayout)
-       : vulkanVersion(the_vulkan_version), blockLayout(the_layout) {}
+       : vulkanVersion(the_vulkan_version), blockLayout(the_layout), supports_VK_KHR_spirv_1_4(false) {}
 
        // The target Vulkan version.  This determines the SPIR-V environment rules to
        // be checked. The bit pattern is as produced by VK_MAKE_VERSION.
@@ -53,6 +53,10 @@ struct SpirvValidatorOptions
 
        // The block layout rules to enforce.
        BlockLayoutRules blockLayout;
+
+       // Does the device support VK_KHR_spirv_1_4?
+       // (Camelcase would just be wrong here.)
+       bool supports_VK_KHR_spirv_1_4;
 };
 
 }  // namespace vk
index 2398eb35ae87dd868022ebadaacfcc59816b3623..242ff797595a0df004735c5936019620161e284c 100644 (file)
@@ -199,6 +199,7 @@ public:
        virtual tcu::TestNode::IterateResult            iterate                         (tcu::TestCase* testCase);
 
 private:
+       bool                                                                            spirvVersionSupported(vk::SpirvVersion);
        vk::BinaryCollection                                            m_progCollection;
        vk::BinaryRegistryReader                                        m_prebuiltBinRegistry;
 
@@ -264,7 +265,7 @@ void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePat
 
        for (vk::GlslSourceCollection::Iterator progIter = sourceProgs.glslSources.begin(); progIter != sourceProgs.glslSources.end(); ++progIter)
        {
-               if (progIter.getProgram().buildOptions.targetVersion > vk::getMaxSpirvVersionForGlsl(m_context.getUsedApiVersion()))
+               if (!spirvVersionSupported(progIter.getProgram().buildOptions.targetVersion))
                        TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
 
                const vk::ProgramBinary* const binProg = buildProgram<glu::ShaderProgramInfo, vk::GlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, log, &m_progCollection, commandLine);
@@ -288,7 +289,7 @@ void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePat
 
        for (vk::HlslSourceCollection::Iterator progIter = sourceProgs.hlslSources.begin(); progIter != sourceProgs.hlslSources.end(); ++progIter)
        {
-               if (progIter.getProgram().buildOptions.targetVersion > vk::getMaxSpirvVersionForGlsl(m_context.getUsedApiVersion()))
+               if (!spirvVersionSupported(progIter.getProgram().buildOptions.targetVersion))
                        TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
 
                const vk::ProgramBinary* const binProg = buildProgram<glu::ShaderProgramInfo, vk::HlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, log, &m_progCollection, commandLine);
@@ -312,7 +313,7 @@ void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePat
 
        for (vk::SpirVAsmCollection::Iterator asmIterator = sourceProgs.spirvAsmSources.begin(); asmIterator != sourceProgs.spirvAsmSources.end(); ++asmIterator)
        {
-               if (asmIterator.getProgram().buildOptions.targetVersion > vk::getMaxSpirvVersionForAsm(m_context.getUsedApiVersion()))
+               if (!spirvVersionSupported(asmIterator.getProgram().buildOptions.targetVersion))
                        TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
 
                buildProgram<vk::SpirVProgramInfo, vk::SpirVAsmCollection::Iterator>(casePath, asmIterator, m_prebuiltBinRegistry, log, &m_progCollection, commandLine);
@@ -357,6 +358,17 @@ tcu::TestNode::IterateResult TestCaseExecutor::iterate (tcu::TestCase*)
                return tcu::TestNode::CONTINUE;
 }
 
+bool TestCaseExecutor::spirvVersionSupported (vk::SpirvVersion spirvVersion)
+{
+       if (spirvVersion <= vk::getMaxSpirvVersionForVulkan(m_context.getUsedApiVersion()))
+               return true;
+
+       if (spirvVersion <= vk::SPIRV_VERSION_1_4)
+               return vk::isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_spirv_1_4");
+
+       return false;
+}
+
 // GLSL shader tests
 
 void createGlslTests (tcu::TestCaseGroup* glslTests)