SpirV tests for Vulkan 1.1
authorBoris Zanin <boris.zanin@mobica.com>
Fri, 1 Sep 2017 11:07:21 +0000 (13:07 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Mon, 2 Oct 2017 10:54:39 +0000 (06:54 -0400)
Add tests:
 * dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_length
 * dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_infinite
 * dEQP-VK.spirv_assembly.instruction.compute.spirv_version.*
 * dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.*
 * dEQP-VK.spirv_assembly.instruction.*opmoduleprocessed*

Components: Vulkan

VK-GL-CTS issue: 269

Change-Id: Ib4c21a881a31ae93b5b13d88c641b3c4a7ca64a5
(cherry picked from commit 308172f1771c4ed01b45faead3055da016cd8d3b)

50 files changed:
AndroidGen.mk
android/cts/master/vk-master.txt
external/vulkancts/framework/vulkan/vkDefs.hpp
external/vulkancts/framework/vulkan/vkPrograms.cpp
external/vulkancts/framework/vulkan/vkPrograms.hpp
external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
external/vulkancts/framework/vulkan/vkSpirVAsm.hpp
external/vulkancts/framework/vulkan/vkSpirVProgram.hpp
external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp
external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp
external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.hpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotOtherTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinMaskVarTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinVarTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShapeTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShuffleTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp
external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
external/vulkancts/modules/vulkan/vktTestCase.cpp
external/vulkancts/modules/vulkan/vktTestCase.hpp
external/vulkancts/modules/vulkan/vktTestPackage.cpp
external/vulkancts/mustpass/1.1.0/vk-default.txt
external/vulkancts/scripts/build_spirv_binaries.py

index 41b32f6..16d946a 100644 (file)
@@ -233,6 +233,9 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmIndexingTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp \
+       external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.cpp \
+       external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.cpp \
+       external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUboMatrixPaddingTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp \
index 20f7b0a..ff5160b 100755 (executable)
@@ -168659,6 +168659,10 @@ dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.multiple_arbitrary_descriptors.offset_view_nonzero
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.descriptor_array.offset_view_zero
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.descriptor_array.offset_view_nonzero
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_0_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_1_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_2_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_3_compute
 dEQP-VK.spirv_assembly.instruction.compute.opnop.all
 dEQP-VK.spirv_assembly.instruction.compute.opatomic.iadd
 dEQP-VK.spirv_assembly.instruction.compute.opatomic.isub
@@ -168675,6 +168679,7 @@ dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.load
 dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.store
 dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.compex
 dEQP-VK.spirv_assembly.instruction.compute.opline.all
+dEQP-VK.spirv_assembly.instruction.compute.opmoduleprocessed.all
 dEQP-VK.spirv_assembly.instruction.compute.opnoline.all
 dEQP-VK.spirv_assembly.instruction.compute.opconstantnull.bool
 dEQP-VK.spirv_assembly.instruction.compute.opconstantnull.sint32
@@ -168752,6 +168757,8 @@ dEQP-VK.spirv_assembly.instruction.compute.loop_control.none
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.dont_unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll_dont_unroll
+dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_length
+dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_infinite
 dEQP-VK.spirv_assembly.instruction.compute.function_control.none
 dEQP-VK.spirv_assembly.instruction.compute.function_control.inline
 dEQP-VK.spirv_assembly.instruction.compute.function_control.dont_inline
@@ -169208,6 +169215,26 @@ dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.complex_types_compu
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.complex_types_compute.opptraccesschain_float_single_buffer_first_input
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.nullptr_compute.opvariable_initialized_null
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.nullptr_compute.opselect_null_or_valid_ptr
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_fragment
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tesse
@@ -169278,6 +169305,11 @@ dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_tesse
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_geom
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_frag
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_vert
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_geom
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_frag
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_tesse
index 20350a9..41b2b19 100644 (file)
@@ -98,10 +98,21 @@ private:
 enum SpirvVersion
 {
        SPIRV_VERSION_1_0       = 0,    //!< SPIR-V 1.0
+       SPIRV_VERSION_1_1       = 1,    //!< SPIR-V 1.1
+       SPIRV_VERSION_1_2       = 2,    //!< SPIR-V 1.2
+       SPIRV_VERSION_1_3       = 3,    //!< SPIR-V 1.3
 
        SPIRV_VERSION_LAST
 };
 
+typedef struct
+{
+       deUint32        magic;
+       deUint32        version;
+       deUint32        generator;
+       deUint32        bound;
+} SpirvBinaryHeader;
+
 namespace wsi
 {
 
index 585c96f..5ddd17f 100644 (file)
@@ -99,11 +99,11 @@ ProgramBinary* createProgramBinaryFromSpirV (const vector<deUint32>& binary)
 
 } // anonymous
 
-void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramInfo* buildInfo)
+void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramInfo* buildInfo, const SpirvVersion spirvVersion)
 {
        std::ostringstream validationLog;
 
-       if (!validateSpirV(binary.size(), &binary[0], &validationLog))
+       if (!validateSpirV(binary.size(), &binary[0], &validationLog, spirvVersion))
        {
                buildInfo->program.linkOk        = false;
                buildInfo->program.infoLog      += "\n" + validationLog.str();
@@ -114,6 +114,7 @@ void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramIn
 
 ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo* buildInfo)
 {
+       const SpirvVersion      spirvVersion    = program.buildOptions.targetVersion;
        const bool                      validateBinary  = VALIDATE_BINARIES;
        vector<deUint32>        binary;
 
@@ -129,13 +130,14 @@ ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo*
        }
 
        if (validateBinary)
-               validateCompiledBinary(binary, buildInfo);
+               validateCompiledBinary(binary, buildInfo, spirvVersion);
 
        return createProgramBinaryFromSpirV(binary);
 }
 
 ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo* buildInfo)
 {
+       const SpirvVersion      spirvVersion    = program.buildOptions.targetVersion;
        const bool                      validateBinary  = VALIDATE_BINARIES;
        vector<deUint32>        binary;
 
@@ -151,24 +153,25 @@ ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo*
        }
 
        if (validateBinary)
-               validateCompiledBinary(binary, buildInfo);
+               validateCompiledBinary(binary, buildInfo, spirvVersion);
 
        return createProgramBinaryFromSpirV(binary);
 }
 
 ProgramBinary* assembleProgram (const SpirVAsmSource& program, SpirVProgramInfo* buildInfo)
 {
+       const SpirvVersion      spirvVersion            = program.buildOptions.targetVersion;
        const bool                      validateBinary          = VALIDATE_BINARIES;
        vector<deUint32>        binary;
 
-       if (!assembleSpirV(&program, &binary, buildInfo))
+       if (!assembleSpirV(&program, &binary, buildInfo, spirvVersion))
                TCU_THROW(InternalError, "Failed to assemble SPIR-V");
 
        if (validateBinary)
        {
                std::ostringstream      validationLog;
 
-               if (!validateSpirV(binary.size(), &binary[0], &validationLog))
+               if (!validateSpirV(binary.size(), &binary[0], &validationLog, spirvVersion))
                {
                        buildInfo->compileOk     = false;
                        buildInfo->infoLog              += "\n" + validationLog.str();
@@ -180,14 +183,14 @@ ProgramBinary* assembleProgram (const SpirVAsmSource& program, SpirVProgramInfo*
        return createProgramBinaryFromSpirV(binary);
 }
 
-void disassembleProgram (const ProgramBinary& program, std::ostream* dst)
+void disassembleProgram (const ProgramBinary& program, std::ostream* dst, SpirvVersion spirvVersion)
 {
        if (program.getFormat() == PROGRAM_FORMAT_SPIRV)
        {
                TCU_CHECK_INTERNAL(isSaneSpirVBinary(program));
 
                if (isNativeSpirVBinaryEndianness())
-                       disassembleSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst);
+                       disassembleSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst, spirvVersion);
                else
                        TCU_THROW(InternalError, "SPIR-V endianness translation not supported");
        }
@@ -195,7 +198,7 @@ void disassembleProgram (const ProgramBinary& program, std::ostream* dst)
                TCU_THROW(NotSupportedError, "Unsupported program format");
 }
 
-bool validateProgram (const ProgramBinary& program, std::ostream* dst)
+bool validateProgram (const ProgramBinary& program, std::ostream* dst, SpirvVersion spirvVersion)
 {
        if (program.getFormat() == PROGRAM_FORMAT_SPIRV)
        {
@@ -206,7 +209,7 @@ bool validateProgram (const ProgramBinary& program, std::ostream* dst)
                }
 
                if (isNativeSpirVBinaryEndianness())
-                       return validateSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst);
+                       return validateSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst, spirvVersion);
                else
                        TCU_THROW(InternalError, "SPIR-V endianness translation not supported");
        }
@@ -264,4 +267,93 @@ VkShaderStageFlagBits getVkShaderStage (glu::ShaderType shaderType)
        return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(s_shaderStages, shaderType);
 }
 
+vk::SpirvVersion getSpirvVersionForAsm (const deUint32 vulkanVersion)
+{
+       vk::SpirvVersion        result                  = vk::SPIRV_VERSION_LAST;
+
+       if (vulkanVersion == VK_API_VERSION_1_0)
+               result = vk::SPIRV_VERSION_1_0;
+       else if (vulkanVersion >= VK_API_VERSION_1_1)
+               result = vk::SPIRV_VERSION_1_3;
+
+       DE_ASSERT(result < vk::SPIRV_VERSION_LAST);
+
+       return result;
+}
+
+vk::SpirvVersion getSpirvVersionForGlsl (const deUint32 vulkanVersion)
+{
+       vk::SpirvVersion        result                  = vk::SPIRV_VERSION_LAST;
+
+       if (vulkanVersion == VK_API_VERSION_1_0)
+               result = vk::SPIRV_VERSION_1_0;
+       else if (vulkanVersion >= VK_API_VERSION_1_1)
+               result = vk::SPIRV_VERSION_1_3;
+
+       DE_ASSERT(result < vk::SPIRV_VERSION_LAST);
+
+       return result;
+}
+
+SpirvVersion extractSpirvVersion (const ProgramBinary& binary)
+{
+       DE_STATIC_ASSERT(SPIRV_VERSION_1_3 + 1 == SPIRV_VERSION_LAST);
+
+       if (binary.getFormat() != PROGRAM_FORMAT_SPIRV)
+               TCU_THROW(InternalError, "Binary is not in SPIR-V format");
+
+       if (!isSaneSpirVBinary(binary) || binary.getSize() < sizeof(SpirvBinaryHeader))
+               TCU_THROW(InternalError, "Invalid SPIR-V header format");
+
+       const deUint32                          spirvBinaryVersion10    = 0x00010000;
+       const deUint32                          spirvBinaryVersion11    = 0x00010100;
+       const deUint32                          spirvBinaryVersion12    = 0x00010200;
+       const deUint32                          spirvBinaryVersion13    = 0x00010300;
+       const SpirvBinaryHeader*        header                                  = reinterpret_cast<const SpirvBinaryHeader*>(binary.getBinary());
+       const deUint32                          spirvVersion                    = isNativeSpirVBinaryEndianness()
+                                                                                                               ? header->version
+                                                                                                               : deReverseBytes32(header->version);
+       SpirvVersion                            result                                  = SPIRV_VERSION_LAST;
+
+       switch (spirvVersion)
+       {
+               case spirvBinaryVersion10:      result = SPIRV_VERSION_1_0; break; //!< SPIR-V 1.0
+               case spirvBinaryVersion11:      result = SPIRV_VERSION_1_1; break; //!< SPIR-V 1.1
+               case spirvBinaryVersion12:      result = SPIRV_VERSION_1_2; break; //!< SPIR-V 1.2
+               case spirvBinaryVersion13:      result = SPIRV_VERSION_1_3; break; //!< SPIR-V 1.3
+               default:                                        TCU_THROW(InternalError, "Unknown SPIR-V version detected in binary");
+       }
+
+       return result;
+}
+
+std::string getSpirvVersionName (const SpirvVersion spirvVersion)
+{
+       DE_STATIC_ASSERT(SPIRV_VERSION_1_3 + 1 == SPIRV_VERSION_LAST);
+       DE_ASSERT(spirvVersion < SPIRV_VERSION_LAST);
+
+       std::string result;
+
+       switch (spirvVersion)
+       {
+               case SPIRV_VERSION_1_0: result = "1.0"; break; //!< SPIR-V 1.0
+               case SPIRV_VERSION_1_1: result = "1.1"; break; //!< SPIR-V 1.1
+               case SPIRV_VERSION_1_2: result = "1.2"; break; //!< SPIR-V 1.2
+               case SPIRV_VERSION_1_3: result = "1.3"; break; //!< SPIR-V 1.3
+               default:                                result = "Unknown";
+       }
+
+       return result;
+}
+
+SpirvVersion& operator++(SpirvVersion& spirvVersion)
+{
+       if (spirvVersion == SPIRV_VERSION_LAST)
+               spirvVersion = SPIRV_VERSION_1_0;
+       else
+               spirvVersion = static_cast<SpirvVersion>(static_cast<deUint32>(spirvVersion) + 1);
+
+       return spirvVersion;
+}
+
 } // vk
index 0e39fa3..f89fd34 100644 (file)
@@ -58,16 +58,22 @@ private:
        const std::vector<deUint8>      m_binary;
 };
 
-template<typename Program>
+struct BinaryBuildOptions
+{
+};
+
+template<typename Program, typename BuildOptions>
 class ProgramCollection
 {
 public:
                                                                ProgramCollection       (void);
+                                                               ProgramCollection       (const BuildOptions defaultBuildOptions);
                                                                ~ProgramCollection      (void);
 
        void                                            clear                           (void);
 
        Program&                                        add                                     (const std::string& name);
+       Program&                                        add                                     (const std::string& name, const BuildOptions* buildOptions);
        void                                            add                                     (const std::string& name, de::MovePtr<Program>& program);
 
        bool                                            contains                        (const std::string& name) const;
@@ -98,86 +104,126 @@ public:
        Iterator                                        begin                           (void) const { return Iterator(m_programs.begin());     }
        Iterator                                        end                                     (void) const { return Iterator(m_programs.end());       }
 
+       bool                                            empty                           (void) const { return m_programs.empty();                       }
+
 private:
        typedef std::map<std::string, Program*> ProgramMap;
 
        ProgramMap                                      m_programs;
+       BuildOptions                            m_defaultBuildOptions;
 };
 
-template<typename Program>
-ProgramCollection<Program>::ProgramCollection (void)
+template<typename Program, typename BuildOptions>
+ProgramCollection<Program, BuildOptions>::ProgramCollection (void)
+{
+}
+
+template<typename Program, typename BuildOptions>
+ProgramCollection<Program, BuildOptions>::ProgramCollection (const BuildOptions defaultBuildOptions)
+       : m_programs()
+       , m_defaultBuildOptions(defaultBuildOptions)
 {
 }
 
-template<typename Program>
-ProgramCollection<Program>::~ProgramCollection (void)
+template<typename Program, typename BuildOptions>
+ProgramCollection<Program, BuildOptions>::~ProgramCollection (void)
 {
        clear();
 }
 
-template<typename Program>
-void ProgramCollection<Program>::clear (void)
+template<typename Program, typename BuildOptions>
+void ProgramCollection<Program, BuildOptions>::clear (void)
 {
        for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
                delete i->second;
        m_programs.clear();
 }
 
-template<typename Program>
-Program& ProgramCollection<Program>::add (const std::string& name)
+template<typename Program, typename BuildOptions>
+Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name)
 {
        DE_ASSERT(!contains(name));
        de::MovePtr<Program> prog = de::newMovePtr<Program>();
+       prog->buildOptions = m_defaultBuildOptions;
        m_programs[name] = prog.get();
        prog.release();
        return *m_programs[name];
 }
 
-template<typename Program>
-void ProgramCollection<Program>::add (const std::string& name, de::MovePtr<Program>& program)
+template<typename Program, typename BuildOptions>
+Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name, const BuildOptions* buildOptions)
+{
+       Program& program = add(name);
+
+       if (buildOptions != DE_NULL)
+               program << *buildOptions;
+
+       return program;
+}
+
+template<typename Program, typename BuildOptions>
+void ProgramCollection<Program, BuildOptions>::add (const std::string& name, de::MovePtr<Program>& program)
 {
        DE_ASSERT(!contains(name));
        m_programs[name] = program.get();
        program.release();
 }
 
-template<typename Program>
-bool ProgramCollection<Program>::contains (const std::string& name) const
+template<typename Program, typename BuildOptions>
+bool ProgramCollection<Program, BuildOptions>::contains (const std::string& name) const
 {
        return de::contains(m_programs, name);
 }
 
-template<typename Program>
-const Program& ProgramCollection<Program>::get (const std::string& name) const
+template<typename Program, typename BuildOptions>
+const Program& ProgramCollection<Program, BuildOptions>::get (const std::string& name) const
 {
        DE_ASSERT(contains(name));
        return *m_programs.find(name)->second;
 }
 
-typedef ProgramCollection<GlslSource>          GlslSourceCollection;
-typedef ProgramCollection<HlslSource>          HlslSourceCollection;
-typedef ProgramCollection<SpirVAsmSource>      SpirVAsmCollection;
+typedef ProgramCollection<GlslSource, ShaderBuildOptions>              GlslSourceCollection;
+typedef ProgramCollection<HlslSource, ShaderBuildOptions>              HlslSourceCollection;
+typedef ProgramCollection<SpirVAsmSource, SpirVAsmBuildOptions>        SpirVAsmCollection;
 
 struct SourceCollections
 {
+       SourceCollections               (const deUint32                                 usedVulkanVersion_,
+                                                        const ShaderBuildOptions&              glslBuildOptions,
+                                                        const ShaderBuildOptions&              hlslBuildOptions,
+                                                        const SpirVAsmBuildOptions&    spirVAsmBuildOptions)
+                                                       : usedVulkanVersion(usedVulkanVersion_)
+                                                       , glslSources(glslBuildOptions)
+                                                       , hlslSources(hlslBuildOptions)
+                                                       , spirvAsmSources(spirVAsmBuildOptions)
+                                                       {
+                                                       }
+
+       deUint32                                usedVulkanVersion;
        GlslSourceCollection    glslSources;
        HlslSourceCollection    hlslSources;
        SpirVAsmCollection              spirvAsmSources;
 };
 
-typedef ProgramCollection<ProgramBinary>               BinaryCollection;
+typedef ProgramCollection<ProgramBinary, BinaryBuildOptions>   BinaryCollection;
 
 ProgramBinary*                 buildProgram            (const GlslSource& program, glu::ShaderProgramInfo* buildInfo);
 ProgramBinary*                 buildProgram            (const HlslSource& program, glu::ShaderProgramInfo* buildInfo);
 ProgramBinary*                 assembleProgram         (const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo);
-void                                   disassembleProgram      (const ProgramBinary& program, std::ostream* dst);
-bool                                   validateProgram         (const ProgramBinary& program, std::ostream* dst);
+void                                   disassembleProgram      (const ProgramBinary& program, std::ostream* dst, SpirvVersion spirvVersion);
+bool                                   validateProgram         (const ProgramBinary& program, std::ostream* dst, SpirvVersion spirvVersion);
 
 Move<VkShaderModule>   createShaderModule      (const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags);
 
 glu::ShaderType                        getGluShaderType        (VkShaderStageFlagBits shaderStage);
 VkShaderStageFlagBits  getVkShaderStage        (glu::ShaderType shaderType);
 
+vk::SpirvVersion               getSpirvVersionForAsm   (const deUint32 vulkanVersion);
+vk::SpirvVersion               getSpirvVersionForGlsl  (const deUint32 vulkanVersion);
+SpirvVersion                   extractSpirvVersion             (const ProgramBinary& binary);
+std::string                            getSpirvVersionName             (const SpirvVersion spirvVersion);
+SpirvVersion&                  operator++                              (SpirvVersion& spirvVersion);
+
 } // vk
 
 #endif // _VKPROGRAMS_HPP
index 1f243b4..e1ebdd1 100644 (file)
@@ -246,7 +246,7 @@ bool compileShaderToSpirV (const std::vector<std::string>* sources, const Shader
        TBuiltInResource        builtinRes;
        const EShMessages       compileFlags    = getCompileFlags(buildOptions, shaderLanguage);
 
-       if (buildOptions.targetVersion != SPIRV_VERSION_1_0)
+       if (buildOptions.targetVersion >= SPIRV_VERSION_LAST)
                TCU_THROW(InternalError, "Unsupported SPIR-V target version");
 
        if (getNumShaderStages(sources) > 1)
@@ -268,6 +268,23 @@ bool compileShaderToSpirV (const std::vector<std::string>* sources, const Shader
                        glslang::TProgram               glslangProgram;
 
                        shader.setStrings(srcPtrs, DE_LENGTH_OF_ARRAY(srcPtrs));
+
+                       switch ( buildOptions.targetVersion )
+                       {
+                       case SPIRV_VERSION_1_0:
+                               shader.setEnvTarget(glslang::EshTargetSpv, 0x10000);
+                               break;
+                       case SPIRV_VERSION_1_1:
+                               shader.setEnvTarget(glslang::EshTargetSpv, 0x10100);
+                               break;
+                       case SPIRV_VERSION_1_2:
+                               shader.setEnvTarget(glslang::EshTargetSpv, 0x10200);
+                               break;
+                       case SPIRV_VERSION_1_3:
+                               shader.setEnvTarget(glslang::EshTargetSpv, 0x10300);
+                               break;
+                       }
+
                        glslangProgram.addShader(&shader);
 
                        if (shaderLanguage == SHADER_LANGUAGE_HLSL)
index 18cddfe..fadf1c5 100644 (file)
@@ -39,11 +39,25 @@ using std::vector;
 
 #if defined(DEQP_HAVE_SPIRV_TOOLS)
 
-static const spv_target_env s_defaultEnvironment = SPV_ENV_VULKAN_1_1;
+static spv_target_env mapTargetSpvEnvironment(SpirvVersion spirvVersion)
+{
+       spv_target_env result = SPV_ENV_UNIVERSAL_1_0;
+
+       switch (spirvVersion)
+       {
+               case SPIRV_VERSION_1_0: result = SPV_ENV_UNIVERSAL_1_0; break;  //!< SPIR-V 1.0
+               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
+               default:                                TCU_THROW(InternalError, "Unknown SPIR-V version");
+       }
+
+       return result;
+}
 
-bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo)
+bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo, SpirvVersion spirvVersion)
 {
-       const spv_context       context         = spvContextCreate(s_defaultEnvironment);
+       const spv_context       context         = spvContextCreate(mapTargetSpvEnvironment(spirvVersion));
        spv_binary                      binary          = DE_NULL;
        spv_diagnostic          diagnostic      = DE_NULL;
 
@@ -84,9 +98,9 @@ bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, S
        }
 }
 
-void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst)
+void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst, SpirvVersion spirvVersion)
 {
-       const spv_context       context         = spvContextCreate(s_defaultEnvironment);
+       const spv_context       context         = spvContextCreate(mapTargetSpvEnvironment(spirvVersion));
        spv_text                        text            = DE_NULL;
        spv_diagnostic          diagnostic      = DE_NULL;
 
@@ -116,9 +130,9 @@ void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::os
        }
 }
 
-bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog)
+bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, SpirvVersion spirvVersion)
 {
-       const spv_context       context         = spvContextCreate(s_defaultEnvironment);
+       const spv_context       context         = spvContextCreate(mapTargetSpvEnvironment(spirvVersion));
        spv_diagnostic          diagnostic      = DE_NULL;
 
        try
@@ -145,17 +159,17 @@ bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostre
 
 #else // defined(DEQP_HAVE_SPIRV_TOOLS)
 
-bool assembleSpirV (const SpirVAsmSource*, std::vector<deUint32>*, SpirVProgramInfo*)
+bool assembleSpirV (const SpirVAsmSource*, std::vector<deUint32>*, SpirVProgramInfo*, SpirvVersion)
 {
        TCU_THROW(NotSupportedError, "SPIR-V assembly not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
 }
 
-void disassembleSpirV (size_t, const deUint32*, std::ostream*)
+void disassembleSpirV (size_t, const deUint32*, std::ostream*, SpirvVersion)
 {
        TCU_THROW(NotSupportedError, "SPIR-V disassembling not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
 }
 
-bool validateSpirV (size_t, const deUint32*, std::ostream*)
+bool validateSpirV (size_t, const deUint32*, std::ostream*, SpirvVersion)
 {
        TCU_THROW(NotSupportedError, "SPIR-V validation not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
 }
index 612c13a..822f1a5 100644 (file)
@@ -32,13 +32,13 @@ namespace vk
 {
 
 //! Assemble SPIR-V program. Will fail with NotSupportedError if compiler is not available.
-bool   assembleSpirV           (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo);
+bool   assembleSpirV           (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo, SpirvVersion spirvVersion);
 
 //! Disassemble SPIR-V binary. Throws tcu::NotSupportedError if disassembler is not available
-void   disassembleSpirV        (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst);
+void   disassembleSpirV        (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst, SpirvVersion spirvVersion);
 
 //! Validate SPIR-V binary, returning true if validation succeeds. Will fail with NotSupportedError if compiler is not available.
-bool   validateSpirV           (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog);
+bool   validateSpirV           (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, SpirvVersion spirvVersion);
 
 } // vk
 
index 5c5244a..94c44a3 100644 (file)
@@ -36,6 +36,19 @@ class TestLog;
 namespace vk
 {
 
+struct SpirVAsmBuildOptions
+{
+       SpirvVersion    targetVersion;
+
+       SpirVAsmBuildOptions (SpirvVersion targetVersion_)
+               : targetVersion (targetVersion_)
+       {}
+
+       SpirVAsmBuildOptions (void)
+               : targetVersion (SPIRV_VERSION_1_0)
+       {}
+};
+
 struct SpirVAsmSource
 {
        SpirVAsmSource (void)
@@ -47,7 +60,14 @@ struct SpirVAsmSource
        {
        }
 
-       std::string             source;
+       SpirVAsmSource& operator<< (const SpirVAsmBuildOptions& buildOptions_)
+       {
+               buildOptions = buildOptions_;
+               return *this;
+       };
+
+       SpirVAsmBuildOptions    buildOptions;
+       std::string                             source;
 };
 
 struct SpirVProgramInfo
index 7069ef4..9fb9f35 100644 (file)
@@ -985,14 +985,14 @@ Memory::Memory (const vk::InstanceInterface&      vki,
 class Context
 {
 public:
-                                                                                                       Context                                 (const vk::InstanceInterface&                                           vki,
-                                                                                                                                                        const vk::DeviceInterface&                                                     vkd,
-                                                                                                                                                        vk::VkPhysicalDevice                                                           physicalDevice,
-                                                                                                                                                        vk::VkDevice                                                                           device,
-                                                                                                                                                        vk::VkQueue                                                                            queue,
-                                                                                                                                                        deUint32                                                                                       queueFamilyIndex,
-                                                                                                                                                        const vector<pair<deUint32, vk::VkQueue> >&            queues,
-                                                                                                                                                        const vk::ProgramCollection<vk::ProgramBinary>&        binaryCollection)
+                                                                                                       Context                                 (const vk::InstanceInterface&                                   vki,
+                                                                                                                                                        const vk::DeviceInterface&                                             vkd,
+                                                                                                                                                        vk::VkPhysicalDevice                                                   physicalDevice,
+                                                                                                                                                        vk::VkDevice                                                                   device,
+                                                                                                                                                        vk::VkQueue                                                                    queue,
+                                                                                                                                                        deUint32                                                                               queueFamilyIndex,
+                                                                                                                                                        const vector<pair<deUint32, vk::VkQueue> >&    queues,
+                                                                                                                                                        const vk::BinaryCollection&                                    binaryCollection)
                : m_vki                                 (vki)
                , m_vkd                                 (vkd)
                , m_physicalDevice              (physicalDevice)
@@ -1016,7 +1016,7 @@ public:
        const vector<pair<deUint32, vk::VkQueue> >&             getQueues                               (void) const { return m_queues; }
        const vector<deUint32>                                                  getQueueFamilies                (void) const { return m_queueFamilies; }
        vk::VkCommandPool                                                               getCommandPool                  (void) const { return *m_commandPool; }
-       const vk::ProgramCollection<vk::ProgramBinary>& getBinaryCollection             (void) const { return m_binaryCollection; }
+       const vk::BinaryCollection&                                             getBinaryCollection             (void) const { return m_binaryCollection; }
 
 private:
        const vk::InstanceInterface&                                    m_vki;
@@ -1027,7 +1027,7 @@ private:
        const deUint32                                                                  m_queueFamilyIndex;
        const vector<pair<deUint32, vk::VkQueue> >              m_queues;
        const vk::Unique<vk::VkCommandPool>                             m_commandPool;
-       const vk::ProgramCollection<vk::ProgramBinary>& m_binaryCollection;
+       const vk::BinaryCollection&                                             m_binaryCollection;
        vector<deUint32>                                                                m_queueFamilies;
 };
 
@@ -1043,7 +1043,7 @@ public:
 
        const Memory&                                                                   getMemory                               (void) const { return m_memory; }
        const Context&                                                                  getContext                              (void) const { return m_context; }
-       const vk::ProgramCollection<vk::ProgramBinary>& getBinaryCollection             (void) const { return m_context.getBinaryCollection(); }
+       const vk::BinaryCollection&                                             getBinaryCollection             (void) const { return m_context.getBinaryCollection(); }
 
        void                            setBuffer               (vk::Move<vk::VkBuffer> buffer,
                                                                                 vk::VkDeviceSize               size)
@@ -4186,9 +4186,9 @@ public:
        {
        }
 
-       const Memory&                                                                   getMemory                                       (void) const { return m_context.getMemory(); }
-       const Context&                                                                  getContext                                      (void) const { return m_context.getContext(); }
-       const vk::ProgramCollection<vk::ProgramBinary>& getBinaryCollection                     (void) const { return m_context.getBinaryCollection(); }
+       const Memory&                           getMemory                                       (void) const { return m_context.getMemory(); }
+       const Context&                          getContext                                      (void) const { return m_context.getContext(); }
+       const vk::BinaryCollection&     getBinaryCollection                     (void) const { return m_context.getBinaryCollection(); }
 
        vk::VkBuffer                            getBuffer                                       (void) const { return m_context.getBuffer(); }
        vk::VkDeviceSize                        getBufferSize                           (void) const { return m_context.getBufferSize(); }
index 3518fc4..c4e4c5e 100644 (file)
@@ -60,7 +60,7 @@ public:
        deUint32                                                                        getQueueFamilyIndex     (void) const    { return m_queueFamilyIndex;                            }
 
        tcu::TestContext&                                                       getTestContext          (void) const    { return m_context.getTestContext();            }
-       vk::ProgramCollection<vk::ProgramBinary>&       getBinaryCollection     (void) const    { return m_context.getBinaryCollection();       }
+       vk::BinaryCollection&                                           getBinaryCollection     (void) const    { return m_context.getBinaryCollection();       }
        vk::Allocator&                                                          getDefaultAllocator     (void) const    { return *m_allocator;  }
 
 private:
index 3751afb..acedf15 100644 (file)
@@ -561,14 +561,14 @@ Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
        return createPipelineLayout(vkd, device, &createInfo);
 }
 
-Move<VkPipeline> createRenderPipeline (const DeviceInterface&                                                  vkd,
-                                                                          VkDevice                                                                                     device,
-                                                                          VkRenderPass                                                                         renderPass,
-                                                                          VkPipelineLayout                                                                     pipelineLayout,
-                                                                          const vk::ProgramCollection<vk::ProgramBinary>&      binaryCollection,
-                                                                          deUint32                                                                                     width,
-                                                                          deUint32                                                                                     height,
-                                                                          deUint32                                                                                     sampleCount)
+Move<VkPipeline> createRenderPipeline (const DeviceInterface&          vkd,
+                                                                          VkDevice                                             device,
+                                                                          VkRenderPass                                 renderPass,
+                                                                          VkPipelineLayout                             pipelineLayout,
+                                                                          const vk::BinaryCollection&  binaryCollection,
+                                                                          deUint32                                             width,
+                                                                          deUint32                                             height,
+                                                                          deUint32                                             sampleCount)
 {
        const Unique<VkShaderModule>    vertexShaderModule                      (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
        const Unique<VkShaderModule>    fragmentShaderModule            (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
index 1256fe7..23ba014 100644 (file)
@@ -709,15 +709,15 @@ Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
        return createPipelineLayout(vkd, device, &createInfo);
 }
 
-Move<VkPipeline> createRenderPipeline (const DeviceInterface&                                                  vkd,
-                                                                          VkDevice                                                                                     device,
-                                                                          VkFormat                                                                                     srcFormat,
-                                                                          VkRenderPass                                                                         renderPass,
-                                                                          VkPipelineLayout                                                                     pipelineLayout,
-                                                                          const vk::ProgramCollection<vk::ProgramBinary>&      binaryCollection,
-                                                                          deUint32                                                                                     width,
-                                                                          deUint32                                                                                     height,
-                                                                          deUint32                                                                                     sampleCount)
+Move<VkPipeline> createRenderPipeline (const DeviceInterface&          vkd,
+                                                                          VkDevice                                             device,
+                                                                          VkFormat                                             srcFormat,
+                                                                          VkRenderPass                                 renderPass,
+                                                                          VkPipelineLayout                             pipelineLayout,
+                                                                          const vk::BinaryCollection&  binaryCollection,
+                                                                          deUint32                                             width,
+                                                                          deUint32                                             height,
+                                                                          deUint32                                             sampleCount)
 {
        const tcu::TextureFormat                format                                          (mapVkFormat(srcFormat));
        const bool                                              isDepthStencilFormat            (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
@@ -976,15 +976,15 @@ Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface&  vkd,
        return createPipelineLayout(vkd, device, &createInfo);
 }
 
-Move<VkPipeline> createSplitPipeline (const DeviceInterface&                                                   vkd,
-                                                                         VkDevice                                                                                      device,
-                                                                         VkRenderPass                                                                          renderPass,
-                                                                         deUint32                                                                                      subpassIndex,
-                                                                         VkPipelineLayout                                                                      pipelineLayout,
-                                                                         const vk::ProgramCollection<vk::ProgramBinary>&       binaryCollection,
-                                                                         deUint32                                                                                      width,
-                                                                         deUint32                                                                                      height,
-                                                                         deUint32                                                                                      sampleCount)
+Move<VkPipeline> createSplitPipeline (const DeviceInterface&           vkd,
+                                                                         VkDevice                                              device,
+                                                                         VkRenderPass                                  renderPass,
+                                                                         deUint32                                              subpassIndex,
+                                                                         VkPipelineLayout                              pipelineLayout,
+                                                                         const vk::BinaryCollection&   binaryCollection,
+                                                                         deUint32                                              width,
+                                                                         deUint32                                              height,
+                                                                         deUint32                                              sampleCount)
 {
        const Unique<VkShaderModule>    vertexShaderModule                      (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
        const Unique<VkShaderModule>    fragmentShaderModule            (createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
@@ -1180,14 +1180,14 @@ Move<VkPipeline> createSplitPipeline (const DeviceInterface&                                                    vkd,
        return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
 }
 
-vector<VkPipelineSp> createSplitPipelines (const DeviceInterface&                                                      vkd,
-                                                                                VkDevice                                                                                       device,
-                                                                                VkRenderPass                                                                           renderPass,
-                                                                                VkPipelineLayout                                                                       pipelineLayout,
-                                                                                const vk::ProgramCollection<vk::ProgramBinary>&        binaryCollection,
-                                                                                deUint32                                                                                       width,
-                                                                                deUint32                                                                                       height,
-                                                                                deUint32                                                                                       sampleCount)
+vector<VkPipelineSp> createSplitPipelines (const DeviceInterface&              vkd,
+                                                                                VkDevice                                               device,
+                                                                                VkRenderPass                                   renderPass,
+                                                                                VkPipelineLayout                               pipelineLayout,
+                                                                                const vk::BinaryCollection&    binaryCollection,
+                                                                                deUint32                                               width,
+                                                                                deUint32                                               height,
+                                                                                deUint32                                               sampleCount)
 {
        std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);
 
index a0293d1..58e20e0 100644 (file)
@@ -522,20 +522,20 @@ public:
                virtual void    rendererDraw    (const VkPipelineLayout pipelineLayout, const VkCommandBuffer cmdBuffer) const = 0;
        };
 
-       Renderer (const DeviceInterface&                                        vk,
-                         const VkDevice                                                        device,
-                         Allocator&                                                            allocator,
-                         const deUint32                                                        queueFamilyIndex,
-                         const VkDescriptorSetLayout                           descriptorSetLayout,    //!< may be NULL, if no descriptors are used
-                         ProgramCollection<vk::ProgramBinary>&         binaryCollection,
-                         const std::string&                                            vertexName,
-                         const std::string&                                            fragmentName,
-                         const VkBuffer                                                        colorBuffer,
-                         const IVec2&                                                          renderSize,
-                         const VkFormat                                                        colorFormat,
-                         const Vec4&                                                           clearColor,
-                         const VkPrimitiveTopology                                     topology,
-                         SpecializationMap                                                     specMap = SpecializationMap())
+       Renderer (const DeviceInterface&                vk,
+                         const VkDevice                                device,
+                         Allocator&                                    allocator,
+                         const deUint32                                queueFamilyIndex,
+                         const VkDescriptorSetLayout   descriptorSetLayout,    //!< may be NULL, if no descriptors are used
+                         BinaryCollection&                             binaryCollection,
+                         const std::string&                    vertexName,
+                         const std::string&                    fragmentName,
+                         const VkBuffer                                colorBuffer,
+                         const IVec2&                                  renderSize,
+                         const VkFormat                                colorFormat,
+                         const Vec4&                                   clearColor,
+                         const VkPrimitiveTopology             topology,
+                         SpecializationMap                             specMap = SpecializationMap())
                : m_colorBuffer                         (colorBuffer)
                , m_renderSize                          (renderSize)
                , m_colorFormat                         (colorFormat)
index 00e9cc3..26d9e62 100644 (file)
@@ -25,6 +25,12 @@ set(DEQP_VK_SPIRV_ASSEMBLY_SRCS
        vktSpvAsmUtils.hpp
        vktSpvAsmVariablePointersTests.cpp
        vktSpvAsmVariablePointersTests.hpp
+       vktSpvAsmSpirvVersionTests.cpp
+       vktSpvAsmSpirvVersionTests.hpp
+       vktSpvAsmLoopDepLenTests.cpp
+       vktSpvAsmLoopDepLenTests.hpp
+       vktSpvAsmLoopDepInfTests.cpp
+       vktSpvAsmLoopDepInfTests.hpp
        )
 
 set(DEQP_VK_SPIRV_ASSEMBLY_LIBS
index 090eadd..adcf0d4 100644 (file)
@@ -267,28 +267,6 @@ namespace vkt
 namespace SpirVAssembly
 {
 
-/*--------------------------------------------------------------------*//*!
- * \brief Test instance for compute pipeline
- *
- * The compute shader is specified in the format of SPIR-V assembly, which
- * is allowed to access MAX_NUM_INPUT_BUFFERS input storage buffers and
- * MAX_NUM_OUTPUT_BUFFERS output storage buffers maximally. The shader
- * source and input/output data are given in a ComputeShaderSpec object.
- *
- * This instance runs the given compute shader by feeding the data from input
- * buffers and compares the data in the output buffers with the expected.
- *//*--------------------------------------------------------------------*/
-class SpvAsmComputeShaderInstance : public TestInstance
-{
-public:
-                                                                               SpvAsmComputeShaderInstance     (Context& ctx, const ComputeShaderSpec& spec, const ComputeTestFeatures features);
-       tcu::TestStatus                                         iterate                                         (void);
-
-private:
-       const ComputeShaderSpec&                        m_shaderSpec;
-       const ComputeTestFeatures                       m_features;
-};
-
 // ComputeShaderTestCase implementations
 
 SpvAsmComputeShaderCase::SpvAsmComputeShaderCase (tcu::TestContext& testCtx, const char* name, const char* description, const ComputeShaderSpec& spec, const ComputeTestFeatures features)
@@ -300,11 +278,15 @@ SpvAsmComputeShaderCase::SpvAsmComputeShaderCase (tcu::TestContext& testCtx, con
 
 void SpvAsmComputeShaderCase::initPrograms (SourceCollections& programCollection) const
 {
-       programCollection.spirvAsmSources.add("compute") << m_shaderSpec.assembly.c_str();
+       programCollection.spirvAsmSources.add("compute") << m_shaderSpec.assembly.c_str() << SpirVAsmBuildOptions(m_shaderSpec.spirvVersion);
 }
 
 TestInstance* SpvAsmComputeShaderCase::createInstance (Context& ctx) const
 {
+       if (getMinRequiredVulkanVersion(m_shaderSpec.spirvVersion) < ctx.getUsedApiVersion())
+       {
+               TCU_THROW(NotSupportedError, std::string("Vulkan higher than " + getVulkanName(ctx.getUsedApiVersion()) + " is required for this test to run").c_str());
+       }
        return new SpvAsmComputeShaderInstance(ctx, m_shaderSpec, m_features);
 }
 
@@ -419,6 +401,10 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
        // Create compute shader and pipeline.
 
        const ProgramBinary&                            binary                          = m_context.getBinaryCollection().get("compute");
+       if (m_shaderSpec.verifyBinary && !m_shaderSpec.verifyBinary(binary))
+       {
+               return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
+       }
        Unique<VkShaderModule>                          module                          (createShaderModule(vkdi, device, binary, (VkShaderModuleCreateFlags)0u));
 
        Unique<VkPipeline>                                      computePipeline         (createComputePipeline(vkdi, device, *pipelineLayout, *module, m_shaderSpec.entryPoint.c_str(), m_shaderSpec.specConstants));
index 50c69e9..a29c843 100644 (file)
@@ -41,6 +41,28 @@ enum ComputeTestFeatures
        COMPUTE_TEST_USES_INT16_INT64,
 };
 
+/*--------------------------------------------------------------------*//*!
+ * \brief Test instance for compute pipeline
+ *
+ * The compute shader is specified in the format of SPIR-V assembly, which
+ * is allowed to access MAX_NUM_INPUT_BUFFERS input storage buffers and
+ * MAX_NUM_OUTPUT_BUFFERS output storage buffers maximally. The shader
+ * source and input/output data are given in a ComputeShaderSpec object.
+ *
+ * This instance runs the given compute shader by feeding the data from input
+ * buffers and compares the data in the output buffers with the expected.
+ *//*--------------------------------------------------------------------*/
+class SpvAsmComputeShaderInstance : public TestInstance
+{
+public:
+                                                                               SpvAsmComputeShaderInstance     (Context& ctx, const ComputeShaderSpec& spec, const ComputeTestFeatures features);
+       tcu::TestStatus                                         iterate                                         (void);
+
+private:
+       const ComputeShaderSpec&                        m_shaderSpec;
+       const ComputeTestFeatures                       m_features;
+};
+
 class SpvAsmComputeShaderCase : public TestCase
 {
 public:
index eec9c4a..2e871ef 100644 (file)
@@ -204,6 +204,8 @@ typedef bool (*ComputeVerifyIOFunc) (const std::vector<BufferSp>&           inputs,
                                                                         const std::vector<BufferSp>&           expectedOutputs,
                                                                         tcu::TestLog&                                          log);
 
+typedef bool (*ComputeVerifyBinaryFunc) (const ProgramBinary&  binary);
+
 /*--------------------------------------------------------------------*//*!
  * \brief Specification for a compute shader.
  *
@@ -230,6 +232,8 @@ struct ComputeShaderSpec
        // If true is returned, then the test case is assumed to have passed, if false is returned, then the test
        // case is assumed to have failed. Exact meaning of failure can be customized with failResult.
        ComputeVerifyIOFunc                                             verifyIO;
+       ComputeVerifyBinaryFunc                                 verifyBinary;
+       SpirvVersion                                                    spirvVersion;
 
                                                                                        ComputeShaderSpec (void)
                                                                                                : entryPoint                                    ("main")
@@ -238,6 +242,8 @@ struct ComputeShaderSpec
                                                                                                , failResult                                    (QP_TEST_RESULT_FAIL)
                                                                                                , failMessage                                   ("Output doesn't match with expected")
                                                                                                , verifyIO                                              (DE_NULL)
+                                                                                               , verifyBinary                                  (DE_NULL)
+                                                                                               , spirvVersion                                  (SPIRV_VERSION_1_0)
                                                                                        {}
 };
 
index 3213532..96c1405 100644 (file)
@@ -474,6 +474,7 @@ string makeVertexShaderAssembly(const map<string, string>& fragments)
                "OpName %BP_color \"color\"\n"
                "OpName %BP_gl_VertexIndex \"gl_VertexIndex\"\n"
                "OpName %BP_gl_InstanceIndex \"gl_InstanceIndex\"\n"
+               "${moduleprocessed:opt}\n"
                "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
                "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
                "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
@@ -577,6 +578,7 @@ string makeTessControlShaderAssembly (const map<string, string>& fragments)
                "OpName %BP_gl_in \"gl_in\"\n"
                "OpName %BP_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
                "OpName %BP_gl_TessLevelInner \"gl_TessLevelInner\"\n"
+               "${moduleprocessed:opt}\n"
                "OpDecorate %BP_out_color Location 1\n"
                "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
                "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
@@ -719,6 +721,7 @@ string makeTessEvalShaderAssembly(const map<string, string>& fragments)
                "OpName %BP_gl_in \"gl_in\"\n"
                "OpName %BP_out_color \"out_color\"\n"
                "OpName %BP_in_color \"in_color\"\n"
+               "${moduleprocessed:opt}\n"
                "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
                "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
                "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
@@ -878,6 +881,7 @@ string makeGeometryShaderAssembly(const map<string, string>& fragments)
                "OpName %BP_out_color \"out_color\"\n"
                "OpName %BP_in_color \"in_color\"\n"
                "OpName %test_code \"testfun(vf4;\"\n"
+               "${moduleprocessed:opt}\n"
                "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
                "OpDecorate %BP_out_gl_position BuiltIn Position\n"
                "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
@@ -1000,6 +1004,7 @@ string makeFragmentShaderAssembly(const map<string, string>& fragments)
                "OpName %BP_fragColor \"fragColor\"\n"
                "OpName %BP_vtxColor \"vtxColor\"\n"
                "OpName %test_code \"testfun(vf4;\"\n"
+               "${moduleprocessed:opt}\n"
                "OpDecorate %BP_fragColor Location 0\n"
                "OpDecorate %BP_vtxColor Location 1\n"
                "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
@@ -1262,116 +1267,141 @@ map<string, string> passthruFragments(void)
 
 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
 // Vertex shader gets custom code from context, the rest are pass-through.
-void addShaderCodeCustomVertex(vk::SourceCollections& dst, InstanceContext context)
+void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
 {
        if (!context.interfaces.empty())
        {
                // Inject boilerplate code to wire up additional input/output variables between stages.
                // Just copy the contents in input variable to output variable in all stages except
                // the customized stage.
-               dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        } else {
                map<string, string> passthru = passthruFragments();
 
-               dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
 }
 
+void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context)
+{
+       addShaderCodeCustomVertex(dst, context, DE_NULL);
+}
+
 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
 // Tessellation control shader gets custom code from context, the rest are
 // pass-through.
-void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext context)
+void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
 {
        if (!context.interfaces.empty())
        {
                // Inject boilerplate code to wire up additional input/output variables between stages.
                // Just copy the contents in input variable to output variable in all stages except
                // the customized stage.
-               dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
-               dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments);
-               dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType()));
-               dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
+               dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
        else
        {
                map<string, string> passthru = passthruFragments();
 
-               dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
-               dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(context.testCodeFragments);
-               dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(passthru);
-               dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
+               dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
 }
 
+void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context)
+{
+       addShaderCodeCustomTessControl(dst, context, DE_NULL);
+}
+
 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
 // Tessellation evaluation shader gets custom code from context, the rest are
 // pass-through.
-void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext context)
+void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
 {
        if (!context.interfaces.empty())
        {
                // Inject boilerplate code to wire up additional input/output variables between stages.
                // Just copy the contents in input variable to output variable in all stages except
                // the customized stage.
-               dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
-               dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType()));
-               dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
+               dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
        else
        {
                map<string, string> passthru = passthruFragments();
-               dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
-               dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(passthru);
-               dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
+               dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
 }
 
+void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context)
+{
+       addShaderCodeCustomTessEval(dst, context, DE_NULL);
+}
+
 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
 // Geometry shader gets custom code from context, the rest are pass-through.
-void addShaderCodeCustomGeometry(vk::SourceCollections& dst, InstanceContext context)
+void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
 {
        if (!context.interfaces.empty())
        {
                // Inject boilerplate code to wire up additional input/output variables between stages.
                // Just copy the contents in input variable to output variable in all stages except
                // the customized stage.
-               dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
-               dst.spirvAsmSources.add("geom") << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
        else
        {
                map<string, string> passthru = passthruFragments();
-               dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
-               dst.spirvAsmSources.add("geom") << makeGeometryShaderAssembly(context.testCodeFragments);
-               dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
 }
 
+void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context)
+{
+       addShaderCodeCustomGeometry(dst, context, DE_NULL);
+}
+
 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
 // Fragment shader gets custom code from context, the rest are pass-through.
-void addShaderCodeCustomFragment(vk::SourceCollections& dst, InstanceContext context)
+void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
 {
        if (!context.interfaces.empty())
        {
                // Inject boilerplate code to wire up additional input/output variables between stages.
                // Just copy the contents in input variable to output variable in all stages except
                // the customized stage.
-               dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
-               dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments);
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
        else
        {
                map<string, string> passthru = passthruFragments();
-               dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
-               dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(context.testCodeFragments);
+               dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(context.resources.spirvVersion);
+               dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(context.resources.spirvVersion);
        }
 }
 
+void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context)
+{
+       addShaderCodeCustomFragment(dst, context, DE_NULL);
+}
+
 void createCombinedModule(vk::SourceCollections& dst, InstanceContext)
 {
        // \todo [2015-12-07 awoloszyn] Make tessellation / geometry conditional
@@ -2174,6 +2204,11 @@ Move<VkBuffer> createBufferForResource(const DeviceInterface& vk, const VkDevice
 
 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
 {
+       if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) < context.getUsedApiVersion())
+       {
+               TCU_THROW(NotSupportedError, string("Vulkan higher than " + getVulkanName(context.getUsedApiVersion()) + " is required for this test to run").c_str());
+       }
+
        const InstanceInterface&                                        vkInstance                              = context.getInstanceInterface();
        const VkPhysicalDevice                                          vkPhysicalDevice                = context.getPhysicalDevice();
        const deUint32                                                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
@@ -2777,6 +2812,35 @@ TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instan
        // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
        vector<vector<VkSpecializationMapEntry> >       specConstantEntries;
        vector<VkSpecializationInfo>                            specializationInfos;
+       if (DE_NULL != instance.resources.verifyBinary)
+       {
+               std::string shaderName;
+               switch(instance.customizedStages)
+               {
+               case    VK_SHADER_STAGE_VERTEX_BIT:
+                       shaderName= "vert";
+                       break;
+               case    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+                       shaderName= "tessc";
+                       break;
+               case    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+                       shaderName= "tesse";
+                       break;
+               case    VK_SHADER_STAGE_GEOMETRY_BIT:
+                       shaderName= "geom";
+                       break;
+               case    VK_SHADER_STAGE_FRAGMENT_BIT:
+                       shaderName= "frag";
+                       break;
+               default:
+                       DE_ASSERT(0);
+                       break;
+               }
+               const ProgramBinary& binary  = context.getBinaryCollection().get(shaderName);
+               if (!instance.resources.verifyBinary(binary))
+                       return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
+
+       }
        createPipelineShaderStages(vk, *vkDevice, instance, context, modules, shaderStageParams);
 
        // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
index b1b93c0..2951a58 100644 (file)
@@ -75,25 +75,31 @@ typedef bool (*GraphicsVerifyIOFunc) (const std::vector<Resource>&          inputs,
                                                                          const std::vector<Resource>&          expectedOutputs,
                                                                          tcu::TestLog&                                         log);
 
+typedef bool (*GraphicsVerifyBinaryFunc) (const ProgramBinary& binary);
+
 // Resources used by graphics-pipeline-based tests.
 struct GraphicsResources
 {
        // Resources used as inputs.
-       std::vector<Resource>   inputs;
+       std::vector<Resource>           inputs;
        // Resources used as outputs. The data supplied will be used as
        // the expected outputs for the corresponding bindings by default.
        // If other behaviors are needed, please provide a custom verifyIO.
-       std::vector<Resource>   outputs;
+       std::vector<Resource>           outputs;
        // If null, a default verification will be performed by comparing the
        // memory pointed to by outputAllocations  and the contents of
        // expectedOutputs. Otherwise the function pointed to by verifyIO will
        // be called. If true is returned, then the test case is assumed to
        // have passed, if false is returned, then the test case is assumed
        // to have failed.
-       GraphicsVerifyIOFunc    verifyIO;
+       GraphicsVerifyIOFunc            verifyIO;
+       GraphicsVerifyBinaryFunc        verifyBinary;
+       SpirvVersion                            spirvVersion;
 
                                                        GraphicsResources()
-                                                               : verifyIO      (DE_NULL)
+                                                               : verifyIO              (DE_NULL)
+                                                               , verifyBinary  (DE_NULL)
+                                                               , spirvVersion  (SPIRV_VERSION_1_0)
                                                        {}
 };
 
@@ -398,6 +404,12 @@ InstanceContext createInstanceContext (const ShaderElement                                                 (&elements)[N],
 }
 
 
+void addShaderCodeCustomVertex(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
+void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
+void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
+void addShaderCodeCustomGeometry(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
+void addShaderCodeCustomFragment(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
+
 void createTestsForAllStages (const std::string&                                               name,
                                                          const tcu::RGBA                                                       (&inputColors)[4],
                                                          const tcu::RGBA                                                       (&outputColors)[4],
index 21824f5..fb852d8 100644 (file)
 #include "vktSpvAsmComputeShaderTestUtil.hpp"
 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
 #include "vktSpvAsmVariablePointersTests.hpp"
+#include "vktSpvAsmSpirvVersionTests.hpp"
 #include "vktTestCaseUtil.hpp"
+#include "vktSpvAsmLoopDepLenTests.hpp"
+#include "vktSpvAsmLoopDepInfTests.hpp"
 
 #include <cmath>
 #include <limits>
@@ -596,6 +599,103 @@ tcu::TestCaseGroup* createOpLineGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
+bool veryfiBinaryShader (const ProgramBinary& binary)
+{
+       const size_t    paternCount                     = 3u;
+       bool paternsCheck[paternCount]          =
+       {
+               false, false, false
+       };
+       const string patersns[paternCount]      =
+       {
+               "VULKAN CTS",
+               "Negative values",
+               "Date: 2017/09/21"
+       };
+       size_t                  paternNdx               = 0u;
+
+       for (size_t ndx = 0u; ndx < binary.getSize(); ++ndx)
+       {
+               if (false == paternsCheck[paternNdx] &&
+                       patersns[paternNdx][0] == static_cast<char>(binary.getBinary()[ndx]) &&
+                       deMemoryEqual((const char*)&binary.getBinary()[ndx], &patersns[paternNdx][0], patersns[paternNdx].length()))
+               {
+                       paternsCheck[paternNdx]= true;
+                       paternNdx++;
+                       if (paternNdx == paternCount)
+                               break;
+               }
+       }
+
+       for (size_t ndx = 0u; ndx < paternCount; ++ndx)
+       {
+               if (!paternsCheck[ndx])
+                       return false;
+       }
+
+       return true;
+}
+
+tcu::TestCaseGroup* createOpModuleProcessedGroup (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> group                   (new tcu::TestCaseGroup(testCtx, "opmoduleprocessed", "Test the OpModuleProcessed instruction"));
+       ComputeShaderSpec                               spec;
+       de::Random                                              rnd                             (deStringHash(group->getName()));
+       const int                                               numElements             = 10;
+       vector<float>                                   positiveFloats  (numElements, 0);
+       vector<float>                                   negativeFloats  (numElements, 0);
+
+       fillRandomScalars(rnd, 1.f, 100.f, &positiveFloats[0], numElements);
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+               negativeFloats[ndx] = -positiveFloats[ndx];
+
+       spec.assembly =
+               string(getComputeAsmShaderPreamble()) +
+               "%fname = OpString \"negateInputs.comp\"\n"
+
+               "OpSource GLSL 430\n"
+               "OpName %main           \"main\"\n"
+               "OpName %id             \"gl_GlobalInvocationID\"\n"
+               "OpModuleProcessed \"VULKAN CTS\"\n"                                    //OpModuleProcessed;
+               "OpModuleProcessed \"Negative values\"\n"
+               "OpModuleProcessed \"Date: 2017/09/21\"\n"
+               "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+               + string(getComputeAsmInputOutputBufferTraits())
+
+               + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+               "OpLine %fname 0 1\n"
+
+               "OpLine %fname 1000 1\n"
+
+               "%id        = OpVariable %uvec3ptr Input\n"
+               "%zero      = OpConstant %i32 0\n"
+               "%main      = OpFunction %void None %voidf\n"
+
+               "%label     = OpLabel\n"
+               "%idval     = OpLoad %uvec3 %id\n"
+               "%x         = OpCompositeExtract %u32 %idval 0\n"
+
+               "%inloc     = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval     = OpLoad %f32 %inloc\n"
+               "%neg       = OpFNegate %f32 %inval\n"
+               "%outloc    = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "             OpStore %outloc %neg\n"
+               "             OpReturn\n"
+               "             OpFunctionEnd\n";
+       spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
+       spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
+       spec.numWorkGroups = IVec3(numElements, 1, 1);
+       spec.verifyBinary = veryfiBinaryShader;
+       spec.spirvVersion = SPIRV_VERSION_1_3;
+
+       group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpModuleProcessed Tests", spec));
+
+       return group.release();
+}
+
 tcu::TestCaseGroup* createOpNoLineGroup (tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> group                   (new tcu::TestCaseGroup(testCtx, "opnoline", "Test the OpNoLine instruction"));
@@ -4113,6 +4213,9 @@ tcu::TestCaseGroup* createLoopControlGroup (tcu::TestContext& testCtx)
                group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
        }
 
+       group->addChild(new SpvAsmLoopControlDependencyLengthCase(testCtx, "dependency_length", "dependency_length"));
+       group->addChild(new SpvAsmLoopControlDependencyInfiniteCase(testCtx, "dependency_infinite", "dependency_infinite"));
+
        return group.release();
 }
 
@@ -4526,7 +4629,6 @@ tcu::TestCaseGroup* createOpSourceContinuedTests (tcu::TestContext& testCtx)
 
        return opSourceTests.release();
 }
-
 tcu::TestCaseGroup* createOpNoLineTests(tcu::TestContext& testCtx)
 {
        RGBA                                                             defaultColors[4];
@@ -4582,6 +4684,44 @@ tcu::TestCaseGroup* createOpNoLineTests(tcu::TestContext& testCtx)
        return opLineTests.release();
 }
 
+tcu::TestCaseGroup* createOpModuleProcessedTests(tcu::TestContext& testCtx)
+{
+       RGBA                                                            defaultColors[4];
+       de::MovePtr<tcu::TestCaseGroup>         opModuleProcessedTests                  (new tcu::TestCaseGroup(testCtx, "opmoduleprocessed", "OpModuleProcessed instruction"));
+       map<string, string>                                     fragments;
+       std::vector<std::string>                        noExtensions;
+       GraphicsResources                                       resources;
+
+       getDefaultColors(defaultColors);
+       resources.verifyBinary = veryfiBinaryShader;
+       resources.spirvVersion = SPIRV_VERSION_1_3;
+
+       fragments["moduleprocessed"]                                                    =
+               "OpModuleProcessed \"VULKAN CTS\"\n"
+               "OpModuleProcessed \"Negative values\"\n"
+               "OpModuleProcessed \"Date: 2017/09/21\"\n";
+
+       fragments["pre_main"]   =
+               "%second_function = OpFunction %v4f32 None %v4f32_function\n"
+               "%second_param1 = OpFunctionParameter %v4f32\n"
+               "%label_secondfunction = OpLabel\n"
+               "OpReturnValue %second_param1\n"
+               "OpFunctionEnd\n";
+
+       fragments["testfun"]            =
+               // A %test_code function that returns its argument unchanged.
+               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%param1 = OpFunctionParameter %v4f32\n"
+               "%label_testfun = OpLabel\n"
+               "%val1 = OpFunctionCall %v4f32 %second_function %param1\n"
+               "OpReturnValue %val1\n"
+               "OpFunctionEnd\n";
+
+       createTestsForAllStages ("opmoduleprocessed", defaultColors, defaultColors, fragments, resources, noExtensions, opModuleProcessedTests.get());
+
+       return opModuleProcessedTests.release();
+}
+
 
 tcu::TestCaseGroup* createOpLineTests(tcu::TestContext& testCtx)
 {
@@ -7910,15 +8050,19 @@ tcu::TestCaseGroup* createOpNopTests (tcu::TestContext& testCtx)
 
 tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
 {
+       const bool testComputePipeline = true;
+
        de::MovePtr<tcu::TestCaseGroup> instructionTests        (new tcu::TestCaseGroup(testCtx, "instruction", "Instructions with special opcodes/operands"));
        de::MovePtr<tcu::TestCaseGroup> computeTests            (new tcu::TestCaseGroup(testCtx, "compute", "Compute Instructions with special opcodes/operands"));
        de::MovePtr<tcu::TestCaseGroup> graphicsTests           (new tcu::TestCaseGroup(testCtx, "graphics", "Graphics Instructions with special opcodes/operands"));
 
+       computeTests->addChild(createSpivVersionCheckTests(testCtx, testComputePipeline));
        computeTests->addChild(createOpNopGroup(testCtx));
        computeTests->addChild(createOpFUnordGroup(testCtx));
        computeTests->addChild(createOpAtomicGroup(testCtx, false));
        computeTests->addChild(createOpAtomicGroup(testCtx, true)); // Using new StorageBuffer decoration
        computeTests->addChild(createOpLineGroup(testCtx));
+       computeTests->addChild(createOpModuleProcessedGroup(testCtx));
        computeTests->addChild(createOpNoLineGroup(testCtx));
        computeTests->addChild(createOpConstantNullGroup(testCtx));
        computeTests->addChild(createOpConstantCompositeGroup(testCtx));
@@ -7967,9 +8111,11 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
        computeTests->addChild(createConditionalBranchComputeGroup(testCtx));
        computeTests->addChild(createIndexingComputeGroup(testCtx));
        computeTests->addChild(createVariablePointersComputeGroup(testCtx));
+       graphicsTests->addChild(createSpivVersionCheckTests(testCtx, !testComputePipeline));
        graphicsTests->addChild(createOpNopTests(testCtx));
        graphicsTests->addChild(createOpSourceTests(testCtx));
        graphicsTests->addChild(createOpSourceContinuedTests(testCtx));
+       graphicsTests->addChild(createOpModuleProcessedTests(testCtx));
        graphicsTests->addChild(createOpLineTests(testCtx));
        graphicsTests->addChild(createOpNoLineTests(testCtx));
        graphicsTests->addChild(createOpConstantNullTests(testCtx));
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.cpp
new file mode 100644 (file)
index 0000000..c2c6e2e
--- /dev/null
@@ -0,0 +1,218 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Loop Control for DependencyInfinite qualifier tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkApiVersion.hpp"
+
+#include "vktSpvAsmLoopDepInfTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktSpvAsmComputeShaderCase.hpp"
+
+#include "deRandom.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+using namespace vk;
+using std::map;
+using std::string;
+using std::vector;
+
+// Assembly code used for testing loop control with dependencies is based on GLSL source code:
+// #version 430
+//
+// layout(std140, set = 0, binding = 0) readonly buffer Input {
+//   float elements[];
+// } input_data;
+// layout(std140, set = 0, binding = 1) writeonly buffer Output {
+//   float elements[];
+// } output_data;
+//
+// void main() {
+//   const uint n = 12;
+//   float c[n];
+//   uint x = gl_GlobalInvocationID.x;
+//
+//   for (uint i = 0; i < n; ++i)
+//     c[i] = float(i) * input_data.elements[x];
+//
+//   output_data.elements[x] = 0.0f;
+//   for (uint i = 0; i < n; ++i)
+//     output_data.elements[x] += c[i];
+// }
+static void getComputeSourceCode (std::string& computeSourceCode)
+{
+       computeSourceCode =
+               string(getComputeAsmShaderPreamble()) +
+
+               "OpSource GLSL 430\n"
+               "OpName %main \"main\"\n"
+               "OpName %id \"gl_GlobalInvocationID\"\n"
+
+               "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+               + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+               "%u32ptr        = OpTypePointer Function %u32\n"
+
+               "%id            = OpVariable %uvec3ptr Input\n"
+               "%zero          = OpConstant %i32 0\n"
+               "%uzero         = OpConstant %u32 0\n"
+               "%fzero         = OpConstant %f32 0\n"
+               "%one           = OpConstant %i32 1\n"
+               "%twelve        = OpConstant %u32 12\n"
+                "%f32arr12_t    = OpTypeArray %f32 %twelve\n"
+                "%f32arr12ptr_t = OpTypePointer Function %f32arr12_t\n"
+               "%f32funcptr    = OpTypePointer Function %f32\n"
+               "%main          = OpFunction %void None %voidf\n"
+               "%entry         = OpLabel\n"
+
+               "%f32arr12      = OpVariable %f32arr12ptr_t Function\n"
+
+               "%i1            = OpVariable %u32ptr Function\n"
+               "                 OpStore %i1 %uzero\n"
+               "%i2            = OpVariable %u32ptr Function\n"
+               "                 OpStore %i2 %uzero\n"
+
+               "%idval         = OpLoad %uvec3 %id\n"
+               "%x             = OpCompositeExtract %u32 %idval 0\n"
+               "%inloc         = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval         = OpLoad %f32 %inloc\n"
+
+               // for (uint i = 0; i < 12; ++i) c[i] = float(i) * input_data.elements[x];
+               "                 OpBranch %loop1_entry\n"
+               "%loop1_entry   = OpLabel\n"
+               "%i1_val        = OpLoad %u32 %i1\n"
+               "%cmp1_lt       = OpULessThan %bool %i1_val %twelve\n"
+               "                 OpLoopMerge %loop1_merge %loop1_body DependencyInfinite\n"
+               "                 OpBranchConditional %cmp1_lt %loop1_body %loop1_merge\n"
+               "%loop1_body    = OpLabel\n"
+               "%i1_valf32     = OpConvertUToF %f32 %i1_val\n"
+               "%mulf1         = OpFMul %f32 %i1_valf32 %inval\n"
+               "%outloc1       = OpAccessChain %f32funcptr %f32arr12 %i1_val\n"
+               "                 OpStore %outloc1 %mulf1\n"
+               "%new1_i        = OpIAdd %u32 %i1_val %one\n"
+               "                 OpStore %i1 %new1_i\n"
+               "                 OpBranch %loop1_entry\n"
+               "%loop1_merge   = OpLabel\n"
+
+               //   output_data.elements[x] = 0.0f;
+               "%outloc        = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "                 OpStore %outloc %fzero\n"
+               "                 OpBranch %loop2_entry\n"
+
+               //   for (uint i = 0; i < n; ++i) output_data.elements[x] += c[i];
+               "%loop2_entry   = OpLabel\n"
+               "%i2_val        = OpLoad %u32 %i2\n"
+               "%cmp2_lt       = OpULessThan %bool %i2_val %twelve\n"
+               "                 OpLoopMerge %loop2_merge %loop2_body None\n"
+               "                 OpBranchConditional %cmp2_lt %loop2_body %loop2_merge\n"
+               "%loop2_body    = OpLabel\n"
+               "%arr1_i2loc    = OpAccessChain %f32funcptr %f32arr12 %i2_val\n"
+               "%arr1_i2val    = OpLoad %f32 %arr1_i2loc\n"
+               "%outval        = OpLoad %f32 %outloc\n"
+               "%addf1         = OpFAdd %f32 %outval %arr1_i2val\n"
+               "                 OpStore %outloc %addf1\n"
+               "%new_i2        = OpIAdd %u32 %i2_val %one\n"
+               "                 OpStore %i2 %new_i2\n"
+               "                 OpBranch %loop2_entry\n"
+               "%loop2_merge   = OpLabel\n"
+
+               "                 OpReturn\n"
+               "                 OpFunctionEnd\n";
+}
+
+static ComputeShaderSpec getComputeShaderSpec ()
+{
+       de::Random                      rnd                             (0xABC);
+       const int                       numElements             = 100;
+       vector<float>           inputFloats             (numElements, 0);
+       vector<float>           outputFloats    (numElements, 0);
+       ComputeShaderSpec       spec;
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+               inputFloats[ndx] = rnd.getFloat(1.0f, 100.0f);
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+       {
+               const deUint32 n = 12;
+               float c[n];
+               float result = 0.0f;
+
+               for (deUint32 i = 0; i < n; ++i)
+                       c[i] = float(i) * inputFloats[ndx];
+
+               for (deUint32 i = 0; i < n; ++i)
+                       result += c[i];
+
+               outputFloats[ndx] = result;
+       }
+
+       // Shader source code can be retrieved to complete definition of ComputeShaderSpec, though it is not required at this stage
+       // getComputeSourceCode (spec.assembly);
+
+       spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+       spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+       spec.numWorkGroups = tcu::IVec3(numElements, 1, 1);
+
+       return spec;
+}
+
+
+class SpvAsmLoopControlDependencyInfiniteInstance : public ComputeShaderSpec, public SpvAsmComputeShaderInstance
+{
+public:
+       SpvAsmLoopControlDependencyInfiniteInstance     (Context& ctx);
+};
+
+SpvAsmLoopControlDependencyInfiniteInstance::SpvAsmLoopControlDependencyInfiniteInstance (Context& ctx)
+       : ComputeShaderSpec(getComputeShaderSpec())
+       , SpvAsmComputeShaderInstance(ctx, *this, COMPUTE_TEST_USES_NONE)
+{
+}
+
+SpvAsmLoopControlDependencyInfiniteCase::SpvAsmLoopControlDependencyInfiniteCase (tcu::TestContext& testCtx, const char* name, const char* description)
+       : TestCase                      (testCtx, name, description)
+{
+}
+
+void SpvAsmLoopControlDependencyInfiniteCase::initPrograms (SourceCollections& programCollection) const
+{
+       std::string comp;
+
+       getComputeSourceCode(comp);
+
+       programCollection.spirvAsmSources.add("compute") << SpirVAsmBuildOptions(SPIRV_VERSION_1_3) << comp;
+}
+
+TestInstance* SpvAsmLoopControlDependencyInfiniteCase::createInstance (Context& context) const
+{
+       if (context.getUsedApiVersion() < VK_API_VERSION_1_1)
+               TCU_THROW(NotSupportedError, "SPIR-V higher than 1.3 is required for this test to run");
+
+       return new SpvAsmLoopControlDependencyInfiniteInstance(context);
+}
+
+} // SpirVAssembly
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.hpp
new file mode 100644 (file)
index 0000000..f572fc6
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _VKTSPVASMLOOPDEPINFTESTS_HPP
+#define _VKTSPVASMLOOPDEPINFTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Loop Control for DependencyInfinite qualifier tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+class SpvAsmLoopControlDependencyInfiniteCase : public TestCase
+{
+public:
+                                                       SpvAsmLoopControlDependencyInfiniteCase (tcu::TestContext& testCtx, const char* name, const char* description);
+       void                                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*                   createInstance                                                  (Context& context) const;
+};
+
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMLOOPDEPINFTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.cpp
new file mode 100644 (file)
index 0000000..935dbc2
--- /dev/null
@@ -0,0 +1,233 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Loop Control for DependencyLength qualifier tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkApiVersion.hpp"
+
+#include "vktSpvAsmLoopDepLenTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktSpvAsmComputeShaderCase.hpp"
+
+#include "deRandom.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+using namespace vk;
+using std::map;
+using std::string;
+using std::vector;
+
+// Assembly code used for testing loop control with dependencies is based on GLSL source code:
+// #version 430
+//
+// layout(std140, set = 0, binding = 0) readonly buffer Input {
+//   float elements[];
+// } input_data;
+// layout(std140, set = 0, binding = 1) writeonly buffer Output {
+//   float elements[];
+// } output_data;
+//
+// void main() {
+//   const uint n = 12;
+//   float c[n];
+//   uint x = gl_GlobalInvocationID.x;
+//
+//   for (uint i = 0; i < 6; ++i)
+//     c[i] = float(i) * input_data.elements[x];
+//
+//   for (uint i = 6; i < n; ++i)
+//     c[i] = c[i - 4] + c[i - 5] + c[i - 6];
+//
+//   output_data.elements[x] = c[n - 1];
+// }
+static void getComputeSourceCode (std::string& computeSourceCode)
+{
+       computeSourceCode =
+               string(getComputeAsmShaderPreamble()) +
+
+               "OpSource GLSL 430\n"
+               "OpName %main \"main\"\n"
+               "OpName %id \"gl_GlobalInvocationID\"\n"
+
+               "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+               + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+               "%u32ptr        = OpTypePointer Function %u32\n"
+
+               "%id            = OpVariable %uvec3ptr Input\n"
+               "%zero          = OpConstant %i32 0\n"
+               "%uzero         = OpConstant %u32 0\n"
+               "%one           = OpConstant %i32 1\n"
+
+               "%four          = OpConstant %u32 4\n"
+               "%five          = OpConstant %u32 5\n"
+               "%six           = OpConstant %u32 6\n"
+               "%elleven       = OpConstant %u32 11\n"
+               "%twelve        = OpConstant %u32 12\n"
+
+               "%f32arr12_t    = OpTypeArray %f32 %twelve\n"
+               "%f32arr12ptr_t = OpTypePointer Function %f32arr12_t\n"
+               "%f32funcptr    = OpTypePointer Function %f32\n"
+
+               "%main          = OpFunction %void None %voidf\n"
+               "%entry         = OpLabel\n"
+
+               "%f32arr12      = OpVariable %f32arr12ptr_t Function\n"
+
+               "%i1            = OpVariable %u32ptr Function\n"
+               "                 OpStore %i1 %uzero\n"
+               "%i2            = OpVariable %u32ptr Function\n"
+               "                 OpStore %i2 %six\n"
+
+               "%idval         = OpLoad %uvec3 %id\n"
+               "%x             = OpCompositeExtract %u32 %idval 0\n"
+               "%inloc         = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval         = OpLoad %f32 %inloc\n"
+
+               // for (uint i = 0; i < 6; ++i) c[i] = float(i) * input_data.elements[x];
+               "                 OpBranch %loop1_entry\n"
+               "%loop1_entry   = OpLabel\n"
+               "%i1_val        = OpLoad %u32 %i1\n"
+               "%cmp1_lt       = OpULessThan %bool %i1_val %six\n"
+               "                 OpLoopMerge %loop1_merge %loop1_body None\n"
+               "                 OpBranchConditional %cmp1_lt %loop1_body %loop1_merge\n"
+               "%loop1_body    = OpLabel\n"
+               "%i1_valf32     = OpConvertUToF %f32 %i1_val\n"
+               "%mulf1         = OpFMul %f32 %i1_valf32 %inval\n"
+               "%outloc1       = OpAccessChain %f32funcptr %f32arr12 %i1_val\n"
+               "                 OpStore %outloc1 %mulf1\n"
+               "%new1_i        = OpIAdd %u32 %i1_val %one\n"
+               "                 OpStore %i1 %new1_i\n"
+               "                 OpBranch %loop1_entry\n"
+               "%loop1_merge   = OpLabel\n"
+
+               //   for (uint i = 6; i < n; ++i) c[i] = c[i - 4] + c[i - 5] + c[i - 6];
+               "                 OpBranch %loop2_entry\n"
+               "%loop2_entry   = OpLabel\n"
+               "%i2_val        = OpLoad %u32 %i2\n"
+               "%cmp2_lt       = OpULessThan %bool %i2_val %twelve\n"
+               "                 OpLoopMerge %loop2_merge %loop2_body DependencyLength 3\n"
+               "                 OpBranchConditional %cmp2_lt %loop2_body %loop2_merge\n"
+               "%loop2_body    = OpLabel\n"
+               "%i2_m4         = OpISub %u32 %i2_val %four\n"
+               "%arr1_i2m4loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m4\n"
+               "%arr1_i2m4val  = OpLoad %f32 %arr1_i2m4loc\n"
+               "%i2_m5         = OpISub %u32 %i2_val %five\n"
+               "%arr1_i2m5loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m5\n"
+               "%arr1_i2m5val  = OpLoad %f32 %arr1_i2m5loc\n"
+               "%f32add1       = OpFAdd %f32 %arr1_i2m4val %arr1_i2m5val\n"
+               "%i2_m6         = OpISub %u32 %i2_val %six\n"
+               "%arr1_i2m6loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m6\n"
+               "%arr1_i2m6val  = OpLoad %f32 %arr1_i2m6loc\n"
+               "%f32add2       = OpFAdd %f32 %f32add1 %arr1_i2m6val\n"
+               "%outloc2       = OpAccessChain %f32funcptr %f32arr12 %i2_val\n"
+               "                 OpStore %outloc2 %f32add2\n"
+               "%new_i2        = OpIAdd %u32 %i2_val %one\n"
+               "                 OpStore %i2 %new_i2\n"
+               "                 OpBranch %loop2_entry\n"
+               "%loop2_merge   = OpLabel\n"
+
+               //   output_data.elements[x] = c[n - 1];
+               "%arr1locq      = OpAccessChain %f32funcptr %f32arr12 %elleven\n"
+               "%arr1valq      = OpLoad %f32 %arr1locq\n"
+               "%outlocq       = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "                 OpStore %outlocq %arr1valq\n"
+               "                 OpReturn\n"
+               "                 OpFunctionEnd\n";
+}
+
+static ComputeShaderSpec getComputeShaderSpec ()
+{
+       de::Random                      rnd                             (0xABC);
+       const int                       numElements             = 100;
+       vector<float>           inputFloats             (numElements, 0);
+       vector<float>           outputFloats    (numElements, 0);
+       ComputeShaderSpec       spec;
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+               inputFloats[ndx] = rnd.getFloat(1.0f, 100.0f);
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+       {
+               const deUint32 n = 12;
+               float c[n];
+
+               for (deUint32 i = 0; i < 6; ++i)
+                       c[i] = float(i) * inputFloats[ndx];
+
+               for (deUint32 i = 6; i < n; ++i)
+                       c[i] = c[i - 4] + c[i - 5] + c[i - 6];
+
+               outputFloats[ndx] = c[n - 1];
+       }
+
+       // Shader source code can be retrieved to complete definition of ComputeShaderSpec, though it is not required at this stage
+       // getComputeSourceCode (spec.assembly);
+
+       spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+       spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+       spec.numWorkGroups = tcu::IVec3(numElements, 1, 1);
+
+       return spec;
+}
+
+
+class SpvAsmLoopControlDependencyLengthInstance : public ComputeShaderSpec, public SpvAsmComputeShaderInstance
+{
+public:
+       SpvAsmLoopControlDependencyLengthInstance       (Context& ctx);
+};
+
+SpvAsmLoopControlDependencyLengthInstance::SpvAsmLoopControlDependencyLengthInstance (Context& ctx)
+       : ComputeShaderSpec(getComputeShaderSpec())
+       , SpvAsmComputeShaderInstance(ctx, *this, COMPUTE_TEST_USES_NONE)
+{
+}
+
+SpvAsmLoopControlDependencyLengthCase::SpvAsmLoopControlDependencyLengthCase (tcu::TestContext& testCtx, const char* name, const char* description)
+       : TestCase                      (testCtx, name, description)
+{
+}
+
+void SpvAsmLoopControlDependencyLengthCase::initPrograms (SourceCollections& programCollection) const
+{
+       std::string comp;
+
+       getComputeSourceCode(comp);
+
+       programCollection.spirvAsmSources.add("compute") << SpirVAsmBuildOptions(SPIRV_VERSION_1_3) << comp;
+}
+
+TestInstance* SpvAsmLoopControlDependencyLengthCase::createInstance (Context& context) const
+{
+       if (context.getUsedApiVersion() < VK_API_VERSION_1_1)
+               TCU_THROW(NotSupportedError, "SPIR-V higher than 1.3 is required for this test to run");
+
+       return new SpvAsmLoopControlDependencyLengthInstance(context);
+}
+
+} // SpirVAssembly
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.hpp
new file mode 100644 (file)
index 0000000..25c55a9
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _VKTSPVASMLOOPDEPLENTESTS_HPP
+#define _VKTSPVASMLOOPDEPLENTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Loop Control for DependencyLength qualifier tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+class SpvAsmLoopControlDependencyLengthCase : public TestCase
+{
+public:
+                                                       SpvAsmLoopControlDependencyLengthCase   (tcu::TestContext& testCtx, const char* name, const char* description);
+       void                                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*                   createInstance                                                  (Context& context) const;
+};
+
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMLOOPDEPLENTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp
new file mode 100644 (file)
index 0000000..98ded32
--- /dev/null
@@ -0,0 +1,399 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Versions check cases
+ *//*--------------------------------------------------------------------*/
+
+#include "vkApiVersion.hpp"
+
+#include "vktSpvAsmSpirvVersionTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktSpvAsmComputeShaderCase.hpp"
+#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+using namespace vk;
+using std::map;
+using std::string;
+using std::vector;
+using tcu::RGBA;
+
+enum Operation
+{
+       OPERATION_COMPUTE = 0,
+       OPERATION_GRAPHICS_VERTEX,
+       OPERATION_GRAPHICS_TESSELATION_EVALUATION,
+       OPERATION_GRAPHICS_TESSELATION_CONTROL,
+       OPERATION_GRAPHICS_GEOMETRY,
+       OPERATION_GRAPHICS_FRAGMENT,
+       OPERATION_LAST
+};
+
+Operation& operator++ (Operation& operation)
+{
+       if (operation == OPERATION_LAST)
+               operation = OPERATION_COMPUTE;
+       else
+               operation = static_cast<Operation>(static_cast<deUint32>(operation) + 1);
+
+       return operation;
+}
+
+struct TestParameters
+{
+       Operation               operation;
+       SpirvVersion    spirvVersion;
+};
+
+static InstanceContext initGraphicsInstanceContext (const TestParameters& testParameters)
+{
+       static const ShaderElement      vertFragPipelineStages[]                =
+       {
+               ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
+               ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
+       };
+       static const ShaderElement      tessPipelineStages[]                    =
+       {
+               ShaderElement("vert",  "main", VK_SHADER_STAGE_VERTEX_BIT),
+               ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
+               ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
+               ShaderElement("frag",  "main", VK_SHADER_STAGE_FRAGMENT_BIT),
+       };
+       static const ShaderElement      geomPipelineStages[]                    =
+       {
+               ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
+               ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT),
+               ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
+       };
+       map<string, string>                     opSimpleTest;
+
+       opSimpleTest["testfun"] =
+               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%param1 = OpFunctionParameter %v4f32\n"
+               "%label_testfun = OpLabel\n"
+               "%a = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+               "%b = OpFAdd %f32 %a %a\n"
+               "%c = OpFSub %f32 %b %a\n"
+               "%ret = OpVectorInsertDynamic %v4f32 %param1 %c %c_i32_0\n"
+               "OpReturnValue %ret\n"
+               "OpFunctionEnd\n";
+
+       switch (testParameters.operation)
+       {
+               case OPERATION_GRAPHICS_VERTEX:                                 return createInstanceContext(vertFragPipelineStages, opSimpleTest);
+               case OPERATION_GRAPHICS_TESSELATION_EVALUATION: return createInstanceContext(tessPipelineStages, opSimpleTest);
+               case OPERATION_GRAPHICS_TESSELATION_CONTROL:    return createInstanceContext(tessPipelineStages, opSimpleTest);
+               case OPERATION_GRAPHICS_GEOMETRY:                               return createInstanceContext(geomPipelineStages, opSimpleTest);
+               case OPERATION_GRAPHICS_FRAGMENT:                               return createInstanceContext(vertFragPipelineStages, opSimpleTest);
+               default:                                                                                TCU_THROW(InternalError, "Invalid operation specified");
+       }
+}
+
+static void getComputeSourceCode (std::string& computeSourceCode)
+{
+       computeSourceCode =
+               string(getComputeAsmShaderPreamble()) +
+
+               "OpSource GLSL 430\n"
+               "OpName %main           \"main\"\n"
+               "OpName %id             \"gl_GlobalInvocationID\"\n"
+
+               "OpDecorate %id BuiltIn GlobalInvocationId\n" +
+
+               string(getComputeAsmInputOutputBufferTraits()) +
+               string(getComputeAsmCommonTypes()) +
+               string(getComputeAsmInputOutputBuffer()) +
+
+               "%id        = OpVariable %uvec3ptr Input\n"
+               "%zero      = OpConstant %i32 0\n"
+
+               "%main      = OpFunction %void None %voidf\n"
+               "%label     = OpLabel\n"
+               "%idval     = OpLoad %uvec3 %id\n"
+               "%x         = OpCompositeExtract %u32 %idval 0\n"
+
+               "             OpNop\n" // Inside a function body
+
+               "%inloc     = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval     = OpLoad %f32 %inloc\n"
+               "%neg       = OpFNegate %f32 %inval\n"
+               "%outloc    = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "             OpStore %outloc %neg\n"
+               "             OpReturn\n"
+               "             OpFunctionEnd\n";
+}
+
+static ComputeShaderSpec getComputeShaderSpec (const TestParameters& testParameters)
+{
+       ComputeShaderSpec       spec;
+       const deUint32          seed                    = (static_cast<deUint32>(testParameters.operation)<<16) ^ static_cast<deUint32>(testParameters.spirvVersion);
+       de::Random                      rnd                             (seed);
+       const int                       numElements             = 100;
+       vector<float>           positiveFloats  (numElements, 0);
+       vector<float>           negativeFloats  (numElements, 0);
+
+       for (size_t ndx = 0; ndx < numElements; ++ndx)
+       {
+               positiveFloats[ndx] = rnd.getFloat(1.0f, 100.0f);
+               negativeFloats[ndx] = -positiveFloats[ndx];
+       }
+
+       // Shader source code can be retrieved to complete definition of ComputeShaderSpec, though it is not required at this stage
+       // getComputeSourceCode (spec.assembly);
+
+       spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
+       spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
+       spec.numWorkGroups = tcu::IVec3(numElements, 1, 1);
+
+       return spec;
+}
+
+static bool isSpirVersionsAsRequested (const BinaryCollection& binaryCollection, SpirvVersion requestedSpirvVersion)
+{
+       bool    result  = true;
+
+       DE_ASSERT(!binaryCollection.empty());
+
+       for (vk::BinaryCollection::Iterator binaryIt = binaryCollection.begin(); binaryIt != binaryCollection.end(); ++binaryIt)
+       {
+               SpirvVersion    binarySpirvVersion      = extractSpirvVersion   (binaryIt.getProgram());
+
+               if (binarySpirvVersion != requestedSpirvVersion)
+                       result = false;
+       }
+
+       return result;
+}
+
+class SpvAsmGraphicsSpirvVersionsInstance : public TestInstance
+{
+public:
+                                       SpvAsmGraphicsSpirvVersionsInstance     (Context& ctx, const TestParameters& testParameters);
+       tcu::TestStatus iterate                                                         (void);
+
+private:
+       TestParameters  m_testParameters;
+};
+
+SpvAsmGraphicsSpirvVersionsInstance::SpvAsmGraphicsSpirvVersionsInstance (Context& ctx, const TestParameters& testParameters)
+       : TestInstance          (ctx)
+       , m_testParameters      (testParameters)
+{
+}
+
+tcu::TestStatus SpvAsmGraphicsSpirvVersionsInstance::iterate (void)
+{
+       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+       if (!isSpirVersionsAsRequested(m_context.getBinaryCollection(), m_testParameters.spirvVersion))
+               return tcu::TestStatus::fail("Binary SPIR-V version is different from requested");
+
+       return runAndVerifyDefaultPipeline(m_context, instanceContext);
+}
+
+
+class SpvAsmComputeSpirvVersionsInstance : public ComputeShaderSpec, public SpvAsmComputeShaderInstance
+{
+public:
+                                       SpvAsmComputeSpirvVersionsInstance      (Context& ctx, const TestParameters& testParameters);
+       tcu::TestStatus iterate                                                         (void);
+
+private:
+       TestParameters  m_testParameters;
+};
+
+SpvAsmComputeSpirvVersionsInstance::SpvAsmComputeSpirvVersionsInstance (Context& ctx, const TestParameters& testParameters)
+       : ComputeShaderSpec(getComputeShaderSpec(testParameters))
+       , SpvAsmComputeShaderInstance(ctx, *this, COMPUTE_TEST_USES_NONE)
+       , m_testParameters(testParameters)
+{
+       if (m_testParameters.operation != OPERATION_COMPUTE)
+               TCU_THROW(InternalError, "Invalid operation specified");
+}
+
+tcu::TestStatus SpvAsmComputeSpirvVersionsInstance::iterate (void)
+{
+       if (!isSpirVersionsAsRequested(m_context.getBinaryCollection(), m_testParameters.spirvVersion))
+               return tcu::TestStatus::fail("Binary SPIR-V version is different from requested");
+
+       return SpvAsmComputeShaderInstance::iterate();
+}
+
+
+class SpvAsmSpirvVersionsCase : public TestCase
+{
+public:
+                                                       SpvAsmSpirvVersionsCase (tcu::TestContext& testCtx, const char* name, const char* description, const TestParameters& testParameters);
+       void                                    initPrograms                    (vk::SourceCollections& programCollection) const;
+       TestInstance*                   createInstance                  (Context& context) const;
+
+private:
+       const TestParameters    m_testParameters;
+};
+
+SpvAsmSpirvVersionsCase::SpvAsmSpirvVersionsCase (tcu::TestContext& testCtx, const char* name, const char* description, const TestParameters& testParameters)
+       : TestCase                      (testCtx, name, description)
+       , m_testParameters      (testParameters)
+{
+}
+
+void validateVulkanVersion (const deUint32 usedVulkanVersion, const SpirvVersion testedSpirvVersion)
+{
+       const SpirvVersion      usedSpirvVersionForAsm  = getSpirvVersionForAsm(usedVulkanVersion);
+
+       if (testedSpirvVersion > usedSpirvVersionForAsm)
+               TCU_THROW(NotSupportedError, "Specified SPIR-V version is not supported by the device/instance");
+}
+
+void SpvAsmSpirvVersionsCase::initPrograms (SourceCollections& programCollection) const
+{
+       const SpirVAsmBuildOptions      spirVAsmBuildOptions    (m_testParameters.spirvVersion);
+
+       validateVulkanVersion(programCollection.usedVulkanVersion, m_testParameters.spirvVersion);
+
+       switch (m_testParameters.operation)
+       {
+               case OPERATION_COMPUTE:
+               {
+                       std::string comp;
+
+                       getComputeSourceCode(comp);
+
+                       programCollection.spirvAsmSources.add("compute", &spirVAsmBuildOptions) << comp;
+
+                       break;
+               }
+
+               case OPERATION_GRAPHICS_VERTEX:
+               {
+                       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+                       addShaderCodeCustomVertex(programCollection, instanceContext, &spirVAsmBuildOptions);
+
+                       break;
+               }
+
+               case OPERATION_GRAPHICS_TESSELATION_EVALUATION:
+               {
+                       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+                       addShaderCodeCustomTessEval(programCollection, instanceContext, &spirVAsmBuildOptions);
+
+                       break;
+               }
+
+               case OPERATION_GRAPHICS_TESSELATION_CONTROL:
+               {
+                       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+                       addShaderCodeCustomTessControl(programCollection, instanceContext, &spirVAsmBuildOptions);
+
+                       break;
+               }
+
+               case OPERATION_GRAPHICS_GEOMETRY:
+               {
+                       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+                       addShaderCodeCustomGeometry(programCollection, instanceContext, &spirVAsmBuildOptions);
+
+                       break;
+               }
+
+               case OPERATION_GRAPHICS_FRAGMENT:
+               {
+                       InstanceContext instanceContext = initGraphicsInstanceContext(m_testParameters);
+
+                       addShaderCodeCustomFragment(programCollection, instanceContext, &spirVAsmBuildOptions);
+
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Invalid operation specified");
+       }
+}
+
+TestInstance* SpvAsmSpirvVersionsCase::createInstance (Context& context) const
+{
+       validateVulkanVersion(context.getUsedApiVersion(), m_testParameters.spirvVersion);
+
+       switch (m_testParameters.operation)
+       {
+               case OPERATION_COMPUTE:
+                       return new SpvAsmComputeSpirvVersionsInstance(context, m_testParameters);
+
+               case OPERATION_GRAPHICS_VERTEX:
+               case OPERATION_GRAPHICS_TESSELATION_EVALUATION:
+               case OPERATION_GRAPHICS_TESSELATION_CONTROL:
+               case OPERATION_GRAPHICS_GEOMETRY:
+               case OPERATION_GRAPHICS_FRAGMENT:
+                       return new SpvAsmGraphicsSpirvVersionsInstance(context, m_testParameters);
+
+               default:
+                       TCU_THROW(InternalError, "Invalid operation specified");
+       }
+}
+
+tcu::TestCaseGroup* createSpivVersionCheckTests (tcu::TestContext& testCtx, const bool compute)
+{
+       const char*     operationNames[OPERATION_LAST]  =
+       {
+               "compute",
+               "vertex",
+               "tesselation_evaluation",
+               "tesselation_control",
+               "geometry",
+               "fragment",
+       };
+
+       de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "spirv_version", "Test SPIR-V version is supported"));
+
+       for (SpirvVersion spirvVersion = SPIRV_VERSION_1_0; spirvVersion < SPIRV_VERSION_LAST; ++spirvVersion)
+       {
+               std::string spirvVersionName = getSpirvVersionName(spirvVersion);
+
+               std::replace(spirvVersionName.begin(), spirvVersionName.end(), '.', '_');
+
+               for (Operation operation = OPERATION_COMPUTE; operation < OPERATION_LAST; ++operation)
+               {
+                       if ((compute && operation == OPERATION_COMPUTE) || (!compute && operation != OPERATION_COMPUTE))
+                       {
+                               const std::string               testName                = spirvVersionName + "_" + operationNames[static_cast<deUint32>(operation)];
+                               const TestParameters    testParameters  =
+                               {
+                                       operation,
+                                       spirvVersion
+                               };
+
+                               group->addChild(new SpvAsmSpirvVersionsCase(testCtx, testName.c_str(), "", testParameters));
+                       }
+               }
+       }
+
+       return group.release();
+}
+
+} // SpirVAssembly
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.hpp
new file mode 100644 (file)
index 0000000..86011cf
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _VKTSPVASMSPIRVVERSIONTESTS_HPP
+#define _VKTSPVASMSPIRVVERSIONTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Versions check cases
+ *//*--------------------------------------------------------------------*/
+
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup* createSpivVersionCheckTests(tcu::TestContext& testCtx, const bool compute);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMSPIRVVERSIONTESTS_HPP
index bf6b59f..84208ad 100644 (file)
@@ -213,5 +213,26 @@ Allocator* createAllocator (const InstanceInterface& instanceInterface, const Vk
        return new SimpleAllocator(deviceInterface, device, memoryProperties);
 }
 
+deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
+{
+       switch(version)
+       {
+       case SPIRV_VERSION_1_0:
+               return VK_API_VERSION_1_0;
+       case SPIRV_VERSION_1_1:
+       case SPIRV_VERSION_1_2:
+       case SPIRV_VERSION_1_3:
+               return VK_API_VERSION_1_1;
+       default:
+               DE_ASSERT(0);
+       }
+       return 0u;
+}
+
+std::string    getVulkanName (const deUint32 version)
+{
+       return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
+}
+
 } // SpirVAssembly
 } // vkt
index bd8d2dc..053c14d 100644 (file)
@@ -94,6 +94,10 @@ vk::Allocator* createAllocator (const vk::InstanceInterface& instanceInterface,
                                                                const vk::DeviceInterface& deviceInterface,
                                                                const vk::VkDevice device);
 
+deUint32 getMinRequiredVulkanVersion (const vk::SpirvVersion version);
+
+std::string    getVulkanName (const deUint32 version);
+
 } // SpirVAssembly
 } // vkt
 
index 67829d2..b746422 100644 (file)
@@ -656,7 +656,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);;
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -681,7 +681,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str())<< vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -707,7 +707,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -738,7 +738,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -771,7 +771,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -804,7 +804,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 6960dcb..3616c80 100644 (file)
@@ -342,12 +342,12 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
+                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 
                std::ostringstream frag;
 
@@ -366,7 +366,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -391,7 +391,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -421,7 +421,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -453,7 +453,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -485,7 +485,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 106cad2..2438828 100644 (file)
@@ -509,7 +509,7 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -528,7 +528,7 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -548,12 +548,12 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
+                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 
                std::ostringstream src;
 
@@ -573,7 +573,7 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -600,7 +600,7 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -627,7 +627,7 @@ void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 9c37a47..9906e0c 100644 (file)
@@ -213,7 +213,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -240,7 +240,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -268,7 +268,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -301,7 +301,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -336,7 +336,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -371,7 +371,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 2ec8698..f11c701 100644 (file)
@@ -580,7 +580,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("comp")
-                                       << glu::ComputeSource(src.str());
+                                       << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
                {
@@ -611,7 +611,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                 << "}\n";
 
                        programCollection.glslSources.add("frag")
-                                       << glu::FragmentSource(frag.str());
+                                       << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
                {
@@ -642,7 +642,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("vert")
-                                       << glu::VertexSource(src.str());
+                                       << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
                {
@@ -678,7 +678,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("geom")
-                                       << glu::GeometrySource(src.str());
+                                       << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
                {
@@ -716,7 +716,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("tesc")
-                                       << glu::TessellationControlSource(src.str());
+                                       << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
                {
@@ -754,7 +754,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("tese")
-                                       << glu::TessellationEvaluationSource(src.str());
+                                       << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else
                {
@@ -836,7 +836,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("comp")
-                                       << glu::ComputeSource(src.str());
+                                       << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
                {
@@ -878,7 +878,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                 << "}\n";
 
                        programCollection.glslSources.add("frag")
-                                       << glu::FragmentSource(frag.str());
+                                       << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
                {
@@ -919,7 +919,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("vert")
-                                       << glu::VertexSource(src.str());
+                                       << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
                {
@@ -965,7 +965,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("geom")
-                                       << glu::GeometrySource(src.str());
+                                       << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
                {
@@ -1013,7 +1013,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("tesc")
-                                       << glu::TessellationControlSource(src.str());
+                                       << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
                {
@@ -1061,7 +1061,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                                << "}\n";
 
                        programCollection.glslSources.add("tese")
-                                       << glu::TessellationEvaluationSource(src.str());
+                                       << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
                }
                else
                {
index 50fcdb2..adec91e 100644 (file)
@@ -254,7 +254,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -273,7 +273,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -293,7 +293,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -318,7 +318,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -345,7 +345,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -372,7 +372,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 5b5b86c..1608724 100644 (file)
@@ -454,7 +454,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -472,7 +472,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -491,7 +491,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -515,7 +515,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -541,12 +541,12 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
+                               << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 
                programCollection.glslSources.add("tesc")
                                << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
@@ -567,7 +567,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 0362dfe..72bb5c6 100644 (file)
@@ -530,7 +530,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -555,7 +555,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -581,7 +581,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -612,7 +612,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -645,7 +645,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -678,7 +678,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 3725b8d..9e1bbd0 100644 (file)
@@ -292,7 +292,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -339,7 +339,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -386,7 +386,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -438,7 +438,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -492,7 +492,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -546,7 +546,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 0ab03d1..afbbd99 100644 (file)
@@ -334,7 +334,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -353,7 +353,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -373,7 +373,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -398,7 +398,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -425,7 +425,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -452,7 +452,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index ada18f5..37ab400 100644 (file)
@@ -295,7 +295,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -344,7 +344,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                         << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -394,7 +394,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -449,7 +449,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -506,7 +506,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -563,7 +563,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 23a9496..66a6dea 100644 (file)
@@ -821,9 +821,7 @@ std::string vkt::subgroups::getVertShaderForStage(vk::VkShaderStageFlags stage)
 
 bool vkt::subgroups::isSubgroupSupported(Context& context)
 {
-       VkPhysicalDeviceProperties properties;
-       context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), &properties);
-       return (properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) ? false : true;
+       return context.getUsedApiVersion() < VK_API_VERSION_1_1 ? false : true;
 }
 
 bool vkt::subgroups::areSubgroupOperationsSupportedForStage(
index 87fa6a9..f0f5732 100644 (file)
@@ -355,7 +355,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                src << "}\n";
 
                programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str());
+                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
        {
@@ -404,7 +404,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                frag << "}\n";
 
                programCollection.glslSources.add("frag")
-                               << glu::FragmentSource(frag.str());
+                               << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
        {
@@ -454,7 +454,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                src << "}\n";
 
                programCollection.glslSources.add("vert")
-                               << glu::VertexSource(src.str());
+                               << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
        {
@@ -509,7 +509,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                src << "}\n";
 
                programCollection.glslSources.add("geom")
-                               << glu::GeometrySource(src.str());
+                               << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
        {
@@ -566,7 +566,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                src << "}\n";
 
                programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(src.str());
+                               << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
        {
@@ -623,7 +623,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                src << "}\n";
 
                programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(src.str());
+                               << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
        }
        else
        {
index 58fcabc..7b947cd 100644 (file)
@@ -3429,15 +3429,15 @@ OperationContext::OperationContext (Context& context, PipelineCacheData& pipelin
 {
 }
 
-OperationContext::OperationContext (const deUint32                                                             apiVersion,
-                                                                       const vk::InstanceInterface&                            vki,
-                                                                       const vk::DeviceInterface&                                      vkd,
-                                                                       vk::VkPhysicalDevice                                            physicalDevice,
-                                                                       vk::VkDevice                                                            device,
-                                                                       vk::Allocator&                                                          allocator,
-                                                                       const std::vector<std::string>&                         deviceExtensions,
-                                                                       vk::ProgramCollection<vk::ProgramBinary>&       programCollection,
-                                                                       PipelineCacheData&                                                      pipelineCacheData)
+OperationContext::OperationContext (const deUint32                                     apiVersion,
+                                                                       const vk::InstanceInterface&    vki,
+                                                                       const vk::DeviceInterface&              vkd,
+                                                                       vk::VkPhysicalDevice                    physicalDevice,
+                                                                       vk::VkDevice                                    device,
+                                                                       vk::Allocator&                                  allocator,
+                                                                       const std::vector<std::string>& deviceExtensions,
+                                                                       vk::BinaryCollection&                   programCollection,
+                                                                       PipelineCacheData&                              pipelineCacheData)
        : m_vki                                 (vki)
        , m_vk                                  (vkd)
        , m_physicalDevice              (physicalDevice)
index b6426b1..4cde4f1 100644 (file)
@@ -110,49 +110,50 @@ enum OperationName
 class OperationContext
 {
 public:
-                                                                                               OperationContext                (Context&                       context,
-                                                                                                                                                PipelineCacheData&     pipelineCacheData);
+                                                                       OperationContext                (Context&                       context,
+                                                                                                                        PipelineCacheData&     pipelineCacheData);
 
-                                                                                               OperationContext                (Context&                                       context,
-                                                                                                                                                PipelineCacheData&                     pipelineCacheData,
-                                                                                                                                                const vk::DeviceInterface&     vk,
-                                                                                                                                                const vk::VkDevice                     device,
-                                                                                                                                                vk::Allocator&                         allocator);
+                                                                       OperationContext                (Context&                                       context,
+                                                                                                                        PipelineCacheData&                     pipelineCacheData,
+                                                                                                                        const vk::DeviceInterface&     vk,
+                                                                                                                        const vk::VkDevice                     device,
+                                                                                                                        vk::Allocator&                         allocator);
 
-                                                                                               OperationContext                (const deUint32                                                         apiVersion,
-                                                                                                                                                const vk::InstanceInterface&                           vki,
-                                                                                                                                                const vk::DeviceInterface&                                     vkd,
-                                                                                                                                                vk::VkPhysicalDevice                                           physicalDevice,
-                                                                                                                                                vk::VkDevice                                                           device,
-                                                                                                                                                vk::Allocator&                                                         allocator,
-                                                                                                                                                const std::vector<std::string>&                        deviceExtensions,
-                                                                                                                                                vk::ProgramCollection<vk::ProgramBinary>&      programCollection,
-                                                                                                                                                PipelineCacheData&                                                     pipelineCacheData);
+                                                                       OperationContext                (const deUint32                                         apiVersion,
+                                                                                                                        const vk::InstanceInterface&           vki,
+                                                                                                                        const vk::DeviceInterface&                     vkd,
+                                                                                                                        vk::VkPhysicalDevice                           physicalDevice,
+                                                                                                                        vk::VkDevice                                           device,
+                                                                                                                        vk::Allocator&                                         allocator,
+                                                                                                                        const std::vector<std::string>&        deviceExtensions,
+                                                                                                                        vk::BinaryCollection&                          programCollection,
+                                                                                                                        PipelineCacheData&                                     pipelineCacheData);
+
+       const vk::InstanceInterface&    getInstanceInterface    (void) const { return m_vki; }
+       const vk::DeviceInterface&              getDeviceInterface              (void) const { return m_vk; }
+       vk::VkPhysicalDevice                    getPhysicalDevice               (void) const { return m_physicalDevice; }
+       vk::VkDevice                                    getDevice                               (void) const { return m_device; }
+       vk::Allocator&                                  getAllocator                    (void) const { return m_allocator; }
+       vk::BinaryCollection&                   getBinaryCollection             (void) const { return m_progCollection; }
+       PipelineCacheData&                              getPipelineCacheData    (void) const { return m_pipelineCacheData; }
+       const std::vector<std::string>& getDeviceExtensions             (void) const { return m_deviceExtensions;}
+       deUint32                                                getUsedApiVersion               (void) const { return m_usedApiVersion; }
 
-       const vk::InstanceInterface&                            getInstanceInterface    (void) const { return m_vki; }
-       const vk::DeviceInterface&                                      getDeviceInterface              (void) const { return m_vk; }
-       vk::VkPhysicalDevice                                            getPhysicalDevice               (void) const { return m_physicalDevice; }
-       vk::VkDevice                                                            getDevice                               (void) const { return m_device; }
-       vk::Allocator&                                                          getAllocator                    (void) const { return m_allocator; }
-       vk::ProgramCollection<vk::ProgramBinary>&       getBinaryCollection             (void) const { return m_progCollection; }
-       PipelineCacheData&                                                      getPipelineCacheData    (void) const { return m_pipelineCacheData; }
-       const std::vector<std::string>&                         getDeviceExtensions             (void) const { return m_deviceExtensions;}
-       deUint32                                                                        getUsedApiVersion               (void) const { return m_usedApiVersion; }
 
 private:
-       const vk::InstanceInterface&                            m_vki;
-       const vk::DeviceInterface&                                      m_vk;
-       const vk::VkPhysicalDevice                                      m_physicalDevice;
-       const vk::VkDevice                                                      m_device;
-       vk::Allocator&                                                          m_allocator;
-       vk::ProgramCollection<vk::ProgramBinary>&       m_progCollection;
-       PipelineCacheData&                                                      m_pipelineCacheData;
-       const std::vector<std::string>&                         m_deviceExtensions;
-       const deUint32                                                          m_usedApiVersion;
+       const vk::InstanceInterface&    m_vki;
+       const vk::DeviceInterface&              m_vk;
+       const vk::VkPhysicalDevice              m_physicalDevice;
+       const vk::VkDevice                              m_device;
+       vk::Allocator&                                  m_allocator;
+       vk::BinaryCollection&                   m_progCollection;
+       PipelineCacheData&                              m_pipelineCacheData;
+       const std::vector<std::string>& m_deviceExtensions;
+       const deUint32                                  m_usedApiVersion;
 
        // Disabled
-                                                                                               OperationContext                (const OperationContext&);
-       OperationContext&                                                       operator=                               (const OperationContext&);
+                                                                       OperationContext                (const OperationContext&);
+       OperationContext&                               operator=                               (const OperationContext&);
 };
 
 // Common interface to images and buffers used by operations.
index 4eda4a6..50bc1c6 100644 (file)
@@ -201,15 +201,19 @@ struct Program
        Status                                  validationStatus;
        std::string                             validationLog;
 
-       explicit                                Program         (const vk::ProgramIdentifier& id_)
+       vk::SpirvVersion                spirvVersion;
+
+       explicit                                Program         (const vk::ProgramIdentifier& id_, const vk::SpirvVersion spirvVersion_)
                                                                : id                            (id_)
                                                                , buildStatus           (STATUS_NOT_COMPLETED)
                                                                , validationStatus      (STATUS_NOT_COMPLETED)
+                                                               , spirvVersion          (spirvVersion_)
                                                        {}
                                                        Program         (void)
                                                                : id                            ("", "")
                                                                , buildStatus           (STATUS_NOT_COMPLETED)
                                                                , validationStatus      (STATUS_NOT_COMPLETED)
+                                                               , spirvVersion          (vk::SPIRV_VERSION_LAST)
                                                        {}
 };
 
@@ -253,6 +257,8 @@ public:
 
                try
                {
+                       DE_ASSERT(m_source.buildOptions.targetVersion < vk::SPIRV_VERSION_LAST);
+
                        m_program->binary               = ProgramBinarySp(vk::buildProgram(m_source, &buildInfo));
                        m_program->buildStatus  = Program::STATUS_PASSED;
                }
@@ -264,7 +270,6 @@ public:
 
                        m_program->buildStatus  = Program::STATUS_FAILED;
                        m_program->buildLog             = log.str();
-
                }
        }
 
@@ -297,6 +302,8 @@ public:
 
                try
                {
+                       DE_ASSERT(m_source.buildOptions.targetVersion < vk::SPIRV_VERSION_LAST);
+
                        m_program->binary               = ProgramBinarySp(vk::assembleProgram(m_source, &buildInfo));
                        m_program->buildStatus  = Program::STATUS_PASSED;
                }
@@ -326,10 +333,13 @@ public:
        void execute (void)
        {
                DE_ASSERT(m_program->buildStatus == Program::STATUS_PASSED);
+               DE_ASSERT(m_program->binary->getFormat() == vk::PROGRAM_FORMAT_SPIRV);
 
-               std::ostringstream validationLog;
+               std::ostringstream                      validationLog;
+               const vk::ProgramBinary&        programBinary   = *(m_program->binary);
+               const vk::SpirvVersion          spirvVersion    = vk::extractSpirvVersion(programBinary);
 
-               if (vk::validateProgram(*m_program->binary, &validationLog))
+               if (vk::validateProgram(*m_program->binary, &validationLog, spirvVersion))
                        m_program->validationStatus = Program::STATUS_PASSED;
                else
                        m_program->validationStatus = Program::STATUS_FAILED;
@@ -352,15 +362,22 @@ struct BuildStats
 {
        int             numSucceeded;
        int             numFailed;
+       int             notSupported;
 
        BuildStats (void)
                : numSucceeded  (0)
                , numFailed             (0)
+               , notSupported  (0)
        {
        }
 };
 
-BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath, bool validateBinaries)
+BuildStats buildPrograms (tcu::TestContext&                    testCtx,
+                                                 const std::string&            dstPath,
+                                                 const bool                            validateBinaries,
+                                                 const deUint32                        usedVulkanVersion,
+                                                 const vk::SpirvVersion        spirvVersionForGlsl,
+                                                 const vk::SpirvVersion        spirvVersionForAsm)
 {
        const deUint32                                          numThreads                      = deGetNumAvailableLogicalCores();
 
@@ -369,6 +386,7 @@ BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath,
        // de::PoolArray<> is faster to build than std::vector
        de::MemPool                                                     programPool;
        de::PoolArray<Program>                          programs                        (&programPool);
+       int                                                                     notSupported            = 0;
 
        {
                de::MemPool                                                     tmpPool;
@@ -387,17 +405,33 @@ BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath,
                                if (iterator.getState() == tcu::TestHierarchyIterator::STATE_ENTER_NODE &&
                                        tcu::isTestNodeTypeExecutable(iterator.getNode()->getNodeType()))
                                {
-                                       const TestCase* const           testCase        = dynamic_cast<TestCase*>(iterator.getNode());
-                                       const string                            casePath        = iterator.getNodePath();
-                                       vk::SourceCollections           sourcePrograms;
-
-                                       testCase->initPrograms(sourcePrograms);
+                                       const TestCase* const           testCase                                        = dynamic_cast<TestCase*>(iterator.getNode());
+                                       const string                            casePath                                        = iterator.getNodePath();
+                                       vk::ShaderBuildOptions          defaultGlslBuildOptions         (spirvVersionForGlsl, 0u);
+                                       vk::ShaderBuildOptions          defaultHlslBuildOptions         (spirvVersionForGlsl, 0u);
+                                       vk::SpirVAsmBuildOptions        defaultSpirvAsmBuildOptions     (spirvVersionForAsm);
+                                       vk::SourceCollections           sourcePrograms                          (usedVulkanVersion, defaultGlslBuildOptions, defaultGlslBuildOptions, defaultSpirvAsmBuildOptions);
+
+                                       try
+                                       {
+                                               testCase->initPrograms(sourcePrograms);
+                                       }
+                                       catch (const tcu::NotSupportedError& )
+                                       {
+                                               notSupported++;
+                                               iterator.next();
+                                               continue;
+                                       }
 
                                        for (vk::GlslSourceCollection::Iterator progIter = sourcePrograms.glslSources.begin();
                                                 progIter != sourcePrograms.glslSources.end();
                                                 ++progIter)
                                        {
-                                               programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName())));
+                                               // Source program requires higher SPIR-V version than available: skip it to avoid fail
+                                               if (progIter.getProgram().buildOptions.targetVersion > spirvVersionForGlsl)
+                                                       continue;
+
+                                               programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.targetVersion));
                                                buildGlslTasks.pushBack(BuildGlslTask(progIter.getProgram(), &programs.back()));
                                                executor.submit(&buildGlslTasks.back());
                                        }
@@ -406,7 +440,11 @@ BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath,
                                                 progIter != sourcePrograms.spirvAsmSources.end();
                                                 ++progIter)
                                        {
-                                               programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName())));
+                                               // Source program requires higher SPIR-V version than available: skip it to avoid fail
+                                               if (progIter.getProgram().buildOptions.targetVersion > spirvVersionForAsm)
+                                                       continue;
+
+                                               programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.targetVersion));
                                                buildSpirvAsmTasks.pushBack(BuildSpirVAsmTask(progIter.getProgram(), &programs.back()));
                                                executor.submit(&buildSpirvAsmTasks.back());
                                        }
@@ -452,7 +490,7 @@ BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath,
 
        {
                BuildStats      stats;
-
+               stats.notSupported = notSupported;
                for (de::PoolArray<Program>::iterator progIter = programs.begin(); progIter != programs.end(); ++progIter)
                {
                        const bool      buildOk                 = progIter->buildStatus == Program::STATUS_PASSED;
@@ -480,21 +518,32 @@ BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath,
 namespace opt
 {
 
-DE_DECLARE_COMMAND_LINE_OPT(DstPath,   std::string);
-DE_DECLARE_COMMAND_LINE_OPT(Cases,             std::string);
-DE_DECLARE_COMMAND_LINE_OPT(Validate,  bool);
-
-} // opt
+DE_DECLARE_COMMAND_LINE_OPT(DstPath,           std::string);
+DE_DECLARE_COMMAND_LINE_OPT(Cases,                     std::string);
+DE_DECLARE_COMMAND_LINE_OPT(Validate,          bool);
+DE_DECLARE_COMMAND_LINE_OPT(VulkanVersion,     deUint32);
 
 void registerOptions (de::cmdline::Parser& parser)
 {
        using de::cmdline::Option;
+       using de::cmdline::NamedValue;
+
+       static const NamedValue<deUint32> s_vulkanVersion[] =
+       {
+               { "1.0",        VK_MAKE_VERSION(1, 0, 0)        },
+               { "1.1",        VK_MAKE_VERSION(1, 1, 0)        },
+       };
 
-       parser << Option<opt::DstPath>  ("d", "dst-path",               "Destination path",     "out")
-                  << Option<opt::Cases>        ("n", "deqp-case",              "Case path filter (works as in test binaries)")
-                  << Option<opt::Validate>     ("v", "validate-spv",   "Validate generated SPIR-V binaries");
+       DE_STATIC_ASSERT(vk::SPIRV_VERSION_1_3 + 1 == vk::SPIRV_VERSION_LAST);
+
+       parser << Option<opt::DstPath>                          ("d", "dst-path",                               "Destination path",     "out")
+                  << Option<opt::Cases>                                ("n", "deqp-case",                              "Case path filter (works as in test binaries)")
+                  << Option<opt::Validate>                             ("v", "validate-spv",                   "Validate generated SPIR-V binaries")
+                  << Option<opt::VulkanVersion>                ("t", "target-vulkan-version",  "Target Vulkan version", s_vulkanVersion, "1.1");
 }
 
+} // opt
+
 int main (int argc, const char* argv[])
 {
        de::cmdline::CommandLine        cmdLine;
@@ -502,7 +551,7 @@ int main (int argc, const char* argv[])
 
        {
                de::cmdline::Parser             parser;
-               registerOptions(parser);
+               opt::registerOptions(parser);
                if (!parser.parse(argc, argv, &cmdLine, std::cerr))
                {
                        parser.help(std::cout);
@@ -527,16 +576,25 @@ int main (int argc, const char* argv[])
 
        try
        {
-               tcu::DirArchive                 archive                 (".");
-               tcu::TestLog                    log                             (deqpCmdLine.getLogFileName(), deqpCmdLine.getLogFlags());
+               tcu::DirArchive                 archive                         (".");
+               tcu::TestLog                    log                                     (deqpCmdLine.getLogFileName(), deqpCmdLine.getLogFlags());
                tcu::Platform                   platform;
-               tcu::TestContext                testCtx                 (platform, archive, log, deqpCmdLine, DE_NULL);
-
-               const vkt::BuildStats   stats                   = vkt::buildPrograms(testCtx,
-                                                                                                                                        cmdLine.getOption<opt::DstPath>(),
-                                                                                                                                        cmdLine.getOption<opt::Validate>());
-
-               tcu::print("DONE: %d passed, %d failed\n", stats.numSucceeded, stats.numFailed);
+               tcu::TestContext                testCtx                         (platform, archive, log, deqpCmdLine, DE_NULL);
+               vk::SpirvVersion                spirvVersionForGlsl     = vk::getSpirvVersionForGlsl(cmdLine.getOption<opt::VulkanVersion>());
+               vk::SpirvVersion                spirvVersionForAsm      = vk::getSpirvVersionForAsm(cmdLine.getOption<opt::VulkanVersion>());
+
+               tcu::print("SPIR-V versions: for GLSL sources: %s, for SPIR-V asm sources: %s\n",
+                                       getSpirvVersionName(spirvVersionForGlsl).c_str(),
+                                       getSpirvVersionName(spirvVersionForAsm).c_str());
+
+               const vkt::BuildStats   stats           = vkt::buildPrograms(testCtx,
+                                                                                                                                cmdLine.getOption<opt::DstPath>(),
+                                                                                                                                cmdLine.getOption<opt::Validate>(),
+                                                                                                                                cmdLine.getOption<opt::VulkanVersion>(),
+                                                                                                                                spirvVersionForGlsl,
+                                                                                                                                spirvVersionForAsm);
+
+               tcu::print("DONE: %d passed, %d failed, %d not supported\n", stats.numSucceeded, stats.numFailed, stats.notSupported);
 
                return stats.numFailed == 0 ? 0 : -1;
        }
index d6866fa..ed71e93 100644 (file)
@@ -406,9 +406,9 @@ vk::Allocator* createAllocator (DefaultDevice* device)
 
 // Context
 
-Context::Context (tcu::TestContext&                                                    testCtx,
-                                 const vk::PlatformInterface&                          platformInterface,
-                                 vk::ProgramCollection<vk::ProgramBinary>&     progCollection)
+Context::Context (tcu::TestContext&                            testCtx,
+                                 const vk::PlatformInterface&  platformInterface,
+                                 vk::BinaryCollection&                 progCollection)
        : m_testCtx                             (testCtx)
        , m_platformInterface   (platformInterface)
        , m_progCollection              (progCollection)
index b2138d0..a7e1507 100644 (file)
@@ -27,6 +27,7 @@
 #include "tcuTestCase.hpp"
 #include "vkDefs.hpp"
 #include "deUniquePtr.hpp"
+#include "vkPrograms.hpp"
 
 namespace glu
 {
@@ -36,8 +37,6 @@ struct ProgramSources;
 namespace vk
 {
 class PlatformInterface;
-class ProgramBinary;
-template<typename Program> class ProgramCollection;
 class Allocator;
 struct SourceCollections;
 }
@@ -50,14 +49,14 @@ class DefaultDevice;
 class Context
 {
 public:
-                                                                                               Context                                                 (tcu::TestContext&                                                      testCtx,
-                                                                                                                                                                const vk::PlatformInterface&                           platformInterface,
-                                                                                                                                                                vk::ProgramCollection<vk::ProgramBinary>&      progCollection);
+                                                                                               Context                                                 (tcu::TestContext&                              testCtx,
+                                                                                                                                                                const vk::PlatformInterface&   platformInterface,
+                                                                                                                                                                vk::BinaryCollection&                  progCollection);
                                                                                                ~Context                                                (void);
 
        tcu::TestContext&                                                       getTestContext                                  (void) const { return m_testCtx;                        }
        const vk::PlatformInterface&                            getPlatformInterface                    (void) const { return m_platformInterface;      }
-       vk::ProgramCollection<vk::ProgramBinary>&       getBinaryCollection                             (void) const { return m_progCollection;         }
+       vk::BinaryCollection&                                           getBinaryCollection                             (void) const { return m_progCollection;         }
 
        // Default instance & device, selected with --deqp-vk-device-id=N
        deUint32                                                                        getInstanceVersion                              (void) const;
@@ -81,7 +80,7 @@ public:
 protected:
        tcu::TestContext&                                                       m_testCtx;
        const vk::PlatformInterface&                            m_platformInterface;
-       vk::ProgramCollection<vk::ProgramBinary>&       m_progCollection;
+       vk::BinaryCollection&                                           m_progCollection;
 
        const de::UniquePtr<DefaultDevice>                      m_device;
        const de::UniquePtr<vk::Allocator>                      m_allocator;
index 427b674..a57d5a0 100644 (file)
@@ -34,6 +34,7 @@
 #include "vkShaderToSpirV.hpp"
 #include "vkDebugReportUtil.hpp"
 #include "vkQueryUtil.hpp"
+#include "vkApiVersion.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -221,9 +222,15 @@ TestCaseExecutor::~TestCaseExecutor (void)
 
 void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePath)
 {
-       const TestCase*                 vktCase         = dynamic_cast<TestCase*>(testCase);
-       tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
-       vk::SourceCollections   sourceProgs;
+       const TestCase*                         vktCase                                         = dynamic_cast<TestCase*>(testCase);
+       tcu::TestLog&                           log                                                     = m_context.getTestContext().getLog();
+       const deUint32                          usedVulkanVersion                       = m_context.getUsedApiVersion();
+       const vk::SpirvVersion          spirvVersionForGlsl                     = vk::getSpirvVersionForGlsl(usedVulkanVersion);
+       const vk::SpirvVersion          spirvVersionForAsm                      = vk::getSpirvVersionForAsm(usedVulkanVersion);
+       vk::ShaderBuildOptions          defaultGlslBuildOptions         (spirvVersionForGlsl, 0u);
+       vk::ShaderBuildOptions          defaultHlslBuildOptions         (spirvVersionForGlsl, 0u);
+       vk::SpirVAsmBuildOptions        defaultSpirvAsmBuildOptions     (spirvVersionForAsm);
+       vk::SourceCollections           sourceProgs                                     (usedVulkanVersion, defaultGlslBuildOptions, defaultHlslBuildOptions, defaultSpirvAsmBuildOptions);
 
        DE_UNREF(casePath); // \todo [2015-03-13 pyry] Use this to identify ProgramCollection storage path
 
@@ -235,13 +242,16 @@ 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::getSpirvVersionForGlsl(m_context.getUsedApiVersion()))
+                       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);
 
                try
                {
                        std::ostringstream disasm;
 
-                       vk::disassembleProgram(*binProg, &disasm);
+                       vk::disassembleProgram(*binProg, &disasm, spirvVersionForGlsl);
 
                        log << vk::SpirVAsmSource(disasm.str());
                }
@@ -253,13 +263,16 @@ 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::getSpirvVersionForGlsl(m_context.getUsedApiVersion()))
+                       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);
 
                try
                {
                        std::ostringstream disasm;
 
-                       vk::disassembleProgram(*binProg, &disasm);
+                       vk::disassembleProgram(*binProg, &disasm, spirvVersionForGlsl);
 
                        log << vk::SpirVAsmSource(disasm.str());
                }
@@ -271,6 +284,9 @@ 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::getSpirvVersionForAsm(m_context.getUsedApiVersion()))
+                       TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
+
                buildProgram<vk::SpirVProgramInfo, vk::SpirVAsmCollection::Iterator>(casePath, asmIterator, m_prebuiltBinRegistry, log, &m_progCollection);
        }
 
index 02d24fc..d65642b 100755 (executable)
@@ -168664,6 +168664,10 @@ dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.multiple_arbitrary_descriptors.offset_view_nonzero
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.descriptor_array.offset_view_zero
 dEQP-VK.binding_model.shader_access.secondary_cmd_buf.with_push_template.storage_buffer.vertex_fragment.descriptor_array.offset_view_nonzero
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_0_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_1_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_2_compute
+dEQP-VK.spirv_assembly.instruction.compute.spirv_version.1_3_compute
 dEQP-VK.spirv_assembly.instruction.compute.opnop.all
 dEQP-VK.spirv_assembly.instruction.compute.opatomic.iadd
 dEQP-VK.spirv_assembly.instruction.compute.opatomic.isub
@@ -168680,6 +168684,7 @@ dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.load
 dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.store
 dEQP-VK.spirv_assembly.instruction.compute.opatomic_storage_buffer.compex
 dEQP-VK.spirv_assembly.instruction.compute.opline.all
+dEQP-VK.spirv_assembly.instruction.compute.opmoduleprocessed.all
 dEQP-VK.spirv_assembly.instruction.compute.opnoline.all
 dEQP-VK.spirv_assembly.instruction.compute.opconstantnull.bool
 dEQP-VK.spirv_assembly.instruction.compute.opconstantnull.sint32
@@ -168757,6 +168762,8 @@ dEQP-VK.spirv_assembly.instruction.compute.loop_control.none
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.dont_unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll_dont_unroll
+dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_length
+dEQP-VK.spirv_assembly.instruction.compute.loop_control.dependency_infinite
 dEQP-VK.spirv_assembly.instruction.compute.function_control.none
 dEQP-VK.spirv_assembly.instruction.compute.function_control.inline
 dEQP-VK.spirv_assembly.instruction.compute.function_control.dont_inline
@@ -169209,6 +169216,26 @@ dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.complex_types_compu
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.complex_types_compute.opptraccesschain_float_single_buffer_first_input
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.nullptr_compute.opvariable_initialized_null
 dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.nullptr_compute.opselect_null_or_valid_ptr
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_0_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_1_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_2_fragment
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_vertex
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_tesselation_evaluation
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_tesselation_control
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_geometry
+dEQP-VK.spirv_assembly.instruction.graphics.spirv_version.1_3_fragment
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tesse
@@ -169279,6 +169306,11 @@ dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_tesse
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_geom
 dEQP-VK.spirv_assembly.instruction.graphics.opsourcecontinued.long_frag
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_vert
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_geom
+dEQP-VK.spirv_assembly.instruction.graphics.opmoduleprocessed.opmoduleprocessed_frag
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opline.opline_empty_name_tesse
index 8f0b0e5..d50219d 100644 (file)
@@ -44,6 +44,7 @@ VULKAN_MODULE         = Module("dEQP-VK", "../external/vulkancts/modules/vulkan", "deqp
 DEFAULT_BUILD_DIR      = os.path.join(tempfile.gettempdir(), "spirv-binaries", "{targetName}-{buildType}")
 DEFAULT_TARGET         = "null"
 DEFAULT_DST_DIR                = os.path.join(DEQP_DIR, "external", "vulkancts", "data", "vulkan", "prebuilt")
+DEFAULT_VULKAN_VERSION = "1.1"
 
 def getBuildConfig (buildPathPtrn, targetName, buildType):
        buildPath = buildPathPtrn.format(
@@ -59,7 +60,7 @@ def cleanDstDir (dstPath):
                print "Removing %s" % os.path.join(dstPath, binFile)
                os.remove(os.path.join(dstPath, binFile))
 
-def execBuildPrograms (buildCfg, generator, module, dstPath):
+def execBuildPrograms (buildCfg, generator, module, dstPath, vulkanVersion):
        fullDstPath     = os.path.realpath(dstPath)
        workDir         = os.path.join(buildCfg.getBuildDir(), "modules", module.dirName)
 
@@ -67,7 +68,7 @@ def execBuildPrograms (buildCfg, generator, module, dstPath):
 
        try:
                binPath = generator.getBinaryPath(buildCfg.getBuildType(), os.path.join(".", "vk-build-programs"))
-               execute([binPath, "--validate-spv", "--dst-path", fullDstPath])
+               execute([binPath, "--validate-spv", "--dst-path", fullDstPath, "--target-vulkan-version", vulkanVersion])
        finally:
                popWorkingDir()
 
@@ -94,6 +95,11 @@ def parseArgs ():
                                                dest="dstPath",
                                                default=DEFAULT_DST_DIR,
                                                help="Destination path")
+       parser.add_argument("-u",
+                                               "--target-vulkan-version",
+                                               dest="vulkanVersion",
+                                               default=DEFAULT_VULKAN_VERSION,
+                                               help="Target Vulkan version")
        return parser.parse_args()
 
 if __name__ == "__main__":
@@ -108,4 +114,4 @@ if __name__ == "__main__":
        if not os.path.exists(args.dstPath):
                os.makedirs(args.dstPath)
 
-       execBuildPrograms(buildCfg, generator, module, args.dstPath)
+       execBuildPrograms(buildCfg, generator, module, args.dstPath, args.vulkanVersion)