SpirV tests for Vulkan 1.1

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)
diff --git a/AndroidGen.mk b/AndroidGen.mk
index 41b32f6..16d946a 100644
--- a/AndroidGen.mk
+++ b/AndroidGen.mk
@@ -233,6 +233,9 @@
 	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 \
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index 20f7b0a..ff5160b 100755
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
@@ -168659,6 +168659,10 @@
 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.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.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_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_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
diff --git a/external/vulkancts/framework/vulkan/vkDefs.hpp b/external/vulkancts/framework/vulkan/vkDefs.hpp
index 20350a9..41b2b19 100644
--- a/external/vulkancts/framework/vulkan/vkDefs.hpp
+++ b/external/vulkancts/framework/vulkan/vkDefs.hpp
@@ -98,10 +98,21 @@
 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
 {
 
diff --git a/external/vulkancts/framework/vulkan/vkPrograms.cpp b/external/vulkancts/framework/vulkan/vkPrograms.cpp
index 585c96f..5ddd17f 100644
--- a/external/vulkancts/framework/vulkan/vkPrograms.cpp
+++ b/external/vulkancts/framework/vulkan/vkPrograms.cpp
@@ -99,11 +99,11 @@
 
 } // 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 @@
 
 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 @@
 	}
 
 	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 @@
 	}
 
 	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 @@
 	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 @@
 		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 @@
 		}
 
 		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 @@
 	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
diff --git a/external/vulkancts/framework/vulkan/vkPrograms.hpp b/external/vulkancts/framework/vulkan/vkPrograms.hpp
index 0e39fa3..f89fd34 100644
--- a/external/vulkancts/framework/vulkan/vkPrograms.hpp
+++ b/external/vulkancts/framework/vulkan/vkPrograms.hpp
@@ -58,16 +58,22 @@
 	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 @@
 	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>
-ProgramCollection<Program>::~ProgramCollection (void)
+template<typename Program, typename BuildOptions>
+ProgramCollection<Program, BuildOptions>::ProgramCollection (const BuildOptions defaultBuildOptions)
+	: m_programs()
+	, m_defaultBuildOptions(defaultBuildOptions)
+{
+}
+
+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
diff --git a/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp b/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
index 1f243b4..e1ebdd1 100644
--- a/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
+++ b/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
@@ -246,7 +246,7 @@
 	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 @@
 			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)
diff --git a/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp b/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
index 18cddfe..fadf1c5 100644
--- a/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
+++ b/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
@@ -39,11 +39,25 @@
 
 #if defined(DEQP_HAVE_SPIRV_TOOLS)
 
-static const spv_target_env s_defaultEnvironment = SPV_ENV_VULKAN_1_1;
-
-bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo)
+static spv_target_env mapTargetSpvEnvironment(SpirvVersion spirvVersion)
 {
-	const spv_context	context		= spvContextCreate(s_defaultEnvironment);
+	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, SpirvVersion spirvVersion)
+{
+	const spv_context	context		= spvContextCreate(mapTargetSpvEnvironment(spirvVersion));
 	spv_binary			binary		= DE_NULL;
 	spv_diagnostic		diagnostic	= DE_NULL;
 
@@ -84,9 +98,9 @@
 	}
 }
 
-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 @@
 	}
 }
 
-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 @@
 
 #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)");
 }
diff --git a/external/vulkancts/framework/vulkan/vkSpirVAsm.hpp b/external/vulkancts/framework/vulkan/vkSpirVAsm.hpp
index 612c13a..822f1a5 100644
--- a/external/vulkancts/framework/vulkan/vkSpirVAsm.hpp
+++ b/external/vulkancts/framework/vulkan/vkSpirVAsm.hpp
@@ -32,13 +32,13 @@
 {
 
 //! 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
 
diff --git a/external/vulkancts/framework/vulkan/vkSpirVProgram.hpp b/external/vulkancts/framework/vulkan/vkSpirVProgram.hpp
index 5c5244a..94c44a3 100644
--- a/external/vulkancts/framework/vulkan/vkSpirVProgram.hpp
+++ b/external/vulkancts/framework/vulkan/vkSpirVProgram.hpp
@@ -36,6 +36,19 @@
 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 @@
 	{
 	}
 
-	std::string		source;
+	SpirVAsmSource& operator<< (const SpirVAsmBuildOptions& buildOptions_)
+	{
+		buildOptions = buildOptions_;
+		return *this;
+	};
+
+	SpirVAsmBuildOptions	buildOptions;
+	std::string				source;
 };
 
 struct SpirVProgramInfo
diff --git a/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp b/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp
index 7069ef4..9fb9f35 100644
--- a/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp
+++ b/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp
@@ -985,14 +985,14 @@
 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 @@
 	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 @@
 	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 @@
 
 	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 @@
 	{
 	}
 
-	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(); }
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp
index 3518fc4..c4e4c5e 100644
--- a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp
@@ -60,7 +60,7 @@
 	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:
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp
index 3751afb..acedf15 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp
@@ -561,14 +561,14 @@
 	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));
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
index 1256fe7..23ba014 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
@@ -709,15 +709,15 @@
 	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 @@
 	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 @@
 	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);
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
index a0293d1..58e20e0 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
@@ -522,20 +522,20 @@
 		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)
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt b/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
index 00e9cc3..26d9e62 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
@@ -25,6 +25,12 @@
 	vktSpvAsmUtils.hpp
 	vktSpvAsmVariablePointersTests.cpp
 	vktSpvAsmVariablePointersTests.hpp
+	vktSpvAsmSpirvVersionTests.cpp
+	vktSpvAsmSpirvVersionTests.hpp
+	vktSpvAsmLoopDepLenTests.cpp
+	vktSpvAsmLoopDepLenTests.hpp
+	vktSpvAsmLoopDepInfTests.cpp
+	vktSpvAsmLoopDepInfTests.hpp
 	)
 
 set(DEQP_VK_SPIRV_ASSEMBLY_LIBS
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
index 090eadd..adcf0d4 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
@@ -267,28 +267,6 @@
 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 @@
 
 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 @@
 	// 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));
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.hpp
index 50c69e9..a29c843 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.hpp
@@ -41,6 +41,28 @@
 	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:
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
index eec9c4a..2e871ef 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
@@ -204,6 +204,8 @@
 									 const std::vector<BufferSp>&		expectedOutputs,
 									 tcu::TestLog&						log);
 
+typedef bool (*ComputeVerifyBinaryFunc) (const ProgramBinary&	binary);
+
 /*--------------------------------------------------------------------*//*!
  * \brief Specification for a compute shader.
  *
@@ -230,6 +232,8 @@
 	// 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 @@
 												, failResult					(QP_TEST_RESULT_FAIL)
 												, failMessage					("Output doesn't match with expected")
 												, verifyIO						(DE_NULL)
+												, verifyBinary					(DE_NULL)
+												, spirvVersion					(SPIRV_VERSION_1_0)
 											{}
 };
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
index 3213532..96c1405 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
@@ -474,6 +474,7 @@
 		"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 @@
 		"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 @@
 		"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 @@
 		"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 @@
 		"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 @@
 
 // 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 @@
 
 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 @@
 	// 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.
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
index b1b93c0..2951a58 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
@@ -75,25 +75,31 @@
 									  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 @@
 }
 
 
+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],
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
index 21824f5..fb852d8 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
@@ -57,7 +57,10 @@
 #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 @@
 	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 @@
 		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 @@
 
 	return opSourceTests.release();
 }
-
 tcu::TestCaseGroup* createOpNoLineTests(tcu::TestContext& testCtx)
 {
 	RGBA								 defaultColors[4];
@@ -4582,6 +4684,44 @@
 	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* 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 @@
 	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
index 0000000..c2c6e2e
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.cpp
@@ -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
index 0000000..f572fc6
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepInfTests.hpp
@@ -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
index 0000000..935dbc2
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.cpp
@@ -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
index 0000000..25c55a9
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmLoopDepLenTests.hpp
@@ -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
index 0000000..98ded32
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp
@@ -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
index 0000000..86011cf
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.hpp
@@ -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
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
index bf6b59f..84208ad 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
@@ -213,5 +213,26 @@
 	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
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
index bd8d2dc..053c14d 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
@@ -94,6 +94,10 @@
 								const vk::DeviceInterface& deviceInterface,
 								const vk::VkDevice device);
 
+deUint32 getMinRequiredVulkanVersion (const vk::SpirvVersion version);
+
+std::string	getVulkanName (const deUint32 version);
+
 } // SpirVAssembly
 } // vkt
 
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
index 67829d2..b746422 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
@@ -656,7 +656,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
index 6960dcb..3616c80 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
@@ -342,12 +342,12 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotOtherTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotOtherTests.cpp
index 106cad2..2438828 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotOtherTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotOtherTests.cpp
@@ -509,7 +509,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
index 9c37a47..9906e0c 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
@@ -213,7 +213,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
index 2ec8698..f11c701 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
@@ -580,7 +580,7 @@
 				<< "}\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 @@
 				 << "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				 << "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				<< "}\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 @@
 				<< "}\n";
 
 			programCollection.glslSources.add("tese")
-					<< glu::TessellationEvaluationSource(src.str());
+					<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 		}
 		else
 		{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinMaskVarTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinMaskVarTests.cpp
index 50fcdb2..adec91e 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinMaskVarTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinMaskVarTests.cpp
@@ -254,7 +254,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinVarTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinVarTests.cpp
index 5b5b86c..1608724 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinVarTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBuiltinVarTests.cpp
@@ -454,7 +454,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
index 0362dfe..72bb5c6 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
@@ -530,7 +530,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
index 3725b8d..9e1bbd0 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
@@ -292,7 +292,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShapeTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShapeTests.cpp
index 0ab03d1..afbbd99 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShapeTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShapeTests.cpp
@@ -334,7 +334,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShuffleTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShuffleTests.cpp
index ada18f5..37ab400 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShuffleTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsShuffleTests.cpp
@@ -295,7 +295,7 @@
 			<< "}\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 @@
 			 << "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\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 @@
 			<< "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
index 23a9496..66a6dea 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
@@ -821,9 +821,7 @@
 
 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(
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp
index 87fa6a9..f0f5732 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp
@@ -355,7 +355,7 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		src << "}\n";
 
 		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(src.str());
+				<< glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
 	}
 	else
 	{
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
index 58fcabc..7b947cd 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
@@ -3429,15 +3429,15 @@
 {
 }
 
-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)
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
index b6426b1..4cde4f1 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
@@ -110,49 +110,50 @@
 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::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; }
+	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; }
+
 
 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.
diff --git a/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp b/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
index 4eda4a6..50bc1c6 100644
--- a/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
+++ b/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
@@ -201,15 +201,19 @@
 	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 @@
 
 		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 @@
 
 			m_program->buildStatus	= Program::STATUS_FAILED;
 			m_program->buildLog		= log.str();
-
 		}
 	}
 
@@ -297,6 +302,8 @@
 
 		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 @@
 	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 @@
 {
 	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 @@
 	// 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 @@
 				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;
+					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);
 
-					testCase->initPrograms(sourcePrograms);
+					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 @@
 						 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	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 @@
 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;
 
-	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");
+	static const NamedValue<deUint32> s_vulkanVersion[] =
+	{
+		{ "1.0",	VK_MAKE_VERSION(1, 0, 0)	},
+		{ "1.1",	VK_MAKE_VERSION(1, 1, 0)	},
+	};
+
+	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 @@
 
 	{
 		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 @@
 
 	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);
+		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>());
 
-		const vkt::BuildStats	stats			= vkt::buildPrograms(testCtx,
-																	 cmdLine.getOption<opt::DstPath>(),
-																	 cmdLine.getOption<opt::Validate>());
+		tcu::print("SPIR-V versions: for GLSL sources: %s, for SPIR-V asm sources: %s\n",
+					getSpirvVersionName(spirvVersionForGlsl).c_str(),
+					getSpirvVersionName(spirvVersionForAsm).c_str());
 
-		tcu::print("DONE: %d passed, %d failed\n", stats.numSucceeded, stats.numFailed);
+		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;
 	}
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.cpp b/external/vulkancts/modules/vulkan/vktTestCase.cpp
index d6866fa..ed71e93 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.cpp
@@ -406,9 +406,9 @@
 
 // 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)
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.hpp b/external/vulkancts/modules/vulkan/vktTestCase.hpp
index b2138d0..a7e1507 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.hpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.hpp
@@ -27,6 +27,7 @@
 #include "tcuTestCase.hpp"
 #include "vkDefs.hpp"
 #include "deUniquePtr.hpp"
+#include "vkPrograms.hpp"
 
 namespace glu
 {
@@ -36,8 +37,6 @@
 namespace vk
 {
 class PlatformInterface;
-class ProgramBinary;
-template<typename Program> class ProgramCollection;
 class Allocator;
 struct SourceCollections;
 }
@@ -50,14 +49,14 @@
 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 @@
 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;
diff --git a/external/vulkancts/modules/vulkan/vktTestPackage.cpp b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
index 427b674..a57d5a0 100644
--- a/external/vulkancts/modules/vulkan/vktTestPackage.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
@@ -34,6 +34,7 @@
 #include "vkShaderToSpirV.hpp"
 #include "vkDebugReportUtil.hpp"
 #include "vkQueryUtil.hpp"
+#include "vkApiVersion.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -221,9 +222,15 @@
 
 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 @@
 
 	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 @@
 
 	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 @@
 
 	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);
 	}
 
diff --git a/external/vulkancts/mustpass/1.1.0/vk-default.txt b/external/vulkancts/mustpass/1.1.0/vk-default.txt
index 02d24fc..d65642b 100755
--- a/external/vulkancts/mustpass/1.1.0/vk-default.txt
+++ b/external/vulkancts/mustpass/1.1.0/vk-default.txt
@@ -168664,6 +168664,10 @@
 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.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.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_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_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
diff --git a/external/vulkancts/scripts/build_spirv_binaries.py b/external/vulkancts/scripts/build_spirv_binaries.py
index 8f0b0e5..d50219d 100644
--- a/external/vulkancts/scripts/build_spirv_binaries.py
+++ b/external/vulkancts/scripts/build_spirv_binaries.py
@@ -44,6 +44,7 @@
 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 @@
 		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 @@
 
 	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 @@
 						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 not os.path.exists(args.dstPath):
 		os.makedirs(args.dstPath)
 
-	execBuildPrograms(buildCfg, generator, module, args.dstPath)
+	execBuildPrograms(buildCfg, generator, module, args.dstPath, args.vulkanVersion)