Merge vk-gl-cts/vulkan-cts-1.1.6 into vk-gl-cts/vulkan-cts-1.2.1

Change-Id: Id02e3ec3375ebdb8642e28b334ef3a42158c904a
diff --git a/AndroidGen.mk b/AndroidGen.mk
index 2271361..9d59585 100644
--- a/AndroidGen.mk
+++ b/AndroidGen.mk
@@ -36,6 +36,7 @@
 	external/vulkancts/framework/vulkan/vkDebugReportUtil.cpp \
 	external/vulkancts/framework/vulkan/vkDefs.cpp \
 	external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp \
+	external/vulkancts/framework/vulkan/vkDeviceProperties.cpp \
 	external/vulkancts/framework/vulkan/vkDeviceUtil.cpp \
 	external/vulkancts/framework/vulkan/vkImageUtil.cpp \
 	external/vulkancts/framework/vulkan/vkImageWithMemory.cpp \
@@ -65,6 +66,7 @@
 	external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiBufferAndImageAllocationUtil.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiBufferComputeInstance.cpp \
+	external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiBufferViewAccessTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiBufferViewCreateTests.cpp \
@@ -155,10 +157,12 @@
 	external/vulkancts/modules/vulkan/geometry/vktGeometryTests.cpp \
 	external/vulkancts/modules/vulkan/geometry/vktGeometryTestsUtil.cpp \
 	external/vulkancts/modules/vulkan/geometry/vktGeometryVaryingGeometryShaderTests.cpp \
+	external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageAtomicOperationTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.cpp \
+	external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageMultisampleLoadStoreTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageMutableTests.cpp \
 	external/vulkancts/modules/vulkan/image/vktImageQualifiersTests.cpp \
@@ -176,11 +180,13 @@
 	external/vulkancts/modules/vulkan/memory/vktMemoryRequirementsTests.cpp \
 	external/vulkancts/modules/vulkan/memory/vktMemoryTests.cpp \
 	external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp \
+	external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.cpp \
 	external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.cpp \
 	external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.cpp \
 	external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.cpp \
 	external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.cpp \
 	external/vulkancts/modules/vulkan/pch.cpp \
+	external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineCacheTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineClearUtil.cpp \
@@ -205,14 +211,17 @@
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.cpp \
+	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleSampleLocationsExtTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderBuiltInTests.cpp \
+	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelinePushConstantTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelinePushDescriptorTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineReferenceRenderer.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineRenderToImageTests.cpp \
+	external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineSpecConstantTests.cpp \
 	external/vulkancts/modules/vulkan/pipeline/vktPipelineSpecConstantUtil.cpp \
@@ -235,6 +244,7 @@
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemFillUpdateCopyBufferTests.cpp \
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemImageValidator.cpp \
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemShaderImageAccessTests.cpp \
+	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.cpp \
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStorageBufferTests.cpp \
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp \
 	external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp \
@@ -247,6 +257,7 @@
 	external/vulkancts/modules/vulkan/query_pool/vktQueryPoolTests.cpp \
 	external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp \
+	external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassSampleReadTests.cpp \
@@ -254,6 +265,7 @@
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassSubpassDependencyTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.cpp \
+	external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentTests.cpp \
 	external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedClearAttachmentTests.cpp \
 	external/vulkancts/modules/vulkan/robustness/vktRobustBufferAccessWithVariablePointersTests.cpp \
@@ -268,6 +280,7 @@
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderClockTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderCommonFunctionTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp \
+	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderIntegerFunctionTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderPackingFunctionTests.cpp \
 	external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp \
@@ -310,6 +323,7 @@
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.cpp \
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmConditionalBranchTests.cpp \
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmCrossStageInterfaceTests.cpp \
+	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.cpp \
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp \
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFromHlslTests.cpp \
 	external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp \
@@ -408,6 +422,7 @@
 	external/vulkancts/modules/vulkan/vktTestPackage.cpp \
 	external/vulkancts/modules/vulkan/vktTestPackageEntry.cpp \
 	external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp \
+	external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.cpp \
 	external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp \
 	external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp \
 	external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp \
@@ -419,6 +434,7 @@
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp \
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp \
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrImageQueryTests.cpp \
+	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.cpp \
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrTests.cpp \
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp \
 	external/vulkancts/modules/vulkan/ycbcr/vktYCbCrViewTests.cpp \
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f25138..e0d7d43 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,8 +55,10 @@
 include(targets/${DEQP_TARGET}/${DEQP_TARGET}.cmake)
 
 # zlib
-find_path(ZLIB_INCLUDE_PATH	zlib.h)
-find_library(ZLIB_LIBRARY	z)
+find_package(ZLIB)
+# dEQP CMake compatibility (as for libpng)
+set(ZLIB_INCLUDE_PATH ${ZLIB_INCLUDE_DIRS})
+set(ZLIB_LIBRARY ${ZLIB_LIBRARIES})
 
 if (NOT ZLIB_INCLUDE_PATH OR NOT ZLIB_LIBRARY)
 	message(STATUS "System version of zlib not found, using external/zlib")
@@ -72,7 +74,7 @@
 # CMake files expect the non-standard PNG_INCLUDE_PATH and PNG_LIBRARY. Set the
 # non-standard variables here to retain compatibility with dEQP's existing
 # CMake files.
-include(FindPNG)
+find_package(PNG)
 set(PNG_INCLUDE_PATH ${PNG_INCLUDE_DIRS})
 set(PNG_LIBRARY ${PNG_LIBRARIES})
 
diff --git a/android/cts/master/src/gles3-driver-issues.txt b/android/cts/master/src/gles3-driver-issues.txt
index baf0d71..e4d641e 100644
--- a/android/cts/master/src/gles3-driver-issues.txt
+++ b/android/cts/master/src/gles3-driver-issues.txt
@@ -520,8 +520,6 @@
 dEQP-GLES3.functional.state_query.integers.draw_buffer_getinteger64
 dEQP-GLES3.functional.state_query.integers.draw_buffer_getfloat
 dEQP-GLES3.functional.state_query.shader.uniform_value_boolean
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.string.extensions
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_linear_linear_clamp_clamp_clamp
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_linear_linear_clamp_clamp_mirror
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index 2ebe9e2..7f2f69a 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
Binary files differ
diff --git a/external/fetch_sources.py b/external/fetch_sources.py
index 7681f27..c2f0377 100644
--- a/external/fetch_sources.py
+++ b/external/fetch_sources.py
@@ -314,9 +314,9 @@
 		"e7b5f0aa5b1b0eadc63a1c624c0ca7f5af133aa857d6a4271b0ef3d0bdb6868e",
 		"renderdoc"),
 	GitRepo(
-		"https://github.com/KhronosGroup/SPIRV-Tools.git",
-		None,
-		"c1d42038f79a926ba293556dbc325d4a90d452d0",
+		"https://gitlab.khronos.org/spirv/spirv-tools.git",
+		"git@gitlab.khronos.org:spirv/spirv-tools.git",
+		"290dd0d21ea11f3a5778e800ac0dda70b7a60223",
 		"spirv-tools"),
 	GitRepo(
 		"https://github.com/KhronosGroup/glslang.git",
@@ -332,7 +332,7 @@
 	GitRepo(
 		"https://github.com/google/amber.git",
 		None,
-		"62ef3e4e056d80f848baadee745cc176f6252cc3",
+		"0556811aeaad846f4bacbbd03e05e61fbfe1e545",
 		"amber"),
 ]
 
diff --git a/external/openglcts/README.md b/external/openglcts/README.md
index b5fb689..b71b926 100644
--- a/external/openglcts/README.md
+++ b/external/openglcts/README.md
@@ -642,6 +642,10 @@
     Run tests that exhaust memory on purpose
     default: 'disable'
 
+  --deqp-archive-dir=<value>
+    Path to test resource files
+    default: current working directory
+
   --deqp-case-fraction=<value>,<value>
     Run a fraction of the test cases (e.g. N,M means run group%M==N)
     default: ''
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl40-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl40-master.txt
index 97740ac..ecc9f42 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl40-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl40-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL40.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL40.draw_indirect.negative-noindirect-arrays
 KHR-GL40.draw_indirect.negative-noindirect-elements
 KHR-GL40.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl41-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl41-master.txt
index afc8688..75a23de 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl41-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl41-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL41.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL41.draw_indirect.negative-noindirect-arrays
 KHR-GL41.draw_indirect.negative-noindirect-elements
 KHR-GL41.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl42-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl42-master.txt
index 8ca8de1..9287485 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl42-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl42-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL42.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL42.draw_indirect.negative-noindirect-arrays
 KHR-GL42.draw_indirect.negative-noindirect-elements
 KHR-GL42.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl43-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl43-master.txt
index 1ababf8..7411192 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl43-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl43-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL43.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL43.draw_indirect.negative-noindirect-arrays
 KHR-GL43.draw_indirect.negative-noindirect-elements
 KHR-GL43.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl44-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl44-master.txt
index b5b4547..63901ab 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl44-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl44-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL44.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL44.draw_indirect.negative-noindirect-arrays
 KHR-GL44.draw_indirect.negative-noindirect-elements
 KHR-GL44.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl45-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl45-master.txt
index 75c49cb..f031ddd 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl45-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl45-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL45.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL45.draw_indirect.negative-noindirect-arrays
 KHR-GL45.draw_indirect.negative-noindirect-elements
 KHR-GL45.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl46-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl46-master.txt
index 78ffae6..4f1429d 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl46-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl46-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL46.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL46.draw_indirect.negative-noindirect-arrays
 KHR-GL46.draw_indirect.negative-noindirect-elements
 KHR-GL46.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl40-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl40-master.txt
index 97740ac..ecc9f42 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl40-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl40-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL40.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL40.draw_indirect.negative-noindirect-arrays
 KHR-GL40.draw_indirect.negative-noindirect-elements
 KHR-GL40.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl41-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl41-master.txt
index afc8688..75a23de 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl41-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl41-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL41.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL41.draw_indirect.negative-noindirect-arrays
 KHR-GL41.draw_indirect.negative-noindirect-elements
 KHR-GL41.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl42-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl42-master.txt
index e5c3274..a64a7f0 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl42-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl42-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL42.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL42.draw_indirect.negative-noindirect-arrays
 KHR-GL42.draw_indirect.negative-noindirect-elements
 KHR-GL42.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl43-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl43-master.txt
index e47dba1..f9a3ef6 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl43-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl43-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL43.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL43.draw_indirect.negative-noindirect-arrays
 KHR-GL43.draw_indirect.negative-noindirect-elements
 KHR-GL43.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl44-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl44-master.txt
index 649409f..1e66a37 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl44-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl44-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL44.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL44.draw_indirect.negative-noindirect-arrays
 KHR-GL44.draw_indirect.negative-noindirect-elements
 KHR-GL44.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl45-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl45-master.txt
index c62f252..13de73c 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl45-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl45-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL45.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL45.draw_indirect.negative-noindirect-arrays
 KHR-GL45.draw_indirect.negative-noindirect-elements
 KHR-GL45.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl46-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl46-master.txt
index bb18db6..a0e7c97 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl46-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/src/gl46-master.txt
@@ -3878,8 +3878,6 @@
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL46.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL46.draw_indirect.negative-noindirect-arrays
 KHR-GL46.draw_indirect.negative-noindirect-elements
 KHR-GL46.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl40-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl40-master.txt
index 3a05ff4..519fcf0 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl40-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl40-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL40.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL40.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL40.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL40.draw_indirect.negative-noindirect-arrays
 KHR-GL40.draw_indirect.negative-noindirect-elements
 KHR-GL40.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl41-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl41-master.txt
index ceea623..8a9c7e0 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl41-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl41-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL41.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL41.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL41.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL41.draw_indirect.negative-noindirect-arrays
 KHR-GL41.draw_indirect.negative-noindirect-elements
 KHR-GL41.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl42-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl42-master.txt
index 8dc2e6a..d84483f 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl42-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl42-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL42.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL42.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL42.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL42.draw_indirect.negative-noindirect-arrays
 KHR-GL42.draw_indirect.negative-noindirect-elements
 KHR-GL42.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl43-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl43-master.txt
index 971be4d..6a02c54 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl43-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl43-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL43.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL43.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL43.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL43.draw_indirect.negative-noindirect-arrays
 KHR-GL43.draw_indirect.negative-noindirect-elements
 KHR-GL43.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl44-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl44-master.txt
index 2bac3e7..4fc2353 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl44-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl44-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL44.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL44.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL44.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL44.draw_indirect.negative-noindirect-arrays
 KHR-GL44.draw_indirect.negative-noindirect-elements
 KHR-GL44.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl45-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl45-master.txt
index e0ba5c9..a2b4a8c 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl45-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl45-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL45.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL45.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL45.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL45.draw_indirect.negative-noindirect-arrays
 KHR-GL45.draw_indirect.negative-noindirect-elements
 KHR-GL45.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl46-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl46-master.txt
index 070492d..2b3eb4a 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl46-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.1.x/gl46-master.txt
@@ -3923,8 +3923,6 @@
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-arrays
 KHR-GL46.draw_indirect.advanced-twoPass-transformFeedback-elements
 KHR-GL46.draw_indirect.advanced-primitiveRestart-elements
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GL46.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GL46.draw_indirect.negative-noindirect-arrays
 KHR-GL46.draw_indirect.negative-noindirect-elements
 KHR-GL46.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/gles3-master.txt
index 6431f5f..45156af 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/gles3-master.txt
@@ -42292,8 +42292,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/src/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/src/gles3-master.txt
index 1c54bd9..837c784 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/src/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.3.x/src/gles3-master.txt
@@ -42273,8 +42273,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/gles3-master.txt
index 0fbed42..f9e8ab3 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/gles3-master.txt
@@ -42890,8 +42890,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/src/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/src/gles3-master.txt
index f8dd107..50f6b7b 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/src/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.4.x/src/gles3-master.txt
@@ -43639,8 +43639,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt
index e49fc73..3742dca 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt
@@ -2233,9 +2233,6 @@
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_local_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_return_type_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_return_type_fragment
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt
index 3791177..420b0c3 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt
@@ -42986,8 +42986,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/src/gles2-spec-issues.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/src/gles2-spec-issues.txt
index 21298d3..af109c1 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/src/gles2-spec-issues.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/src/gles2-spec-issues.txt
@@ -1,3 +1,8 @@
 #VK-GL-CTS 294
 dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
 dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
+
+#VK-GL-CTS 2116
+dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles2-master.txt
index e49fc73..3742dca 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles2-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles2-master.txt
@@ -2233,9 +2233,6 @@
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_local_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_return_type_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_return_type_fragment
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles3-master.txt
index 3791177..420b0c3 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/gles3-master.txt
@@ -42986,8 +42986,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/src/gles2-spec-issues.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/src/gles2-spec-issues.txt
index 21298d3..af109c1 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/src/gles2-spec-issues.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.6.x/src/gles2-spec-issues.txt
@@ -1,3 +1,8 @@
 #VK-GL-CTS 294
 dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
 dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
+
+#VK-GL-CTS 2116
+dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
index 164c179..b70bffc 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
@@ -145,8 +145,6 @@
 dEQP-GLES2.functional.shaders.preprocessor.basic.empty_function_fragment
 dEQP-GLES2.functional.shaders.preprocessor.basic.empty_directive_vertex
 dEQP-GLES2.functional.shaders.preprocessor.basic.empty_directive_fragment
-dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
-dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
 dEQP-GLES2.functional.shaders.preprocessor.definitions.define_value_and_function_vertex
 dEQP-GLES2.functional.shaders.preprocessor.definitions.define_value_and_function_fragment
 dEQP-GLES2.functional.shaders.preprocessor.definitions.undefine_object_invalid_syntax_vertex
@@ -2264,9 +2262,6 @@
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_local_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
-dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
-dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_fragment
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_return_type_vertex
 dEQP-GLES2.functional.shaders.functions.invalid.uniform_return_type_fragment
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
index df5b53e..ff0a2e1 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
@@ -43004,8 +43004,6 @@
 dEQP-GLES3.functional.state_query.shader.precision_fragment_lowp_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_mediump_int
 dEQP-GLES3.functional.state_query.shader.precision_fragment_highp_int
-dEQP-GLES3.functional.state_query.internal_format.rgba_samples
-dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.internal_format.r8_samples
 dEQP-GLES3.functional.state_query.internal_format.rg8_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb8_samples
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/src/gles2-spec-issues.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/src/gles2-spec-issues.txt
new file mode 100644
index 0000000..af109c1
--- /dev/null
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/src/gles2-spec-issues.txt
@@ -0,0 +1,8 @@
+#VK-GL-CTS 294
+dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
+dEQP-GLES2.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
+
+#VK-GL-CTS 2116
+dEQP-GLES2.functional.shaders.functions.invalid.attribute_argument_vertex
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_fragment
+dEQP-GLES2.functional.shaders.functions.invalid.varying_argument_vertex
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/gles31-khr-master.txt
index 03ee838..84b0575 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/gles31-khr-master.txt
@@ -1171,8 +1171,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/src/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/src/gles31-khr-master.txt
index 03ee838..84b0575 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/src/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.2.x/src/gles31-khr-master.txt
@@ -1171,8 +1171,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/gles31-khr-master.txt
index 9d96e35..e8ca86e 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/gles31-khr-master.txt
@@ -1171,8 +1171,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/src/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/src/gles31-khr-master.txt
index 9d96e35..e8ca86e 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/src/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.3.x/src/gles31-khr-master.txt
@@ -1171,8 +1171,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
index d9df703..6a23c58 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
@@ -2101,8 +2101,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/src/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/src/gles31-khr-master.txt
index d9df703..6a23c58 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/src/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/src/gles31-khr-master.txt
@@ -2101,8 +2101,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles2-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles2-khr-master.txt
index b797c0c..080903c 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles2-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles2-khr-master.txt
@@ -422,10 +422,10 @@
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES2.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f_linear
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles3-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles3-khr-master.txt
index 6bf4ede..5a6f76f 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles3-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles3-khr-master.txt
@@ -3244,10 +3244,10 @@
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES3.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -3262,6 +3262,8 @@
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES3.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES3.core.internalformat.copy_tex_image.rgb
 KHR-GLES3.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles31-khr-master.txt
index 828baad..2f0b28e 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles31-khr-master.txt
@@ -2109,8 +2109,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
@@ -2275,10 +2273,10 @@
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES31.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -2293,6 +2291,8 @@
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES31.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES31.core.internalformat.copy_tex_image.rgb
 KHR-GLES31.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles32-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles32-khr-master.txt
index 6697dad..788b602 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles32-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles32-khr-master.txt
@@ -1040,10 +1040,10 @@
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES32.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -1058,6 +1058,8 @@
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES32.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES32.core.internalformat.copy_tex_image.rgb
 KHR-GLES32.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles2-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles2-khr-master.txt
index b797c0c..080903c 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles2-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles2-khr-master.txt
@@ -422,10 +422,10 @@
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES2.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f_linear
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles3-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles3-khr-master.txt
index 6bf4ede..5a6f76f 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles3-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles3-khr-master.txt
@@ -3244,10 +3244,10 @@
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES3.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -3262,6 +3262,8 @@
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES3.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES3.core.internalformat.copy_tex_image.rgb
 KHR-GLES3.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles31-khr-master.txt
index 828baad..2f0b28e 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles31-khr-master.txt
@@ -2109,8 +2109,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
@@ -2275,10 +2273,10 @@
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES31.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -2293,6 +2291,8 @@
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES31.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES31.core.internalformat.copy_tex_image.rgb
 KHR-GLES31.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles32-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles32-khr-master.txt
index 6697dad..788b602 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles32-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles32-khr-master.txt
@@ -1040,10 +1040,10 @@
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES32.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -1058,6 +1058,8 @@
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES32.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES32.core.internalformat.copy_tex_image.rgb
 KHR-GLES32.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles2-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles2-khr-master.txt
index b797c0c..080903c 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles2-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles2-khr-master.txt
@@ -422,10 +422,10 @@
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES2.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES2.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES2.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES2.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES2.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES2.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES2.core.internalformat.texture2d.rgb_float_rgb32f_linear
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt
index 6bf4ede..5a6f76f 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt
@@ -3244,10 +3244,10 @@
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES3.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES3.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -3262,6 +3262,8 @@
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES3.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES3.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES3.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES3.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES3.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES3.core.internalformat.copy_tex_image.rgb
 KHR-GLES3.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
index 828baad..2f0b28e 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
@@ -2109,8 +2109,6 @@
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-arrays
 KHR-GLES31.core.draw_indirect.advanced-twoPass-Compute-elements
 KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-arrays
-KHR-GLES31.core.draw_indirect.misc-reservedMustBeZero-elements
 KHR-GLES31.core.draw_indirect.negative-noindirect-arrays
 KHR-GLES31.core.draw_indirect.negative-noindirect-elements
 KHR-GLES31.core.draw_indirect.negative-invalidMode-arrays
@@ -2275,10 +2273,10 @@
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES31.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES31.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -2293,6 +2291,8 @@
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES31.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES31.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES31.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES31.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES31.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES31.core.internalformat.copy_tex_image.rgb
 KHR-GLES31.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles32-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles32-khr-master.txt
index 6697dad..788b602 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles32-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles32-khr-master.txt
@@ -1040,10 +1040,10 @@
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_short_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_component_unsigned_int_depth_component
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth_stencil
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
-KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f_linear
-KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f_linear
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_oes_rgb_linear
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_oes_rgba_linear
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f
 KHR-GLES32.core.internalformat.texture2d.rgba_float_rgba32f
 KHR-GLES32.core.internalformat.texture2d.rgb_float_rgb32f_linear
@@ -1058,6 +1058,8 @@
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_short_5_6_5_rgb565
 KHR-GLES32.core.internalformat.texture2d.rgb_unsigned_byte_rgb8
 KHR-GLES32.core.internalformat.texture2d.rgba_unsigned_byte_rgba8
+KHR-GLES32.core.internalformat.texture2d.rgb_half_float_rgb16f
+KHR-GLES32.core.internalformat.texture2d.rgba_half_float_rgba16f
 KHR-GLES32.core.internalformat.texture2d.depth_stencil_unsigned_int_24_8_depth24_stencil8
 KHR-GLES32.core.internalformat.copy_tex_image.rgb
 KHR-GLES32.core.internalformat.copy_tex_image.rgba
diff --git a/external/openglcts/modules/common/glcInternalformatTests.cpp b/external/openglcts/modules/common/glcInternalformatTests.cpp
index 6442929..4304985 100644
--- a/external/openglcts/modules/common/glcInternalformatTests.cpp
+++ b/external/openglcts/modules/common/glcInternalformatTests.cpp
@@ -460,6 +460,7 @@
 		colorConversionMap[GL_BYTE]						   = &convertByte;
 		colorConversionMap[GL_UNSIGNED_BYTE]			   = &convertUByte;
 		colorConversionMap[GL_HALF_FLOAT]				   = &convertHFloat;
+		colorConversionMap[GL_HALF_FLOAT_OES]			   = &convertHFloat;
 		colorConversionMap[GL_FLOAT]					   = &convertFloat;
 		colorConversionMap[GL_SHORT]					   = &convertShort;
 		colorConversionMap[GL_UNSIGNED_SHORT]			   = &convertUShort;
@@ -693,6 +694,9 @@
 	if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
 		return STOP;
 
+	glu::RenderContext&  renderContext   = m_context.getRenderContext();
+	const Functions&	 gl				 = renderContext.getFunctions();
+
 	typedef std::map<GLenum, TextureFormat> ReferenceFormatMap;
 	static ReferenceFormatMap formatMap;
 	if (formatMap.empty())
@@ -709,7 +713,7 @@
 		formatMap[GL_DEPTH_COMPONENT] = TextureFormat(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT);
 		formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL);
 
-		if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 0)))
+		if (glu::IsES3Compatible(gl))
 		{
 			formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8_OES);
 		}
@@ -725,8 +729,6 @@
 	}
 
 	const TextureFormat& referenceFormat = formatIterator->second;
-	glu::RenderContext&  renderContext   = m_context.getRenderContext();
-	const Functions&	 gl				 = renderContext.getFunctions();
 
 	if (m_renderWidth > m_context.getRenderTarget().getWidth())
 		m_renderWidth = m_context.getRenderTarget().getWidth();
@@ -1422,10 +1424,10 @@
 		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT, OES_depth_texture),
 		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT, OES_depth_texture),
 		TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL, OES_packed_depth_stencil, OES_depth_texture),
-		TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float),
-		TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float),
-		TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
-		TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
+		TF(GL_RGB, GL_HALF_FLOAT_OES, GL_RGB, OES_texture_half_float),
+		TF(GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA, OES_texture_half_float),
+		TF(GL_RGB, GL_HALF_FLOAT_OES, GL_RGB, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
+		TF(GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
 		TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float),
 		TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, OES_texture_float),
 		TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
@@ -1462,6 +1464,8 @@
 			TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565),
 			TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8),
 			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8),
+			TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F),
+			TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F),
 			TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8),
 		};
 
diff --git a/external/openglcts/modules/common/glcShaderConstExprTests.cpp b/external/openglcts/modules/common/glcShaderConstExprTests.cpp
index 6071c6b..c04cb2d 100644
--- a/external/openglcts/modules/common/glcShaderConstExprTests.cpp
+++ b/external/openglcts/modules/common/glcShaderConstExprTests.cpp
@@ -210,19 +210,9 @@
 	{
 		shaderSpec.version = glu::GLSL_VERSION_310_ES;
 		shaderTypes.push_back(glu::SHADERTYPE_COMPUTE);
-
-		if (context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") ||
-			context.getContextInfo().isExtensionSupported("GL_OES_geometry_shader"))
-		{
-			shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);
-		}
-
-		if (context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
-			context.getContextInfo().isExtensionSupported("GL_OES_tessellation_shader"))
-		{
-			shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);
-			shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);
-		}
+		shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);
+		shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);
+		shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);
 	}
 	else
 	{
diff --git a/external/openglcts/modules/common/glcShaderMacroTests.cpp b/external/openglcts/modules/common/glcShaderMacroTests.cpp
index 30b1cce..9f29cbe 100644
--- a/external/openglcts/modules/common/glcShaderMacroTests.cpp
+++ b/external/openglcts/modules/common/glcShaderMacroTests.cpp
@@ -127,18 +127,9 @@
 	else if (glu::contextSupports(contextType, glu::ApiType::es(3, 1)))
 	{
 		shaderSpec.version = glu::GLSL_VERSION_310_ES;
-		if (m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") ||
-			m_context.getContextInfo().isExtensionSupported("GL_OES_geometry_shader"))
-		{
-			shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);
-		}
-
-		if (m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
-			m_context.getContextInfo().isExtensionSupported("GL_OES_tessellation_shader"))
-		{
-			shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);
-			shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);
-		}
+		shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);
+		shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);
+		shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);
 	}
 
 	for (std::size_t typeIndex = 0; typeIndex < shaderTypes.size(); ++typeIndex)
diff --git a/external/openglcts/modules/common/subgroups/CMakeLists.txt b/external/openglcts/modules/common/subgroups/CMakeLists.txt
index dbfa94a..e6696b9 100644
--- a/external/openglcts/modules/common/subgroups/CMakeLists.txt
+++ b/external/openglcts/modules/common/subgroups/CMakeLists.txt
@@ -36,6 +36,7 @@
 set(DEQP_GL_SUBGROUPS_LIBS
   glutil
   tcutil
+  glcts-common
   )
 
 PCH(DEQP_GL_SUBGROUPS_SRCS ../../pch.cpp)
diff --git a/external/openglcts/modules/common/subgroups/glcSubgroupsBasicTests.cpp b/external/openglcts/modules/common/subgroups/glcSubgroupsBasicTests.cpp
index acdc764..9f7de05 100755
--- a/external/openglcts/modules/common/subgroups/glcSubgroupsBasicTests.cpp
+++ b/external/openglcts/modules/common/subgroups/glcSubgroupsBasicTests.cpp
@@ -361,7 +361,7 @@
 				"{\n"
 				"  if (subgroupElect())\n"
 				"  {\n"
-				"    out_color.r = 71.f;\n" // << 2 * ELECTED_VALUE - UNELECTED_VALUE << ";\n"
+				"    out_color.r = 2.0f * " + electedValue.str() + ".0f - " + unelectedValue.str() + ".0f;\n"
 				"    out_color.g = 2.0f;\n"
 				"  }\n"
 				"  else\n"
@@ -1519,27 +1519,16 @@
 										supportedCheck, initPrograms, test, caseDef);
 		}
 
-		if (OPTYPE_ELECT == opTypeIndex)
+		for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
 		{
-			for (int stageIndex = 1; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
-			{
-				const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex]};
-				SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(),
-							op + "_" + getShaderStageName(caseDef.shaderStage), "",
-							supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
-			}
-		}
-		else
-		{
-			for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
-			{
-				const CaseDefinition caseDefFrag = {opTypeIndex, stages[stageIndex]};
-				SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(),
-							op + "_" + getShaderStageName(caseDefFrag.shaderStage), "",
-							supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDefFrag);
-			}
-		}
+			if (opTypeIndex == OPTYPE_ELECT && stageIndex == 0)
+				continue;		// This is not tested. I don't know why.
 
+			const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex]};
+			SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(),
+						op + "_" + getShaderStageName(caseDef.shaderStage), "",
+						supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
+		}
 	}
 
 	de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup(
diff --git a/external/openglcts/modules/gles31/es31cDrawIndirectTests.cpp b/external/openglcts/modules/gles31/es31cDrawIndirectTests.cpp
index 982f126..075236a 100644
--- a/external/openglcts/modules/gles31/es31cDrawIndirectTests.cpp
+++ b/external/openglcts/modules/gles31/es31cDrawIndirectTests.cpp
@@ -5718,203 +5718,6 @@
 }
 
 template <typename api>
-class CNonZeroReservedMustBeZeroArray : public DrawIndirectBase
-{
-	virtual std::string Title()
-	{
-		return "non-zero reservedMustBeZero - glDrawArrayIndirect";
-	}
-
-	virtual std::string Purpose()
-	{
-		return "Verify that no driver crash occurred";
-	}
-
-	virtual std::string Method()
-	{
-		return "Call glDrawArrayIndirect with non-zero ReservedMustBeZero";
-	}
-
-	virtual std::string PassCriteria()
-	{
-		return "The test will pass if no OpenGL errors reported and no driver crash occurred";
-	}
-
-	virtual long Setup()
-	{
-		glClear(GL_COLOR_BUFFER_BIT);
-		return NO_ERROR;
-	}
-
-	virtual long Run()
-	{
-		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
-		if (!_program)
-		{
-			return ERROR;
-		}
-		glUseProgram(_program);
-
-		CColorArray coords;
-		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
-
-		glGenVertexArrays(1, &_vao);
-		glBindVertexArray(_vao);
-
-		glGenBuffers(1, &_buffer);
-		glBindBuffer(GL_ARRAY_BUFFER, _buffer);
-
-		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
-		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
-		glEnableVertexAttribArray(0);
-
-		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
-		indirectArrays.count					 = static_cast<GLuint>(coords.size());
-		indirectArrays.primCount				 = 1;
-		indirectArrays.first					 = 0;
-		indirectArrays.reservedMustBeZero		 = 2312;
-
-		glGenBuffers(1, &_bufferIndirect);
-		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
-		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
-
-		glDrawArraysIndirect(GL_TRIANGLES, 0);
-
-		DIResult result;
-		if (glGetError() == GL_NO_ERROR)
-		{
-			//No GL error: undefined
-		}
-		else
-		{
-			result.error() << "Invalid error code returned by a driver";
-		}
-
-		return result.code();
-	}
-
-	virtual long Cleanup()
-	{
-		glDisableVertexAttribArray(0);
-		glUseProgram(0);
-		glDeleteProgram(_program);
-		glDeleteVertexArrays(1, &_vao);
-		glDeleteBuffers(1, &_buffer);
-		glDeleteBuffers(1, &_bufferIndirect);
-		return NO_ERROR;
-	}
-
-private:
-	GLuint _program;
-	GLuint _vao, _buffer, _bufferIndirect;
-};
-
-template <typename api>
-struct CNonZeroReservedMustBeZeroElements : public DrawIndirectBase
-{
-	virtual std::string Title()
-	{
-		return "non-zero reservedMustBeZero - glDrawElementsIndirect";
-	}
-
-	virtual std::string Purpose()
-	{
-		return "Verify that no driver crash occurred";
-	}
-
-	virtual std::string Method()
-	{
-		return "Call glDrawElementsIndirect with non-zero ReservedMustBeZero";
-	}
-
-	virtual std::string PassCriteria()
-	{
-		return "The test will pass if no OpenGL errors reported and no driver crash occurred";
-	}
-
-	virtual long Setup()
-	{
-		glClear(GL_COLOR_BUFFER_BIT);
-		return NO_ERROR;
-	}
-
-	virtual long Run()
-	{
-		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
-		if (!_program)
-		{
-			return ERROR;
-		}
-		glUseProgram(_program);
-
-		CColorArray coords;
-		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
-
-		glGenVertexArrays(1, &_vao);
-		glBindVertexArray(_vao);
-
-		glGenBuffers(1, &_buffer);
-		glBindBuffer(GL_ARRAY_BUFFER, _buffer);
-
-		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
-		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
-		glEnableVertexAttribArray(0);
-
-		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
-		indirectElements.count						 = static_cast<GLuint>(coords.size());
-		indirectElements.primCount					 = 1;
-		indirectElements.baseVertex					 = 0;
-		indirectElements.firstIndex					 = 0;
-		indirectElements.reservedMustBeZero			 = 1;
-
-		CElementArray elements(coords.size(), 0);
-		for (size_t i = 0; i < elements.size(); ++i)
-		{
-			elements[i] = static_cast<GLuint>(i);
-		}
-
-		glGenBuffers(1, &_bufferIndirect);
-		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
-		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
-
-		glGenBuffers(1, &_ebo);
-		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
-		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
-					 GL_STATIC_DRAW);
-
-		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
-
-		DIResult result;
-		if (glGetError() == GL_NO_ERROR)
-		{
-			//No GL error: undefined
-		}
-		else
-		{
-			result.error() << "Invalid error code returned by a driver";
-		}
-
-		return result.code();
-	}
-
-	virtual long Cleanup()
-	{
-		glDisableVertexAttribArray(0);
-		glUseProgram(0);
-		glDeleteProgram(_program);
-		glDeleteVertexArrays(1, &_vao);
-		glDeleteBuffers(1, &_buffer);
-		glDeleteBuffers(1, &_ebo);
-		glDeleteBuffers(1, &_bufferIndirect);
-		return NO_ERROR;
-	}
-
-private:
-	GLuint _program;
-	GLuint _vao, _buffer, _ebo, _bufferIndirect;
-};
-
-template <typename api>
 struct CNegativeZeroBufferArray : public DrawIndirectBase
 {
 	virtual std::string Title()
@@ -8153,11 +7956,6 @@
 	addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
 							 TestSubcase::Create<CPrimitiveRestartElements<test_api::GL> >));
 
-	addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-arrays",
-							 TestSubcase::Create<CNonZeroReservedMustBeZeroArray<test_api::GL> >));
-	addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-elements",
-							 TestSubcase::Create<CNonZeroReservedMustBeZeroElements<test_api::GL> >));
-
 	addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
 							 TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL> >));
 	addChild(new TestSubcase(m_context, "negative-noindirect-elements",
@@ -8341,11 +8139,6 @@
 	addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
 							 TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3> >));
 
-	addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-arrays",
-							 TestSubcase::Create<CNonZeroReservedMustBeZeroArray<test_api::ES3> >));
-	addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-elements",
-							 TestSubcase::Create<CNonZeroReservedMustBeZeroElements<test_api::ES3> >));
-
 	addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
 							 TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3> >));
 	addChild(new TestSubcase(m_context, "negative-noindirect-elements",
diff --git a/external/openglcts/modules/gles31/es31cShaderBitfieldOperationTests.cpp b/external/openglcts/modules/gles31/es31cShaderBitfieldOperationTests.cpp
index e4402c0..43c7276 100644
--- a/external/openglcts/modules/gles31/es31cShaderBitfieldOperationTests.cpp
+++ b/external/openglcts/modules/gles31/es31cShaderBitfieldOperationTests.cpp
@@ -26,6 +26,7 @@
 #include "deRandom.hpp"
 #include "deString.h"
 #include "deStringUtil.hpp"
+#include "deFloat16.h"
 #include "gluContextInfo.hpp"
 #include "gluDrawUtil.hpp"
 #include "gluPixelTransfer.hpp"
@@ -390,6 +391,32 @@
 	}
 };
 
+static float reduce32PrecisionTo16(float f)
+{
+	return deFloat16To32(deFloat32To16(f));
+}
+
+static GLuint pack(float x, float y, float z, float w, float range)
+{
+	return ((int(deFloatFloor(x * range + 0.5f)) & 0xFF) << 0) |
+			((int(deFloatFloor(y * range + 0.5f)) & 0xFF) << 8) |
+			((int(deFloatFloor(z * range + 0.5f)) & 0xFF) << 16)|
+			((int(deFloatFloor(w * range + 0.5f)) & 0xFF) << 24);
+}
+
+static bool checkOutData(GLuint result, const GLfloat input[4], float range)
+{
+	GLuint expected = pack(input[0], input[1], input[2], input[3], range);
+
+	GLuint expected_mp = pack(reduce32PrecisionTo16(input[0]),
+									reduce32PrecisionTo16(input[1]),
+									reduce32PrecisionTo16(input[2]),
+									reduce32PrecisionTo16(input[3]),
+									range);
+
+	return (expected == result || expected_mp == result);
+}
+
 class ShaderBitfieldOperationCasePackUnorm : public ShaderBitfieldOperationCase
 {
 public:
@@ -402,14 +429,7 @@
 private:
 	virtual bool test(Data const* data)
 	{
-		GLuint expected =
-			((int(data->inVec4[0] * 255.0 + 0.5) & 0xFF) << 0) | ((int(data->inVec4[1] * 255.0 + 0.5) & 0xFF) << 8) |
-			((int(data->inVec4[2] * 255.0 + 0.5) & 0xFF) << 16) | ((int(data->inVec4[3] * 255.0 + 0.5) & 0xFF) << 24);
-		if (expected != data->outUvec4[0])
-		{
-			return false;
-		}
-		return true;
+					return checkOutData(data->outUvec4[0], data->inVec4, 255.0f);
 	}
 };
 
@@ -425,15 +445,7 @@
 private:
 	virtual bool test(Data const* data)
 	{
-		GLuint expected = ((int(deFloatFloor(data->inVec4[0] * 127.0f + 0.5f)) & 0xFF) << 0) |
-						  ((int(deFloatFloor(data->inVec4[1] * 127.0f + 0.5f)) & 0xFF) << 8) |
-						  ((int(deFloatFloor(data->inVec4[2] * 127.0f + 0.5f)) & 0xFF) << 16) |
-						  ((int(deFloatFloor(data->inVec4[3] * 127.0f + 0.5f)) & 0xFF) << 24);
-		if (expected != data->outUvec4[0])
-		{
-			return false;
-		}
-		return true;
+					return checkOutData(data->outUvec4[0], data->inVec4, 127.0f);
 	}
 };
 
diff --git a/external/openglcts/modules/gles31/es31cShaderImageLoadStoreTests.cpp b/external/openglcts/modules/gles31/es31cShaderImageLoadStoreTests.cpp
index 5176bec..da55550 100644
--- a/external/openglcts/modules/gles31/es31cShaderImageLoadStoreTests.cpp
+++ b/external/openglcts/modules/gles31/es31cShaderImageLoadStoreTests.cpp
@@ -4175,10 +4175,28 @@
 		const int kSize = 64;
 		if (!IsVSFSAvailable(1, 1) || !IsImageAtomicSupported())
 			return NOT_SUPPORTED;
+                /* Note that we use imageAtomicCompSwap on the vertex
+                 * shader on purpose, for two reasons:
+                 *
+                 * * Test can't assume that the vertex shader will be
+                 *   executed exactly once per vertex. So the test
+                 *   can't use imageAtomicAdd as it is not possible to
+                 *   known in advance the final value (see khronos
+                 *   issue #1910)
+                 *
+                 * * Test can't assume that all the vertex shader
+                 *   executions will be executed before rasterization
+                 *   (so fragment shader) starts, specially on tile
+                 *   based GPUs. So the test can't use
+                 *   imageAtomicExchange, as it could happen that a
+                 *   vertex shader execution overrides the values
+                 *   being updated by the frament shader (see khronos
+                 *   issue #1997)
+                 */
 		const char* const glsl_vs =
 			NL "layout(location = 0) in vec4 i_position;" NL
 			   "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL "void main() {" NL
-			   "  gl_Position = i_position;" NL "  imageAtomicExchange(g_image, ivec2(0, gl_VertexID), 100u);" NL "}";
+			   "  gl_Position = i_position;" NL "  imageAtomicCompSwap(g_image, ivec2(0, gl_VertexID), 0u, 100u);" NL "}";
 		const char* const glsl_fs =
 			NL "#define KSIZE 64" NL "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL
 			   "void main() {" NL "  imageAtomicAdd(g_image, ivec2(0, int(gl_FragCoord.x) & 0x03), 0x1u);" NL "}";
diff --git a/external/openglcts/modules/glesext/geometry_shader/esextcGeometryShaderAPI.cpp b/external/openglcts/modules/glesext/geometry_shader/esextcGeometryShaderAPI.cpp
index 2695949..c4bc8d8 100644
--- a/external/openglcts/modules/glesext/geometry_shader/esextcGeometryShaderAPI.cpp
+++ b/external/openglcts/modules/glesext/geometry_shader/esextcGeometryShaderAPI.cpp
@@ -1554,6 +1554,11 @@
 	gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_gl_max_geometry_texture_image_units_ext_value);
 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname");
 
+	/* Retrieve GL_MAX_IMAGE_UNITS pname value */
+	glw::GLint m_gl_max_image_units_value = 0;
+	gl.getIntegerv(GL_MAX_IMAGE_UNITS, &m_gl_max_image_units_value);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_IMAGE_UNITS pname");
+
 	/* Check if m_gl_max_geometry_image_uniforms_value is less than or equal zero. */
 	if (m_gl_max_geometry_image_uniforms_ext_value <= 0)
 	{
@@ -1575,15 +1580,15 @@
 		}
 	}
 
-	/* Check if m_gl_max_geometry_texture_image_units_value is less than m_gl_max_geometry_image_uniforms_value. */
-	if (m_gl_max_geometry_texture_image_units_ext_value < m_gl_max_geometry_image_uniforms_ext_value)
+	/* Check if m_gl_max_image_units_value is less than m_gl_max_geometry_image_uniforms_value. */
+	if (m_gl_max_image_units_value < m_gl_max_geometry_image_uniforms_ext_value)
 	{
 		m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value "
 						   << "[" << m_gl_max_geometry_image_uniforms_ext_value
 						   << "]"
-							  " is greater than GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT query value "
+							  " is greater than GL_MAX_IMAGE_UNITS query value "
 							  "["
-						   << m_gl_max_geometry_texture_image_units_ext_value << "]." << tcu::TestLog::EndMessage;
+						   << m_gl_max_image_units_value << "]." << tcu::TestLog::EndMessage;
 
 		result = false;
 		goto end;
diff --git a/external/openglcts/modules/runner/glcTestRunner.cpp b/external/openglcts/modules/runner/glcTestRunner.cpp
index 885cfa8..e5423d8 100644
--- a/external/openglcts/modules/runner/glcTestRunner.cpp
+++ b/external/openglcts/modules/runner/glcTestRunner.cpp
@@ -765,12 +765,12 @@
 void TestRunner::deinit(void)
 {
 	// Print out totals.
-	bool isConformant = m_sessionsExecuted == m_sessionsPassed;
+	bool isConformant_ = m_sessionsExecuted == m_sessionsPassed;
 	DE_ASSERT(m_sessionsExecuted == m_sessionsPassed + m_sessionsFailed);
 	tcu::print("\n%d/%d sessions passed, conformance test %s\n", m_sessionsPassed, m_sessionsExecuted,
-			   isConformant ? "PASSED" : "FAILED");
+			   isConformant_ ? "PASSED" : "FAILED");
 
-	m_summary.isConformant = isConformant;
+	m_summary.isConformant = isConformant_;
 
 	// Write out summary.
 	writeRunSummary(m_summary, de::FilePath::join(m_logDirPath, "cts-run-summary.xml").getPath());
diff --git a/external/openglcts/modules/runner/glcTestRunner.hpp b/external/openglcts/modules/runner/glcTestRunner.hpp
index 4ae9a61..962d334 100644
--- a/external/openglcts/modules/runner/glcTestRunner.hpp
+++ b/external/openglcts/modules/runner/glcTestRunner.hpp
@@ -102,6 +102,7 @@
 	~TestRunner(void);
 
 	bool iterate(void);
+	bool isConformant() const { return m_summary.isConformant; }
 
 private:
 	TestRunner(const TestRunner& other);
diff --git a/external/openglcts/modules/runner/glcTestRunnerMain.cpp b/external/openglcts/modules/runner/glcTestRunnerMain.cpp
index 8a75b23..44c5c85 100644
--- a/external/openglcts/modules/runner/glcTestRunnerMain.cpp
+++ b/external/openglcts/modules/runner/glcTestRunnerMain.cpp
@@ -112,6 +112,7 @@
 int main(int argc, char** argv)
 {
 	CommandLine cmdLine;
+	int exitStatus = EXIT_SUCCESS;
 
 	if (!parseCommandLine(cmdLine, argc, argv))
 	{
@@ -129,7 +130,14 @@
 		for (;;)
 		{
 			if (!runner.iterate())
+			{
+				if (!runner.isConformant())
+				{
+					exitStatus = EXIT_FAILURE;
+				}
+
 				break;
+			}
 		}
 	}
 	catch (const std::exception& e)
@@ -138,5 +146,5 @@
 		return -1;
 	}
 
-	return 0;
+	return exitStatus;
 }
diff --git a/external/openglcts/scripts/build_mustpass.py b/external/openglcts/scripts/build_mustpass.py
index c7409ea..9795860 100644
--- a/external/openglcts/scripts/build_mustpass.py
+++ b/external/openglcts/scripts/build_mustpass.py
@@ -454,7 +454,8 @@
 
 MASTER_GLES2_COMMON_FILTERS			= [
 				include("gles2-master.txt"),
-				exclude("gles2-test-issues.txt")
+				exclude("gles2-test-issues.txt"),
+				exclude("gles2-spec-issues.txt")
 		]
 MASTER_GLES2_PKG         = Package(module = ES2CTS_MODULE, configurations = [
         # Master
diff --git a/external/vulkancts/README.md b/external/vulkancts/README.md
index c86c9e8..66f1021 100644
--- a/external/vulkancts/README.md
+++ b/external/vulkancts/README.md
@@ -140,6 +140,11 @@
 
 	--deqp-log-filename=<path>
 
+By default, the CTS will expect to find its test resource files in the current
+working directory. This can be overridden with:
+
+	--deqp-archive-dir=<path>
+
 By default, the shader cache will be written into the path "shadercache.bin". If the
 platform requires a different path, it can be specified with:
 
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/access-new-vector-inside-if-condition.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/access-new-vector-inside-if-condition.amber
new file mode 100644
index 0000000..8da30bc
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/access-new-vector-inside-if-condition.amber
@@ -0,0 +1,110 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader that accesses a new vector within an if condition
+
+# The test passes because the shader always writes the color red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   int x = 0;
+#
+#   if (vec4(1.0)[clamp(x, 0, 3)] >= 1.0)
+#   {
+#   }
+#
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 26
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %23
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "x"
+               OpName %23 "_GLF_color"
+               OpDecorate %8 RelaxedPrecision
+               OpDecorate %14 RelaxedPrecision
+               OpDecorate %16 RelaxedPrecision
+               OpDecorate %23 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %9 = OpConstant %6 0
+         %10 = OpTypeFloat 32
+         %11 = OpTypeVector %10 4
+         %12 = OpConstant %10 1
+         %13 = OpConstantComposite %11 %12 %12 %12 %12
+         %15 = OpConstant %6 3
+         %18 = OpTypeBool
+         %22 = OpTypePointer Output %11
+         %23 = OpVariable %22 Output
+         %24 = OpConstant %10 0
+         %25 = OpConstantComposite %11 %12 %24 %24 %12
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %8 = OpVariable %7 Function
+               OpStore %8 %9
+         %14 = OpLoad %6 %8
+         %16 = OpExtInst %6 %1 SClamp %14 %9 %15
+         %17 = OpVectorExtractDynamic %10 %13 %16
+         %19 = OpFOrdGreaterThanEqual %18 %17 %12
+               OpSelectionMerge %21 None
+               OpBranchConditional %19 %20 %21
+         %20 = OpLabel
+               OpBranch %21
+         %21 = OpLabel
+               OpStore %23 %25
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-in-do-while.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-in-do-while.amber
new file mode 100644
index 0000000..20d7f22
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-in-do-while.amber
@@ -0,0 +1,206 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with an always false if.
+
+# The test passes because the shader always writes color red.
+# Function brick() writes red in the beginning and returns in the end.
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--inline-entry-points-exhaustive'
+# '--scalar-replacement=100'
+# '--eliminate-local-single-block'
+# '--eliminate-local-single-block'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-code-aggressive'
+# '--eliminate-dead-branches'
+# '--convert-local-access-chains'
+# '--scalar-replacement=100'
+# '--reduce-load-size'
+# '--scalar-replacement=100'
+# '--redundancy-elimination'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-branches'
+# '--vector-dce'
+# '--eliminate-local-single-block'
+# '--private-to-local'
+# '--copy-propagate-arrays'
+# '--eliminate-dead-branches'
+# '--redundancy-elimination'
+# '--vector-dce'
+# '--scalar-replacement=100'
+# '--eliminate-local-multi-store'
+# '--scalar-replacement=100'
+# '--redundancy-elimination'
+# '--redundancy-elimination'
+# '--copy-propagate-arrays'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# vec2 brick(vec2 uv)
+# {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#
+#     int a;
+#     do
+#     {
+#         if (injectionSwitch.y < 0.0) // Always false
+#         {
+#             return vec2(1.0);
+#         }
+#         uv.y -= 1.0;
+#     } while (false);
+#
+#     uv.y -= 1.0;
+#     return vec2(1.0);
+# }
+#
+# void main()
+# {
+#     brick(vec2(1.0));
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 54
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %15
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %11 "brick(vf2;"
+               OpName %10 "uv"
+               OpName %15 "_GLF_color"
+               OpName %23 "buf0"
+               OpMemberName %23 0 "injectionSwitch"
+               OpName %25 ""
+               OpName %51 "param"
+               OpDecorate %15 Location 0
+               OpMemberDecorate %23 0 Offset 0
+               OpDecorate %23 Block
+               OpDecorate %25 DescriptorSet 0
+               OpDecorate %25 Binding 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %7 %8
+         %13 = OpTypeVector %6 4
+         %14 = OpTypePointer Output %13
+         %15 = OpVariable %14 Output
+         %16 = OpConstant %6 1
+         %17 = OpConstant %6 0
+         %18 = OpConstantComposite %13 %16 %17 %17 %16
+         %23 = OpTypeStruct %7
+         %24 = OpTypePointer Uniform %23
+         %25 = OpVariable %24 Uniform
+         %26 = OpTypeInt 32 1
+         %27 = OpConstant %26 0
+         %28 = OpTypeInt 32 0
+         %29 = OpConstant %28 1
+         %30 = OpTypePointer Uniform %6
+         %33 = OpTypeBool
+         %37 = OpConstantComposite %7 %16 %16
+         %39 = OpTypePointer Function %6
+         %44 = OpConstantFalse %33
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %51 = OpVariable %8 Function
+               OpStore %51 %37
+         %52 = OpFunctionCall %7 %11 %51
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %7 None %9
+         %10 = OpFunctionParameter %8
+         %12 = OpLabel
+               OpStore %15 %18
+               OpBranch %19
+         %19 = OpLabel
+               OpLoopMerge %21 %36 None
+               OpBranch %20
+         %20 = OpLabel
+         %31 = OpAccessChain %30 %25 %27 %29
+         %32 = OpLoad %6 %31
+         %34 = OpFOrdLessThan %33 %32 %17
+               OpSelectionMerge %53 None
+               OpBranchConditional %34 %35 %36
+         %35 = OpLabel
+               OpReturnValue %37
+         %53 = OpLabel
+               OpBranch %36
+         %36 = OpLabel
+         %40 = OpAccessChain %39 %10 %29
+         %41 = OpLoad %6 %40
+         %42 = OpFSub %6 %41 %16
+               OpStore %40 %42
+               OpBranchConditional %44 %19 %21
+         %21 = OpLabel
+         %46 = OpLoad %6 %40
+         %47 = OpFSub %6 %46 %16
+               OpStore %40 %47
+               OpReturnValue %37
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-with-discard-return.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-with-discard-return.amber
new file mode 100644
index 0000000..880d3c9
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/always-false-if-with-discard-return.amber
@@ -0,0 +1,152 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with discard keyword and a return
+
+# The test passes because main always writes the color red; the discard statement is unreachable.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# vec3 drawShape()
+# {
+#     discard;
+#     return vec3(1.0);
+# }
+# vec3 computePoint()
+# {
+#     drawShape();
+#     return vec3(1.0);
+# }
+# void main()
+# {
+#     if (injectionSwitch.x > injectionSwitch.y) // always false
+#     {
+#         drawShape();
+#         computePoint();
+#     }
+#
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 46
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %43
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "drawShape("
+               OpName %11 "computePoint("
+               OpName %22 "buf0"
+               OpMemberName %22 0 "injectionSwitch"
+               OpName %24 ""
+               OpName %43 "_GLF_color"
+               OpMemberDecorate %22 0 Offset 0
+               OpDecorate %22 Block
+               OpDecorate %24 DescriptorSet 0
+               OpDecorate %24 Binding 0
+               OpDecorate %43 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 3
+          %8 = OpTypeFunction %7
+         %14 = OpConstant %6 1
+         %15 = OpConstantComposite %7 %14 %14 %14
+         %21 = OpTypeVector %6 2
+         %22 = OpTypeStruct %21
+         %23 = OpTypePointer Uniform %22
+         %24 = OpVariable %23 Uniform
+         %25 = OpTypeInt 32 1
+         %26 = OpConstant %25 0
+         %27 = OpTypeInt 32 0
+         %28 = OpConstant %27 0
+         %29 = OpTypePointer Uniform %6
+         %32 = OpConstant %27 1
+         %35 = OpTypeBool
+         %41 = OpTypeVector %6 4
+         %42 = OpTypePointer Output %41
+         %43 = OpVariable %42 Output
+         %44 = OpConstant %6 0
+         %45 = OpConstantComposite %41 %14 %44 %44 %14
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %30 = OpAccessChain %29 %24 %26 %28
+         %31 = OpLoad %6 %30
+         %33 = OpAccessChain %29 %24 %26 %32
+         %34 = OpLoad %6 %33
+         %36 = OpFOrdGreaterThan %35 %31 %34
+               OpSelectionMerge %38 None
+               OpBranchConditional %36 %37 %38
+         %37 = OpLabel
+         %39 = OpFunctionCall %7 %9
+         %40 = OpFunctionCall %7 %11
+               OpBranch %38
+         %38 = OpLabel
+               OpStore %43 %45
+               OpReturn
+               OpFunctionEnd
+          %9 = OpFunction %7 None %8
+         %10 = OpLabel
+               OpKill
+               OpFunctionEnd
+         %11 = OpFunction %7 None %8
+         %12 = OpLabel
+         %18 = OpFunctionCall %7 %9
+               OpReturnValue %15
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/break-in-do-while-with-nested-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/break-in-do-while-with-nested-if.amber
new file mode 100644
index 0000000..4a78a31
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/break-in-do-while-with-nested-if.amber
@@ -0,0 +1,175 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with nested if
+
+# The test passes because main always writes color red.
+# Running code after writing red does not matter.
+
+# Optimized using spirv-opt with the following arguments:
+# '--copy-propagate-arrays'
+# '--if-conversion'
+# '--convert-local-access-chains'
+# '--convert-local-access-chains'
+# '--vector-dce'
+# '--reduce-load-size'
+# '--reduce-load-size'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--inline-entry-points-exhaustive'
+# '--redundancy-elimination'
+# '--private-to-local'
+# '--eliminate-dead-code-aggressive'
+# '--ccp'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--inline-entry-points-exhaustive'
+# '--eliminate-dead-inserts'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# void main()
+# {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#
+#     do
+#     {
+#         if (injectionSwitch.y < 0.0) // Always false
+#         {
+#             bool GLF_live12c5 = false;
+#             if (GLF_live12c5)
+#             {
+#             }
+#             continue;
+#         }
+#         break;
+#     } while (false);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 39
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %18 "buf0"
+               OpMemberName %18 0 "injectionSwitch"
+               OpName %20 ""
+               OpName %33 "GLF_live12c5"
+               OpDecorate %9 Location 0
+               OpMemberDecorate %18 0 Offset 0
+               OpDecorate %18 Block
+               OpDecorate %20 DescriptorSet 0
+               OpDecorate %20 Binding 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %17 = OpTypeVector %6 2
+         %18 = OpTypeStruct %17
+         %19 = OpTypePointer Uniform %18
+         %20 = OpVariable %19 Uniform
+         %21 = OpTypeInt 32 1
+         %22 = OpConstant %21 0
+         %23 = OpTypeInt 32 0
+         %24 = OpConstant %23 1
+         %25 = OpTypePointer Uniform %6
+         %28 = OpTypeBool
+         %32 = OpTypePointer Function %28
+         %34 = OpConstantFalse %28
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %33 = OpVariable %32 Function
+               OpStore %9 %12
+               OpBranch %13
+         %13 = OpLabel
+               OpLoopMerge %15 %37 None
+               OpBranch %14
+         %14 = OpLabel
+         %26 = OpAccessChain %25 %20 %22 %24
+         %27 = OpLoad %6 %26
+         %29 = OpFOrdLessThan %28 %27 %11
+               OpSelectionMerge %31 None
+               OpBranchConditional %29 %30 %31
+         %30 = OpLabel
+               OpStore %33 %34
+         %35 = OpLoad %28 %33
+               OpSelectionMerge %38 None
+               OpBranchConditional %35 %36 %37
+         %36 = OpLabel
+               OpBranch %37
+         %38 = OpLabel
+               OpBranch %37
+         %37 = OpLabel
+               OpBranchConditional %34 %13 %15
+         %31 = OpLabel
+               OpBranch %15
+         %15 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/call-if-while-switch.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/call-if-while-switch.amber
new file mode 100644
index 0000000..02a0594
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/call-if-while-switch.amber
@@ -0,0 +1,196 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with a call, if, while, switch
+
+# The test passes because the fragment shader does some control flow and then writes the color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+# int data[10];
+#
+# void merge(int from)
+# {
+#   int i = 1;
+#   if (1 < data[1])
+#   {
+#     i++;
+#   }
+#   while (i < 3)
+#   {
+#     i++;
+#     switch (int(injectionSwitch.x))
+#     {
+#     case 19:
+#       from++;
+#     case 38:
+#     case 23:
+#       break;
+#     case 78:
+#       _GLF_color = vec4(1.0);
+#     default:
+#       1;
+#     }
+#   }
+#   data[from] = 1;
+# }
+# void main()
+# {
+#   merge(1);
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 112
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %59
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %18 "data"
+               OpName %40 "buf0"
+               OpMemberName %40 0 "injectionSwitch"
+               OpName %42 ""
+               OpName %59 "_GLF_color"
+               OpDecorate %18 RelaxedPrecision
+               OpMemberDecorate %40 0 Offset 0
+               OpDecorate %40 Block
+               OpDecorate %42 DescriptorSet 0
+               OpDecorate %42 Binding 0
+               OpDecorate %59 Location 0
+               OpDecorate %71 RelaxedPrecision
+               OpDecorate %85 RelaxedPrecision
+               OpDecorate %95 RelaxedPrecision
+               OpDecorate %110 RelaxedPrecision
+               OpDecorate %99 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+         %13 = OpConstant %6 1
+         %14 = OpTypeInt 32 0
+         %15 = OpConstant %14 10
+         %16 = OpTypeArray %6 %15
+         %22 = OpTypeBool
+         %34 = OpConstant %6 3
+         %38 = OpTypeFloat 32
+         %39 = OpTypeVector %38 2
+         %40 = OpTypeStruct %39
+         %41 = OpTypePointer Uniform %40
+         %42 = OpVariable %41 Uniform
+         %43 = OpConstant %6 0
+         %44 = OpConstant %14 0
+         %45 = OpTypePointer Uniform %38
+         %57 = OpTypeVector %38 4
+         %58 = OpTypePointer Output %57
+         %59 = OpVariable %58 Output
+         %60 = OpConstant %38 1
+         %61 = OpConstantComposite %57 %60 %60 %60 %60
+         %67 = OpConstant %38 0
+         %68 = OpConstantComposite %57 %60 %67 %67 %60
+         %98 = OpTypePointer Function %16
+        %109 = OpConstant %6 2
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %18 = OpVariable %98 Function
+         %70 = OpAccessChain %7 %18 %13
+         %71 = OpLoad %6 %70
+         %72 = OpSLessThan %22 %13 %71
+        %110 = OpSelect %6 %72 %109 %13
+               OpBranch %77
+         %77 = OpLabel
+        %101 = OpPhi %6 %13 %5 %106 %89
+         %99 = OpPhi %6 %110 %5 %85 %89
+         %82 = OpSLessThan %22 %99 %34
+               OpLoopMerge %78 %89 None
+               OpBranchConditional %82 %83 %78
+         %83 = OpLabel
+         %85 = OpIAdd %6 %99 %13
+         %86 = OpAccessChain %45 %42 %43 %44
+         %87 = OpLoad %38 %86
+         %88 = OpConvertFToS %6 %87
+               OpSelectionMerge %111 None
+               OpSwitch %88 %90 19 %91 38 %92 23 %92 78 %93
+         %90 = OpLabel
+               OpBranch %89
+         %91 = OpLabel
+         %95 = OpIAdd %6 %101 %13
+               OpBranch %92
+         %92 = OpLabel
+        %108 = OpPhi %6 %101 %83 %95 %91
+               OpBranch %89
+         %93 = OpLabel
+               OpStore %59 %61
+               OpBranch %90
+        %111 = OpLabel
+               OpBranch %89
+         %89 = OpLabel
+        %106 = OpPhi %6 %101 %90 %108 %92 %43 %111
+               OpBranch %77
+         %78 = OpLabel
+         %97 = OpAccessChain %7 %18 %101
+               OpStore %97 %13
+               OpStore %59 %68
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/complex-nested-loops-and-call.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/complex-nested-loops-and-call.amber
new file mode 100644
index 0000000..7c9c22d
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/complex-nested-loops-and-call.amber
@@ -0,0 +1,318 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with complex nested loops, breaks, etc.
+
+# The test passes because the shader always outputs the color red.
+# pickColor(i) returns red (because i is always 1).
+# mand() returns red because it sets iteration to 1, breaks from the first loop,
+# does not enter the if, and returns pickColor(iteration).
+# main() writes red because it sets data[0] to mand() and then writes
+# vec4(data[0], 1.0) to the color output variable.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# vec3 pickColor(int i)
+# {
+#     return vec3(float(i), 0.0, 0.0); // i is always 1
+# }
+#
+# // Returns vec3(1.0, 0.0, 0.0)
+# vec3 mand()
+# {
+#     float x = 0.0, y = 0.0;
+#     int iteration = 1;
+#     int k = 1;
+#     int iterationCap = 17;
+#     do
+#     {
+#         if (injectionSwitch.x < 10.0) // always true
+#         {
+#             break;
+#         }
+#         if (injectionSwitch.x < 20.0)
+#         {
+#             discard;
+#         }
+#         iteration++;
+#         if (injectionSwitch.x < 30.0)
+#         {
+#             return vec3(1.0);
+#         }
+#     } while (k < iterationCap);
+#
+#     if (injectionSwitch.x > 10.0) // always false
+#     {
+#         if (gl_FragCoord.x < 0.0)
+#         {
+#             do
+#             {
+#                 _GLF_color = vec4(1.0);
+#             } while (gl_FragCoord.y < 0.0);
+#         }
+#         do
+#         {
+#             _GLF_color = vec4(1.0);
+#         } while (gl_FragCoord.x < 0.0);
+#         return vec3(1.0);
+#     }
+#     return pickColor(iteration); // pickColor(1)
+# }
+# void main()
+# {
+#     vec3 data[16];
+#     for (
+#         int i = 0;
+#         i < int(injectionSwitch.y); // i < 1
+#         i++)
+#     {
+#         for (
+#             int j = 0;
+#             j < 2;
+#             j++)
+#         {
+#             data[int(injectionSwitch.x)] = mand(); // data[0] = vec3(1.0, 0.0, 0.0);
+#         }
+#     }
+#     _GLF_color = vec4(data[0], 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 255
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %79 %91
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %36 "buf0"
+               OpMemberName %36 0 "injectionSwitch"
+               OpName %38 ""
+               OpName %79 "gl_FragCoord"
+               OpName %91 "_GLF_color"
+               OpName %133 "data"
+               OpMemberDecorate %36 0 Offset 0
+               OpDecorate %36 Block
+               OpDecorate %38 DescriptorSet 0
+               OpDecorate %38 Binding 0
+               OpDecorate %79 BuiltIn FragCoord
+               OpDecorate %91 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %8 = OpTypeFloat 32
+          %9 = OpTypeVector %8 3
+         %19 = OpConstant %8 0
+         %27 = OpConstant %6 1
+         %35 = OpTypeVector %8 2
+         %36 = OpTypeStruct %35
+         %37 = OpTypePointer Uniform %36
+         %38 = OpVariable %37 Uniform
+         %39 = OpConstant %6 0
+         %40 = OpTypeInt 32 0
+         %41 = OpConstant %40 0
+         %42 = OpTypePointer Uniform %8
+         %45 = OpConstant %8 10
+         %46 = OpTypeBool
+         %53 = OpConstant %8 20
+         %62 = OpConstant %8 30
+         %66 = OpConstant %8 1
+         %67 = OpConstantComposite %9 %66 %66 %66
+         %77 = OpTypeVector %8 4
+         %78 = OpTypePointer Input %77
+         %79 = OpVariable %78 Input
+         %80 = OpTypePointer Input %8
+         %90 = OpTypePointer Output %77
+         %91 = OpVariable %90 Output
+         %92 = OpConstantComposite %77 %66 %66 %66 %66
+         %93 = OpConstant %40 1
+        %128 = OpConstant %6 2
+        %130 = OpConstant %40 16
+        %131 = OpTypeArray %9 %130
+        %132 = OpTypePointer Function %131
+        %138 = OpTypePointer Function %9
+        %159 = OpConstantFalse %46
+        %162 = OpConstantTrue %46
+        %251 = OpUndef %9
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %133 = OpVariable %132 Function
+               OpBranch %111
+        %111 = OpLabel
+        %237 = OpPhi %6 %39 %5 %143 %124
+        %250 = OpPhi %9 %251 %5 %249 %124
+        %117 = OpAccessChain %42 %38 %39 %93
+        %118 = OpLoad %8 %117
+        %119 = OpConvertFToS %6 %118
+        %120 = OpSLessThan %46 %237 %119
+               OpLoopMerge %113 %124 None
+               OpBranchConditional %120 %112 %113
+        %112 = OpLabel
+               OpBranch %122
+        %122 = OpLabel
+        %249 = OpPhi %9 %250 %112 %245 %175
+        %238 = OpPhi %6 %39 %112 %141 %175
+        %129 = OpSLessThan %46 %238 %128
+               OpLoopMerge %252 %175 None
+               OpBranchConditional %129 %123 %252
+        %123 = OpLabel
+        %134 = OpAccessChain %42 %38 %39 %41
+        %135 = OpLoad %8 %134
+        %136 = OpConvertFToS %6 %135
+               OpBranch %174
+        %174 = OpLabel
+               OpLoopMerge %254 %176 None
+               OpBranch %178
+        %178 = OpLabel
+        %240 = OpPhi %6 %27 %174 %194 %198
+               OpLoopMerge %179 %198 None
+               OpBranch %181
+        %181 = OpLabel
+        %184 = OpFOrdLessThan %46 %135 %45
+               OpSelectionMerge %185 None
+               OpBranchConditional %184 %186 %185
+        %186 = OpLabel
+               OpBranch %179
+        %185 = OpLabel
+        %189 = OpFOrdLessThan %46 %135 %53
+               OpSelectionMerge %190 None
+               OpBranchConditional %189 %191 %190
+        %191 = OpLabel
+               OpKill
+        %190 = OpLabel
+        %194 = OpIAdd %6 %240 %27
+        %197 = OpFOrdLessThan %46 %135 %62
+               OpSelectionMerge %253 None
+               OpBranchConditional %197 %199 %198
+        %199 = OpLabel
+               OpBranch %179
+        %253 = OpLabel
+               OpBranch %198
+        %198 = OpLabel
+               OpBranch %178
+        %179 = OpLabel
+        %246 = OpPhi %9 %249 %186 %67 %199
+        %244 = OpPhi %6 %240 %186 %194 %199
+        %241 = OpPhi %46 %159 %186 %162 %199
+               OpSelectionMerge %204 None
+               OpBranchConditional %241 %254 %204
+        %204 = OpLabel
+        %207 = OpFOrdGreaterThan %46 %135 %45
+               OpSelectionMerge %208 None
+               OpBranchConditional %207 %209 %208
+        %209 = OpLabel
+        %210 = OpAccessChain %80 %79 %41
+        %211 = OpLoad %8 %210
+        %212 = OpFOrdLessThan %46 %211 %19
+               OpSelectionMerge %213 None
+               OpBranchConditional %212 %214 %213
+        %214 = OpLabel
+               OpBranch %215
+        %215 = OpLabel
+               OpStore %91 %92
+        %219 = OpAccessChain %80 %79 %93
+        %220 = OpLoad %8 %219
+        %221 = OpFOrdLessThan %46 %220 %19
+               OpLoopMerge %216 %215 None
+               OpBranchConditional %221 %215 %216
+        %216 = OpLabel
+               OpBranch %213
+        %213 = OpLabel
+               OpBranch %222
+        %222 = OpLabel
+               OpStore %91 %92
+               OpLoopMerge %223 %222 None
+               OpBranchConditional %212 %222 %223
+        %223 = OpLabel
+               OpBranch %254
+        %208 = OpLabel
+        %235 = OpConvertSToF %8 %244
+        %236 = OpCompositeConstruct %9 %235 %19 %19
+               OpBranch %254
+        %176 = OpLabel
+               OpBranch %174
+        %254 = OpLabel
+        %245 = OpPhi %9 %246 %179 %67 %223 %236 %208
+               OpBranch %175
+        %175 = OpLabel
+        %139 = OpAccessChain %138 %133 %136
+               OpStore %139 %245
+        %141 = OpIAdd %6 %238 %27
+               OpBranch %122
+        %252 = OpLabel
+	       OpBranch %124
+        %124 = OpLabel
+        %143 = OpIAdd %6 %237 %27
+               OpBranch %111
+        %113 = OpLabel
+        %144 = OpAccessChain %138 %133 %39
+        %145 = OpLoad %9 %144
+        %146 = OpCompositeExtract %8 %145 0
+        %147 = OpCompositeExtract %8 %145 1
+        %148 = OpCompositeExtract %8 %145 2
+        %149 = OpCompositeConstruct %77 %146 %147 %148 %66
+               OpStore %91 %149
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/conditional-return-in-infinite-while.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/conditional-return-in-infinite-while.amber
new file mode 100644
index 0000000..bf198f2
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/conditional-return-in-infinite-while.amber
@@ -0,0 +1,193 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader with conditional return inside an infinite loop
+
+# The test passes because the shader always writes the color red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# int GLF_live6tree[10];
+#
+# int GLF_live6search()
+# {
+#     // This function is never accessed
+#     int GLF_live6currentNode;
+#     int GLF_live6index = 0;
+#     while (true)
+#     {
+#         GLF_live6currentNode = GLF_live6tree[GLF_live6index];
+#         if (GLF_live6currentNode != 1)
+#         {
+#             return 1;
+#         }
+#         GLF_live6index = 1;
+#     }
+#     return 1;
+# }
+#
+# void main()
+# {
+#     if (injectionSwitch.x > 1.0) // Always false
+#     {
+#         GLF_live6search();
+#     }
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 57
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %54
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "GLF_live6search("
+               OpName %11 "GLF_live6index"
+               OpName %20 "GLF_live6currentNode"
+               OpName %25 "GLF_live6tree"
+               OpName %40 "buf0"
+               OpMemberName %40 0 "injectionSwitch"
+               OpName %42 ""
+               OpName %54 "_GLF_color"
+               OpDecorate %8 RelaxedPrecision
+               OpDecorate %11 RelaxedPrecision
+               OpDecorate %20 RelaxedPrecision
+               OpDecorate %25 RelaxedPrecision
+               OpDecorate %26 RelaxedPrecision
+               OpDecorate %29 RelaxedPrecision
+               OpDecorate %30 RelaxedPrecision
+               OpMemberDecorate %40 0 Offset 0
+               OpDecorate %40 Block
+               OpDecorate %42 DescriptorSet 0
+               OpDecorate %42 Binding 0
+               OpDecorate %51 RelaxedPrecision
+               OpDecorate %54 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeFunction %6
+         %10 = OpTypePointer Function %6
+         %12 = OpConstant %6 0
+         %18 = OpTypeBool
+         %19 = OpConstantTrue %18
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 10
+         %23 = OpTypeArray %6 %22
+         %24 = OpTypePointer Private %23
+         %25 = OpVariable %24 Private
+         %27 = OpTypePointer Private %6
+         %31 = OpConstant %6 1
+         %38 = OpTypeFloat 32
+         %39 = OpTypeVector %38 2
+         %40 = OpTypeStruct %39
+         %41 = OpTypePointer Uniform %40
+         %42 = OpVariable %41 Uniform
+         %43 = OpConstant %21 0
+         %44 = OpTypePointer Uniform %38
+         %47 = OpConstant %38 1
+         %52 = OpTypeVector %38 4
+         %53 = OpTypePointer Output %52
+         %54 = OpVariable %53 Output
+         %55 = OpConstant %38 0
+         %56 = OpConstantComposite %52 %47 %55 %55 %47
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %45 = OpAccessChain %44 %42 %12 %43
+         %46 = OpLoad %38 %45
+         %48 = OpFOrdGreaterThan %18 %46 %47
+               OpSelectionMerge %50 None
+               OpBranchConditional %48 %49 %50
+         %49 = OpLabel
+         %51 = OpFunctionCall %6 %8
+               OpBranch %50
+         %50 = OpLabel
+               OpStore %54 %56
+               OpReturn
+               OpFunctionEnd
+          %8 = OpFunction %6 None %7
+          %9 = OpLabel
+         %11 = OpVariable %10 Function
+         %20 = OpVariable %10 Function
+               OpStore %11 %12
+               OpBranch %13
+         %13 = OpLabel
+               OpLoopMerge %15 %16 None
+               OpBranch %17
+         %17 = OpLabel
+               OpBranchConditional %19 %14 %15
+         %14 = OpLabel
+         %26 = OpLoad %6 %11
+         %28 = OpAccessChain %27 %25 %26
+         %29 = OpLoad %6 %28
+               OpStore %20 %29
+         %30 = OpLoad %6 %20
+         %32 = OpINotEqual %18 %30 %31
+               OpSelectionMerge %34 None
+               OpBranchConditional %32 %33 %34
+         %33 = OpLabel
+               OpReturnValue %31
+         %34 = OpLabel
+               OpStore %11 %31
+               OpBranch %16
+         %16 = OpLabel
+               OpBranch %13
+         %15 = OpLabel
+               OpReturnValue %31
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/disc-and-add-in-func-in-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/disc-and-add-in-func-in-loop.amber
new file mode 100644
index 0000000..435bd04
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/disc-and-add-in-func-in-loop.amber
@@ -0,0 +1,194 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with discard and add in function in loop
+
+# The test passes because main always outputs the color red and returns.
+# red() has an unreachable discard and adds zero to the returned value.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#   vec2 injectionSwitch;
+# };
+#
+# vec4 red()
+# {
+#   if(injectionSwitch.x > 0.0) // always false
+#     discard;
+#
+#   return vec4(1.0, 0.0, 0.0, 1.0) + injectionSwitch.x; // add zero
+# }
+#
+# void main()
+# {
+#   while(true)
+#   {
+#     while(injectionSwitch.y > 0.0) // always true
+#     {
+#       _GLF_color = red();
+#       return;
+#     }
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 102
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %52
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %12 "buf0"
+               OpMemberName %12 0 "injectionSwitch"
+               OpName %14 ""
+               OpName %52 "_GLF_color"
+               OpMemberDecorate %12 0 Offset 0
+               OpDecorate %12 Block
+               OpDecorate %14 DescriptorSet 0
+               OpDecorate %14 Binding 0
+               OpDecorate %52 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+         %11 = OpTypeVector %6 2
+         %12 = OpTypeStruct %11
+         %13 = OpTypePointer Uniform %12
+         %14 = OpVariable %13 Uniform
+         %15 = OpTypeInt 32 1
+         %16 = OpConstant %15 0
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %19 = OpTypePointer Uniform %6
+         %22 = OpConstant %6 0
+         %23 = OpTypeBool
+         %28 = OpConstant %6 1
+         %29 = OpConstantComposite %7 %28 %22 %22 %28
+         %41 = OpConstantTrue %23
+         %47 = OpConstant %17 1
+         %51 = OpTypePointer Output %7
+         %52 = OpVariable %51 Output
+         %63 = OpConstantFalse %23
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpBranch %60
+         %60 = OpLabel
+               OpLoopMerge %59 %62 None
+               OpBranch %36
+         %36 = OpLabel
+        %100 = OpPhi %23 %63 %60 %98 %66
+               OpLoopMerge %38 %66 None
+               OpBranch %42
+         %42 = OpLabel
+         %48 = OpAccessChain %19 %14 %16 %47
+         %49 = OpLoad %6 %48
+         %50 = OpFOrdGreaterThan %23 %49 %22
+               OpLoopMerge %44 %45 None
+               OpBranchConditional %50 %43 %44
+         %43 = OpLabel
+               OpBranch %81
+         %81 = OpLabel
+               OpLoopMerge %82 %83 None
+               OpBranch %84
+         %84 = OpLabel
+         %85 = OpAccessChain %19 %14 %16 %18
+         %86 = OpLoad %6 %85
+         %87 = OpFOrdGreaterThan %23 %86 %22
+               OpSelectionMerge %88 None
+               OpBranchConditional %87 %89 %88
+         %89 = OpLabel
+         %90 = OpFunctionCall %2 %55
+         %91 = OpUndef %7
+               OpBranch %82
+         %88 = OpLabel
+         %94 = OpCompositeConstruct %7 %86 %86 %86 %86
+         %95 = OpFAdd %7 %29 %94
+               OpBranch %82
+         %83 = OpLabel
+               OpBranch %81
+         %82 = OpLabel
+         %97 = OpPhi %7 %91 %89 %95 %88
+               OpStore %52 %97
+               OpBranch %44
+         %45 = OpLabel
+               OpBranch %42
+         %44 = OpLabel
+         %98 = OpPhi %23 %100 %42 %41 %82
+               OpSelectionMerge %101 None
+               OpBranchConditional %98 %38 %66
+        %101 = OpLabel
+               OpBranch %66
+         %66 = OpLabel
+               OpBranch %36
+         %38 = OpLabel
+               OpSelectionMerge %68 None
+               OpBranchConditional %98 %59 %68
+         %68 = OpLabel
+               OpBranch %59
+         %62 = OpLabel
+               OpBranch %60
+         %59 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %55 = OpFunction %2 None %3
+         %56 = OpLabel
+               OpKill
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-array-manipulating-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-array-manipulating-loop.amber
new file mode 100644
index 0000000..c8c2dd7
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-array-manipulating-loop.amber
@@ -0,0 +1,162 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: An array-manipulating fragment shader with a discard
+
+# The test passes because the discard is not dynamically reachable, and
+# data[0] ends up with the value 1.0 after the loop so that red is
+# rendered
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+#
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  float data[10] = float[](0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0);
+#  for(int i = 0; i < 10; i++) {
+#    if(gl_FragCoord.x < 0.0) {
+#      discard;
+#    }
+#    data[0] = data[i];
+#  }
+#  _GLF_color = vec4(data[0], 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 61
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %38 %57
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %11 "data"
+               OpName %25 "i"
+               OpName %38 "gl_FragCoord"
+               OpName %57 "_GLF_color"
+               OpDecorate %25 RelaxedPrecision
+               OpDecorate %32 RelaxedPrecision
+               OpDecorate %38 BuiltIn FragCoord
+               OpDecorate %48 RelaxedPrecision
+               OpDecorate %53 RelaxedPrecision
+               OpDecorate %55 RelaxedPrecision
+               OpDecorate %57 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeInt 32 0
+          %8 = OpConstant %7 10
+          %9 = OpTypeArray %6 %8
+         %10 = OpTypePointer Function %9
+         %12 = OpConstant %6 0.100000001
+         %13 = OpConstant %6 0.200000003
+         %14 = OpConstant %6 0.300000012
+         %15 = OpConstant %6 0.400000006
+         %16 = OpConstant %6 0.5
+         %17 = OpConstant %6 0.600000024
+         %18 = OpConstant %6 0.699999988
+         %19 = OpConstant %6 0.800000012
+         %20 = OpConstant %6 0.899999976
+         %21 = OpConstant %6 1
+         %22 = OpConstantComposite %9 %12 %13 %14 %15 %16 %17 %18 %19 %20 %21
+         %23 = OpTypeInt 32 1
+         %24 = OpTypePointer Function %23
+         %26 = OpConstant %23 0
+         %33 = OpConstant %23 10
+         %34 = OpTypeBool
+         %36 = OpTypeVector %6 4
+         %37 = OpTypePointer Input %36
+         %38 = OpVariable %37 Input
+         %39 = OpConstant %7 0
+         %40 = OpTypePointer Input %6
+         %43 = OpConstant %6 0
+         %49 = OpTypePointer Function %6
+         %54 = OpConstant %23 1
+         %56 = OpTypePointer Output %36
+         %57 = OpVariable %56 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %11 = OpVariable %10 Function
+         %25 = OpVariable %24 Function
+               OpStore %11 %22
+               OpStore %25 %26
+               OpBranch %27
+         %27 = OpLabel
+               OpLoopMerge %29 %30 None
+               OpBranch %31
+         %31 = OpLabel
+         %32 = OpLoad %23 %25
+         %35 = OpSLessThan %34 %32 %33
+               OpBranchConditional %35 %28 %29
+         %28 = OpLabel
+         %41 = OpAccessChain %40 %38 %39
+         %42 = OpLoad %6 %41
+         %44 = OpFOrdLessThan %34 %42 %43
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %45 %46
+         %45 = OpLabel
+               OpKill
+         %46 = OpLabel
+         %48 = OpLoad %23 %25
+         %50 = OpAccessChain %49 %11 %48
+         %51 = OpLoad %6 %50
+         %52 = OpAccessChain %49 %11 %26
+               OpStore %52 %51
+               OpBranch %30
+         %30 = OpLabel
+         %53 = OpLoad %23 %25
+         %55 = OpIAdd %23 %53 %54
+               OpStore %25 %55
+               OpBranch %27
+         %29 = OpLabel
+         %58 = OpAccessChain %49 %11 %26
+         %59 = OpLoad %6 %58
+         %60 = OpCompositeConstruct %36 %59 %43 %43 %21
+               OpStore %57 %60
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop-in-function.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop-in-function.amber
new file mode 100644
index 0000000..7654782
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop-in-function.amber
@@ -0,0 +1,178 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader with a discard nested in a loop in a function
+
+# The test passes because the discard is always reached, so we end up with the background color, black.
+
+# Optimized using spirv-opt with the following arguments:
+# '--simplify-instructions'
+# '--eliminate-dead-inserts'
+# '--redundancy-elimination'
+# '--inline-entry-points-exhaustive'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--convert-local-access-chains'
+# '--convert-local-access-chains'
+# '--eliminate-dead-code-aggressive'
+# '--eliminate-local-single-store'
+# '--if-conversion'
+# '--simplify-instructions'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# void f()
+# {
+#  do
+#   {
+#    if(1.0 > injectionSwitch.y)
+#     {
+#      if(gl_FragCoord.y < 0.0)
+#       {
+#       }
+#      continue;
+#     }
+#    discard;
+#   }
+#  while(false);
+# }
+# void main()
+# {
+#  f();
+#  _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 47
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %31 %44
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %6 "f("
+               OpName %15 "buf0"
+               OpMemberName %15 0 "injectionSwitch"
+               OpName %17 ""
+               OpName %31 "gl_FragCoord"
+               OpName %44 "_GLF_color"
+               OpMemberDecorate %15 0 Offset 0
+               OpDecorate %15 Block
+               OpDecorate %17 DescriptorSet 0
+               OpDecorate %17 Binding 0
+               OpDecorate %31 BuiltIn FragCoord
+               OpDecorate %44 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+         %12 = OpTypeFloat 32
+         %13 = OpConstant %12 1
+         %14 = OpTypeVector %12 2
+         %15 = OpTypeStruct %14
+         %16 = OpTypePointer Uniform %15
+         %17 = OpVariable %16 Uniform
+         %18 = OpTypeInt 32 1
+         %19 = OpConstant %18 0
+         %20 = OpTypeInt 32 0
+         %21 = OpConstant %20 1
+         %22 = OpTypePointer Uniform %12
+         %25 = OpTypeBool
+         %29 = OpTypeVector %12 4
+         %30 = OpTypePointer Input %29
+         %31 = OpVariable %30 Input
+         %32 = OpTypePointer Input %12
+         %35 = OpConstant %12 0
+         %41 = OpConstantFalse %25
+         %43 = OpTypePointer Output %29
+         %44 = OpVariable %43 Output
+         %45 = OpConstantComposite %29 %13 %35 %35 %13
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %42 = OpFunctionCall %2 %6
+               OpStore %44 %45
+               OpReturn
+               OpFunctionEnd
+          %6 = OpFunction %2 None %3
+          %7 = OpLabel
+               OpBranch %8
+          %8 = OpLabel
+               OpLoopMerge %10 %38 None
+               OpBranch %9
+          %9 = OpLabel
+         %23 = OpAccessChain %22 %17 %19 %21
+         %24 = OpLoad %12 %23
+         %26 = OpFOrdGreaterThan %25 %13 %24
+               OpSelectionMerge %28 None
+               OpBranchConditional %26 %27 %28
+         %27 = OpLabel
+         %33 = OpAccessChain %32 %31 %21
+         %34 = OpLoad %12 %33
+         %36 = OpFOrdLessThan %25 %34 %35
+               OpSelectionMerge %46 None
+               OpBranchConditional %36 %37 %38
+         %37 = OpLabel
+               OpBranch %38
+         %46 = OpLabel
+               OpBranch %38
+         %38 = OpLabel
+               OpBranchConditional %41 %8 %10
+         %28 = OpLabel
+               OpKill
+         %10 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 0 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop.amber
new file mode 100644
index 0000000..a0abd62
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discard-in-loop.amber
@@ -0,0 +1,160 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader with a discard in a loop
+
+# The test passes because the discard is always reached, so the background colour will remain black.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  for(int i = 0; i < 10; i++)
+#   {
+#    if(gl_FragCoord.y < 0.0)
+#     {
+#      if(gl_FragCoord.x < 0.0)
+#       {
+#        break;
+#       }
+#      continue;
+#     }
+#    discard;
+#   }
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 64
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %22 %45
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %22 "gl_FragCoord"
+               OpName %45 "_GLF_color"
+               OpDecorate %22 BuiltIn FragCoord
+               OpDecorate %45 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %9 = OpConstant %6 0
+         %16 = OpConstant %6 10
+         %17 = OpTypeBool
+         %19 = OpTypeFloat 32
+         %20 = OpTypeVector %19 4
+         %21 = OpTypePointer Input %20
+         %22 = OpVariable %21 Input
+         %23 = OpTypeInt 32 0
+         %24 = OpConstant %23 1
+         %25 = OpTypePointer Input %19
+         %28 = OpConstant %19 0
+         %32 = OpConstant %23 0
+         %42 = OpConstant %6 1
+         %44 = OpTypePointer Output %20
+         %45 = OpVariable %44 Output
+         %46 = OpConstant %19 1
+         %47 = OpConstantComposite %20 %46 %28 %28 %46
+         %55 = OpConstantFalse %17
+         %58 = OpConstantTrue %17
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpBranch %52
+         %52 = OpLabel
+               OpLoopMerge %51 %54 None
+               OpBranch %10
+         %10 = OpLabel
+         %61 = OpPhi %6 %9 %52 %43 %37
+         %18 = OpSLessThan %17 %61 %16
+               OpLoopMerge %12 %37 None
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+         %26 = OpAccessChain %25 %22 %24
+         %27 = OpLoad %19 %26
+         %29 = OpFOrdLessThan %17 %27 %28
+               OpSelectionMerge %31 None
+               OpBranchConditional %29 %30 %31
+         %30 = OpLabel
+         %33 = OpAccessChain %25 %22 %32
+         %34 = OpLoad %19 %33
+         %35 = OpFOrdLessThan %17 %34 %28
+               OpSelectionMerge %63 None
+               OpBranchConditional %35 %36 %37
+         %36 = OpLabel
+               OpBranch %12
+         %63 = OpLabel
+               OpBranch %37
+         %37 = OpLabel
+         %43 = OpIAdd %6 %61 %42
+               OpBranch %10
+         %31 = OpLabel
+         %50 = OpFunctionCall %2 %48
+               OpBranch %12
+         %12 = OpLabel
+         %62 = OpPhi %17 %55 %10 %55 %36 %58 %31
+               OpSelectionMerge %59 None
+               OpBranchConditional %62 %51 %59
+         %59 = OpLabel
+               OpStore %45 %47
+               OpBranch %51
+         %54 = OpLabel
+               OpBranch %52
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %48 = OpFunction %2 None %3
+         %49 = OpLabel
+               OpKill
+               OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 0 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/discards-in-control-flow.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discards-in-control-flow.amber
new file mode 100644
index 0000000..a82b751
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/discards-in-control-flow.amber
@@ -0,0 +1,168 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with discards in loops and conditionals
+
+# The test passes because the fragment shader writes a red pixel, and then
+# terminates without further output manipulation (the discards are not
+# dynamically reachable)
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+#
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main(void)
+# {
+#  _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#  if(int(gl_FragCoord.x) < 2000) {
+#  } else {
+#    for(int ll = 0; ; ll++) {
+#      if(gl_FragCoord.x < 0.0) {
+#        discard;
+#      }
+#      if(ll >= 5) {
+#        break;
+#      }
+#    }
+#    if(int(gl_FragCoord.x) >= 2000) {
+#      discard;
+#    }
+#  }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 57
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9 %14
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %14 "gl_FragCoord"
+               OpName %29 "ll"
+               OpDecorate %9 Location 0
+               OpDecorate %14 BuiltIn FragCoord
+               OpDecorate %29 RelaxedPrecision
+               OpDecorate %41 RelaxedPrecision
+               OpDecorate %47 RelaxedPrecision
+               OpDecorate %49 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %13 = OpTypePointer Input %7
+         %14 = OpVariable %13 Input
+         %15 = OpTypeInt 32 0
+         %16 = OpConstant %15 0
+         %17 = OpTypePointer Input %6
+         %20 = OpTypeInt 32 1
+         %22 = OpConstant %20 2000
+         %23 = OpTypeBool
+         %28 = OpTypePointer Function %20
+         %30 = OpConstant %20 0
+         %42 = OpConstant %20 5
+         %48 = OpConstant %20 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %29 = OpVariable %28 Function
+               OpStore %9 %12
+         %18 = OpAccessChain %17 %14 %16
+         %19 = OpLoad %6 %18
+         %21 = OpConvertFToS %20 %19
+         %24 = OpSLessThan %23 %21 %22
+               OpSelectionMerge %26 None
+               OpBranchConditional %24 %25 %27
+         %25 = OpLabel
+               OpBranch %26
+         %27 = OpLabel
+               OpStore %29 %30
+               OpBranch %31
+         %31 = OpLabel
+               OpLoopMerge %33 %34 None
+               OpBranch %32
+         %32 = OpLabel
+         %35 = OpAccessChain %17 %14 %16
+         %36 = OpLoad %6 %35
+         %37 = OpFOrdLessThan %23 %36 %11
+               OpSelectionMerge %39 None
+               OpBranchConditional %37 %38 %39
+         %38 = OpLabel
+               OpKill
+         %39 = OpLabel
+         %41 = OpLoad %20 %29
+         %43 = OpSGreaterThanEqual %23 %41 %42
+               OpSelectionMerge %45 None
+               OpBranchConditional %43 %44 %45
+         %44 = OpLabel
+               OpBranch %33
+         %45 = OpLabel
+               OpBranch %34
+         %34 = OpLabel
+         %47 = OpLoad %20 %29
+         %49 = OpIAdd %20 %47 %48
+               OpStore %29 %49
+               OpBranch %31
+         %33 = OpLabel
+         %50 = OpAccessChain %17 %14 %16
+         %51 = OpLoad %6 %50
+         %52 = OpConvertFToS %20 %51
+         %53 = OpSGreaterThanEqual %23 %52 %22
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %54 %55
+         %54 = OpLabel
+               OpKill
+         %55 = OpLabel
+               OpBranch %26
+         %26 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-with-always-true-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-with-always-true-if.amber
new file mode 100644
index 0000000..23d640d
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-with-always-true-if.amber
@@ -0,0 +1,193 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with a do while that always returns
+
+# The test passes because the shader always writes the color red. The do while returns on first iteration.
+
+# Optimized using spirv-opt with the following arguments:
+# '--redundancy-elimination'
+# '--reduce-load-size'
+# '--combine-access-chains'
+# '--eliminate-dead-code-aggressive'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct _GLF_struct_12
+# {
+#   int count;
+# };
+#
+# bool puzzlelize(vec2 pos)
+# {
+#   return true;
+# }
+#
+# void main()
+# {
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#
+#   vec2 grid;
+#   _GLF_struct_12 _GLF_struct_replacement_12;
+#
+#   do
+#   {
+#     if (gl_FragCoord.y > -1.0) // Always true
+#     {
+#       return;
+#     }
+#   } while (_GLF_struct_replacement_12.count != 1);
+#
+#   grid += vec2(1, _GLF_struct_replacement_12.count);
+#   vec2 position;
+#   position = grid;
+#   vec4(puzzlelize(position));
+#
+#   _GLF_color = vec4(1.0, 1.0, 1.0, 1.0); // This should not be reached
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 64
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %19 %28
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %12 "puzzlelize(vf2;"
+               OpName %11 "pos"
+               OpName %19 "_GLF_color"
+               OpName %28 "gl_FragCoord"
+               OpName %40 "_GLF_struct_12"
+               OpMemberName %40 0 "count"
+               OpName %42 "_GLF_struct_replacement_12"
+               OpName %49 "grid"
+               OpName %56 "position"
+               OpName %58 "param"
+               OpDecorate %19 Location 0
+               OpDecorate %28 BuiltIn FragCoord
+               OpMemberDecorate %40 0 RelaxedPrecision
+               OpDecorate %46 RelaxedPrecision
+               OpDecorate %51 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeBool
+         %10 = OpTypeFunction %9 %8
+         %14 = OpConstantTrue %9
+         %17 = OpTypeVector %6 4
+         %18 = OpTypePointer Output %17
+         %19 = OpVariable %18 Output
+         %20 = OpConstant %6 1
+         %21 = OpConstant %6 0
+         %22 = OpConstantComposite %17 %20 %21 %21 %20
+         %27 = OpTypePointer Input %17
+         %28 = OpVariable %27 Input
+         %29 = OpTypeInt 32 0
+         %30 = OpConstant %29 1
+         %31 = OpTypePointer Input %6
+         %34 = OpConstant %6 -1
+         %39 = OpTypeInt 32 1
+         %40 = OpTypeStruct %39
+         %41 = OpTypePointer Function %40
+         %43 = OpConstant %39 0
+         %44 = OpTypePointer Function %39
+         %47 = OpConstant %39 1
+         %63 = OpConstantComposite %17 %20 %20 %20 %20
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %42 = OpVariable %41 Function
+         %49 = OpVariable %8 Function
+         %56 = OpVariable %8 Function
+         %58 = OpVariable %8 Function
+               OpStore %19 %22
+               OpBranch %23
+         %23 = OpLabel
+               OpLoopMerge %25 %26 None
+               OpBranch %24
+         %24 = OpLabel
+         %32 = OpAccessChain %31 %28 %30
+         %33 = OpLoad %6 %32
+         %35 = OpFOrdGreaterThan %9 %33 %34
+               OpSelectionMerge %37 None
+               OpBranchConditional %35 %36 %37
+         %36 = OpLabel
+               OpReturn
+         %37 = OpLabel
+               OpBranch %26
+         %26 = OpLabel
+         %45 = OpAccessChain %44 %42 %43
+         %46 = OpLoad %39 %45
+         %48 = OpINotEqual %9 %46 %47
+               OpBranchConditional %48 %23 %25
+         %25 = OpLabel
+         %51 = OpLoad %39 %45
+         %52 = OpConvertSToF %6 %51
+         %53 = OpCompositeConstruct %7 %20 %52
+         %54 = OpLoad %7 %49
+         %55 = OpFAdd %7 %54 %53
+               OpStore %49 %55
+         %57 = OpLoad %7 %49
+               OpStore %56 %57
+         %59 = OpLoad %7 %56
+               OpStore %58 %59
+         %60 = OpFunctionCall %9 %12 %58
+               OpStore %19 %63
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %9 None %10
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+               OpReturnValue %14
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/for-loop-with-return.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/for-loop-with-return.amber
new file mode 100644
index 0000000..b3f859c
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/for-loop-with-return.amber
@@ -0,0 +1,148 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with a for loop that loops only once
+
+# The test passes because the shader always writes the color red. The for loop only goes through once.
+
+# Optimized using spirv-opt with the following arguments:
+# '--vector-dce'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--ccp'
+# '--eliminate-dead-inserts'
+# '--convert-local-access-chains'
+# '--vector-dce'
+# '--eliminate-dead-code-aggressive'
+# '--vector-dce'
+# '--eliminate-local-multi-store'
+# '--if-conversion'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# vec3 mand()
+# {
+#   do
+#   {
+#     return vec3(1.0);
+#   } while (true);
+# }
+# void main()
+# {
+#   mand();
+#
+#   for (
+#       int i = 1;
+#       true;
+#       1)
+#   {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     return;
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 36
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %33
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "mand("
+               OpName %33 "_GLF_color"
+               OpDecorate %33 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 3
+          %8 = OpTypeFunction %7
+         %15 = OpConstant %6 1
+         %16 = OpConstantComposite %7 %15 %15 %15
+         %31 = OpTypeVector %6 4
+         %32 = OpTypePointer Output %31
+         %33 = OpVariable %32 Output
+         %34 = OpConstant %6 0
+         %35 = OpConstantComposite %31 %15 %34 %34 %15
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %21 = OpFunctionCall %7 %9
+               OpBranch %26
+         %26 = OpLabel
+               OpLoopMerge %28 %29 None
+               OpBranch %27
+         %27 = OpLabel
+               OpStore %33 %35
+               OpReturn
+         %29 = OpLabel
+               OpBranch %26
+         %28 = OpLabel
+               OpUnreachable
+               OpFunctionEnd
+          %9 = OpFunction %7 None %8
+         %10 = OpLabel
+               OpBranch %11
+         %11 = OpLabel
+               OpLoopMerge %13 %14 None
+               OpBranch %12
+         %12 = OpLabel
+               OpReturnValue %16
+         %14 = OpLabel
+               OpBranch %11
+         %13 = OpLabel
+               OpUnreachable
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/index.txt b/external/vulkancts/data/vulkan/amber/graphicsfuzz/index.txt
new file mode 100644
index 0000000..0a489d4
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/index.txt
@@ -0,0 +1,85 @@
+{	"access-new-vector-inside-if-condition.amber",	"access-new-vector-inside-if-condition","A shader that accesses a new vector within an if condition"							},
+{	"always-false-if-in-do-while.amber",			"always-false-if-in-do-while",			"A fragment shader with an always false if."											},
+{	"always-false-if-with-discard-return.amber",	"always-false-if-with-discard-return",	"A fragment shader with discard keyword and a return"									},
+{	"barrier-in-loop-with-break.amber",				"barrier-in-loop-with-break",			"A compute shader with a barrier in a loop with a break"								},
+{	"break-in-do-while-with-nested-if.amber",		"break-in-do-while-with-nested-if",		"A fragment shader with nested if"														},
+{	"call-if-while-switch.amber",					"call-if-while-switch",					"A fragment shader with a call, if, while, switch"										},
+{	"color-write-in-loop.amber",					"color-write-in-loop",					"A fragment shader that writes to color in a loop"										},
+{	"complex-nested-loops-and-call.amber",			"complex-nested-loops-and-call",		"A fragment shader with complex nested loops, breaks, etc."								},
+{	"conditional-return-in-infinite-while.amber",	"conditional-return-in-infinite-while",	"A shader with conditional return inside an infinite loop"								},
+{	"continue-and-merge.amber",						"continue-and-merge",					"A fragment shader with two nested loops"												},
+{	"control-flow-in-function.amber",				"control-flow-in-function",				"A fragment shader with a lot of control flow"											},
+{	"control-flow-switch.amber",					"control-flow-switch",					"A fragment shader with somewhat complex control flow and a switch"						},
+{	"dead-barriers-in-loops.amber",					"dead-barriers-in-loops",				"A compute shader with dead barriers"													},
+{	"dead-struct-init.amber",						"dead-struct-init",						"A fragment shader that uses struct initializers"										},
+{	"disc-and-add-in-func-in-loop.amber",			"disc-and-add-in-func-in-loop",			"A fragment shader with discard and add in function in loop"							},
+{	"discard-continue-return.amber",				"discard-continue-return",				"A fragment shader with a discard, continue, and return"								},
+{	"discard-in-array-manipulating-loop.amber",		"discard-in-array-manipulating-loop",	"An array-manipulating fragment shader with a discard"									},
+{	"discard-in-loop.amber",						"discard-in-loop",						"A shader with a discard in a loop"														},
+{	"discard-in-loop-in-function.amber",			"discard-in-loop-in-function",			"A shader with a discard nested in a loop in a function"								},
+{	"discards-in-control-flow.amber",				"discards-in-control-flow",				"A fragment shader with discards in loops and conditionals"								},
+{	"do-while-loop-in-conditionals.amber",			"do-while-loop-in-conditionals",		"A fragment shader with do-while loop in conditional nest"								},
+{	"do-while-with-always-true-if.amber",			"do-while-with-always-true-if",			"A fragment shader with a do while that always returns"									},
+{	"early-return-and-barrier.amber",				"early-return-and-barrier",				"A compute shader with an early return and a barrier"									},
+{	"for-condition-always-false.amber",				"for-condition-always-false",			"A fragment shader that uses a for loop with condition always false"					},
+{	"for-loop-with-return.amber",					"for-loop-with-return",					"A fragment shader with a for loop that loops only once"								},
+{	"for-with-ifs-and-return.amber",				"for-with-ifs-and-return",				"A fragment shader with two ifs and return/continue inside a for loop"					},
+{	"fragcoord-control-flow.amber",					"fragcoord-control-flow",				"A fragment shader that uses FragCoord and somewhat complex control flow"				},
+{	"fragcoord-control-flow-2.amber",				"fragcoord-control-flow-2",				"A fragment shader that uses FragCoord and somewhat complex control flow"				},
+{	"if-and-switch.amber",							"if-and-switch",						"A fragment shader with a switch and some data flow"									},
+{	"int-mat2-struct.amber",						"int-mat2-struct",						"Fragment shader using (int, mat2) struct"												},
+{	"loop-call-discard.amber",						"loop-call-discard",					"A fragment shader with nested loops and a function call"								},
+{	"loop-dead-if-loop.amber",						"loop-dead-if-loop",					"A fragment shader with a loop, dead if, and a loop"									},
+{	"loop-nested-ifs.amber",						"loop-nested-ifs",						"A fragment shader with a for loop containing nested ifs"								},
+{	"loops-breaks-returns.amber",					"loops-breaks-returns",					"A compute shader with loops, breaks, returns"											},
+{	"loops-ifs-continues-call.amber",				"loops-ifs-continues-call",				"A fragment shader with nested control flow and a call"									},
+{	"mat-array-deep-control-flow.amber",			"mat-array-deep-control-flow",			"A fragment shader that uses an array of matrices and has deep control flow"			},
+{	"mat-array-distance.amber",						"mat-array-distance",					"A fragment shader that uses an array of matrices and distance"							},
+{	"mat-mul-in-loop.amber",						"mat-mul-in-loop",						"Shader with matrix multiplication in loop"												},
+{	"matrices-and-return-in-loop.amber",			"matrices-and-return-in-loop",			"A fragment shader with matrices and a return in a loop"								},
+{	"max-mix-conditional-discard.amber",			"max-mix-conditional-discard",			"A fragment shader with an expression used in two discard guards"						},
+{	"mix-floor-add.amber",							"mix-floor-add",						"A fragment shader with mix, uintBitsToFloat, and floor"								},
+{	"modf-gl-color.amber",							"modf-gl-color",						"A fragment shader with modf of gl color"												},
+{	"modf-temp-modf-color.amber",					"modf-temp-modf-color",					"A fragment shader that calls modf twice, once with color"								},
+{	"nested-for-loops-with-return.amber",			"nested-for-loops-with-return",			"A fragment shader with two nested for loops with return"								},
+{	"nested-ifs-and-return-in-for-loop.amber",		"nested-ifs-and-return-in-for-loop",	"A fragment shader with return in nest of ifs, inside loop"								},
+{	"nested-loops-switch.amber",					"nested-loops-switch",					"A fragment shader with nested loops and a switch"										},
+{	"pow-vec4.amber",								"pow-vec4",								"A fragment shader that uses pow"														},
+{	"return-before-writing-wrong-color.amber",		"return-before-writing-wrong-color",	"A fragment shader with return before writing wrong color"								},
+{	"return-float-from-while-loop.amber",			"return-float-from-while-loop",			"A fragment shader with unreachable while loop"											},
+{	"return-in-loop-in-function.amber",				"return-in-loop-in-function",			"A fragment shader with early return from loop in function"								},
+{	"returned-boolean-in-vector.amber",				"returned-boolean-in-vector",			"A fragment shader with returned boolean in vector"										},
+{	"similar-nested-ifs.amber",						"similar-nested-ifs",					"A fragment shader with similar nested ifs and loops"									},
+{	"smoothstep-after-loop.amber",					"smoothstep-after-loop",				"Fragment shader with 1-iteration loop and smoothstep"									},
+{	"struct-and-unreachable-infinite-loop.amber",	"struct-and-unreachable-infinite-loop",	"Fragment shader with struct and unreachable infinite loop"								},
+{	"struct-controlled-loop.amber",					"struct-controlled-loop",				"Shader with loop controlled by struct"													},
+{	"struct-used-as-temporary.amber",				"struct-used-as-temporary",				"A fragment shader that uses a temporary struct variable"								},
+{	"switch-if-discard.amber",						"switch-if-discard",					"A fragment shader with a switch, if, and discard"										},
+{	"switch-with-empty-if-false.amber",				"switch-with-empty-if-false",			"A fragment shader with always false if in switch statement"							},
+{	"swizzle-struct-init-min.amber",				"swizzle-struct-init-min",				"A fragment shader that uses vector swizzles, struct initializers, and min"				},
+{	"transpose-rectangular-matrix.amber",			"transpose-rectangular-matrix",			"Fragment shader that uses 'transpose'"													},
+{	"two-2-iteration-loops.amber",					"two-2-iteration-loops",				"Fragment shader with pair of outer loops"												},
+{	"two-for-loops-with-barrier-function.amber",	"two-for-loops-with-barrier-function",	"A compute shader with two barrier functions"											},
+{	"two-loops-matrix.amber",						"two-loops-matrix",						"A fragment shader with two loops and some matrices"									},
+{	"two-loops-set-struct.amber",					"two-loops-set-struct",					"A fragment shader with two loops that write to a struct"								},
+{	"two-loops-with-break.amber",					"two-loops-with-break",					"A fragment shader with two loops with breaks"											},
+{	"two-nested-do-whiles.amber",					"two-nested-do-whiles",					"A fragment shader with nested do while"												},
+{	"two-nested-for-loops-with-returns.amber",		"two-nested-for-loops-with-returns",	"A compute shader with two nested for loops"											},
+{	"two-nested-infinite-loops-discard.amber",		"two-nested-infinite-loops-discard",	"A fragment shader with an always false if function"									},
+{	"undefined-integer-in-function.amber",			"undefined-integer-in-function",		"A fragment shader with nested do while and undefined int"								},
+{	"uninit-element-cast-in-loop.amber",			"uninit-element-cast-in-loop",			"A fragment shader with uninitialized element cast in loop"								},
+{	"uninitialized-var-decrement-and-add.amber",	"uninitialized-var-decrement-and-add",	"A fragment shader that uses an uninitialized variable"									},
+{	"undefined-assign-in-infinite-loop.amber",		"undefined-assign-in-infinite-loop",	"A fragment shader with uninitialized read in infinite loop"							},
+{	"unreachable-barrier-in-loops.amber",			"unreachable-barrier-in-loops",			"A compute shader with an unreachable barrier in a loop nest"							},
+{	"unreachable-continue-statement.amber",			"unreachable-continue-statement",		"A fragment shader with unreachable continue statement"									},
+{	"unreachable-discard-statement-in-if.amber",	"unreachable-discard-statement-in-if",	"A fragment shader with discard keyword and a return"									},
+{	"unreachable-discard-statement.amber",			"unreachable-discard-statement",		"A fragment shader with unreachable discard statement"									},
+{	"unreachable-loops.amber",						"unreachable-loops",					"Fragment shader that writes red despite unreachable loops"								},
+{	"unreachable-loops-in-switch.amber",			"unreachable-loops-in-switch",			"A fragment shader with unreachable loops in a switch"									},
+{	"unreachable-return-in-loop.amber",				"unreachable-return-in-loop",			"A fragment shader with an unreachable return in a loop"								},
+{	"unreachable-switch-case-with-discards.amber",	"unreachable-switch-case-with-discards","A shader with a switch statement containing unreachable discards"						},
+{	"while-function-always-false.amber",			"while-function-always-false",			"A fragment shader with an always false while function"									},
+{	"while-inside-switch.amber",					"while-inside-switch",					"A fragment shader that uses a while loop inside a switch"								},
+{	"write-before-break.amber",						"write-before-break",					"Fragment shader that writes red before loop break"										},
+{	"write-red-in-loop-nest.amber",					"write-red-in-loop-nest",				"A fragment shader that writes red in a nest of loops"									},
+{	"wrong-color-in-always-false-if.amber",			"wrong-color-in-always-false-if",		"A fragment shader with wrong color write in false if"									},
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/int-mat2-struct.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/int-mat2-struct.amber
new file mode 100644
index 0000000..1f08441
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/int-mat2-struct.amber
@@ -0,0 +1,196 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Fragment shader using (int, mat2) struct
+
+# The test passes because the struct instance is created and used in a way that guarantees writing red to the output buffer
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-local-single-block'
+# '--eliminate-dead-branches'
+# '--vector-dce'
+# '--simplify-instructions'
+# '--reduce-load-size'
+# '--eliminate-local-multi-store'
+# '--private-to-local'
+# '--eliminate-dead-branches'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--ccp'
+# '--reduce-load-size'
+# '--eliminate-local-single-block'
+# '--scalar-replacement=100'
+# '--combine-access-chains'
+# '--if-conversion'
+# '--ccp'
+# '--eliminate-dead-branches'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-local-single-block'
+# '--inline-entry-points-exhaustive'
+# '--eliminate-dead-inserts'
+# '--eliminate-local-multi-store'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--vector-dce'
+# '--eliminate-dead-inserts'
+# '--private-to-local'
+# '--eliminate-local-multi-store'
+# spirv-opt commit hash: f1e5cd73f658abcc23ee96d78f2dc27c4b7028c1
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# struct S {
+#  int f1;
+#  mat2 f2;
+# } ;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  S myS = S(1, transpose(gl_FragCoord.x < 0.0 ? mat2(1.0, 2.0, 3.0, 4.0) : mat2(0.5, -0.5, -0.5, 0.5)));
+#  _GLF_color = vec4(float(myS.f1), myS.f2[0][0] + myS.f2[1][0], myS.f2[0][1] + myS.f2[1][1], float(myS.f1));
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 81
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %16 %46
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %10 "S"
+               OpMemberName %10 0 "f1"
+               OpMemberName %10 1 "f2"
+               OpName %16 "gl_FragCoord"
+               OpName %46 "_GLF_color"
+               OpMemberDecorate %10 0 RelaxedPrecision
+               OpDecorate %16 BuiltIn FragCoord
+               OpDecorate %46 Location 0
+               OpDecorate %69 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeFloat 32
+          %8 = OpTypeVector %7 2
+          %9 = OpTypeMatrix %8 2
+         %10 = OpTypeStruct %6 %9
+         %11 = OpTypePointer Function %10
+         %13 = OpConstant %6 1
+         %14 = OpTypeVector %7 4
+         %15 = OpTypePointer Input %14
+         %16 = OpVariable %15 Input
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %19 = OpTypePointer Input %7
+         %22 = OpConstant %7 0
+         %23 = OpTypeBool
+         %25 = OpTypePointer Function %9
+         %29 = OpConstant %7 1
+         %30 = OpConstant %7 2
+         %31 = OpConstantComposite %8 %29 %30
+         %32 = OpConstant %7 3
+         %33 = OpConstant %7 4
+         %34 = OpConstantComposite %8 %32 %33
+         %35 = OpConstantComposite %9 %31 %34
+         %37 = OpConstant %7 0.5
+         %38 = OpConstant %7 -0.5
+         %39 = OpConstantComposite %8 %37 %38
+         %40 = OpConstantComposite %8 %38 %37
+         %41 = OpConstantComposite %9 %39 %40
+         %45 = OpTypePointer Output %14
+         %46 = OpVariable %45 Output
+         %47 = OpConstant %6 0
+         %48 = OpTypePointer Function %6
+         %52 = OpTypePointer Function %7
+         %58 = OpConstant %17 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %70 = OpVariable %25 Function
+         %69 = OpVariable %48 Function
+         %26 = OpVariable %25 Function
+         %20 = OpAccessChain %19 %16 %18
+         %21 = OpLoad %7 %20
+         %24 = OpFOrdLessThan %23 %21 %22
+               OpSelectionMerge %28 None
+               OpBranchConditional %24 %27 %36
+         %27 = OpLabel
+               OpStore %26 %35
+               OpBranch %28
+         %36 = OpLabel
+               OpStore %26 %41
+               OpBranch %28
+         %28 = OpLabel
+         %68 = OpPhi %9 %35 %27 %41 %36
+         %43 = OpTranspose %9 %68
+         %44 = OpCompositeConstruct %10 %13 %43
+         %71 = OpCompositeExtract %6 %44 0
+               OpStore %69 %71
+         %72 = OpCompositeExtract %9 %44 1
+               OpStore %70 %72
+         %51 = OpConvertSToF %7 %71
+         %73 = OpAccessChain %52 %70 %47 %18
+         %77 = OpLoad %9 %70
+         %54 = OpCompositeExtract %7 %77 0 0
+         %74 = OpAccessChain %52 %70 %13 %18
+         %78 = OpLoad %9 %70
+         %56 = OpCompositeExtract %7 %78 1 0
+         %57 = OpFAdd %7 %54 %56
+         %75 = OpAccessChain %52 %70 %47 %58
+         %79 = OpLoad %9 %70
+         %60 = OpCompositeExtract %7 %79 0 1
+         %76 = OpAccessChain %52 %70 %13 %58
+         %80 = OpLoad %9 %70
+         %62 = OpCompositeExtract %7 %80 1 1
+         %63 = OpFAdd %7 %60 %62
+         %66 = OpConvertSToF %7 %71
+         %67 = OpCompositeConstruct %14 %51 %57 %63 %66
+               OpStore %46 %67
+               OpReturn
+               OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/loop-dead-if-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loop-dead-if-loop.amber
new file mode 100644
index 0000000..0b629cb
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loop-dead-if-loop.amber
@@ -0,0 +1,266 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with a loop, dead if, and a loop
+
+# The test passes because the fragment shader contains two loops that do nothing (the if is never
+# entered) and finishes by writing red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#     for (
+#         int k = 0;
+#         k < 4;
+#         k++)
+#     {
+#
+#         if (0.0 > injectionSwitch.y) // always false
+#         {
+#             int donor_replacementGLF_dead0stack[10];
+#             int donor_replacementGLF_dead0top;
+#             for (
+#                 int GLF_dead0j = 1;
+#                 1 <= donor_replacementGLF_dead0stack[0];
+#                 1)
+#             {
+#             }
+#             donor_replacementGLF_dead0stack[donor_replacementGLF_dead0top >= 0 && donor_replacementGLF_dead0top < 9 ? ++donor_replacementGLF_dead0top : 0] = 1;
+#         }
+#
+#         vec4 matrix_b = vec4(0.0);
+#         for (
+#             int b = 3;
+#             b >= 0;
+#             b--)
+#         {
+#             matrix_b[b] = matrix_b[b] - 1.0;
+#         }
+#     }
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 90
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %88
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "k"
+               OpName %22 "buf0"
+               OpMemberName %22 0 "injectionSwitch"
+               OpName %24 ""
+               OpName %33 "GLF_dead0j"
+               OpName %43 "donor_replacementGLF_dead0stack"
+               OpName %47 "donor_replacementGLF_dead0top"
+               OpName %64 "matrix_b"
+               OpName %66 "b"
+               OpName %88 "_GLF_color"
+               OpDecorate %8 RelaxedPrecision
+               OpDecorate %15 RelaxedPrecision
+               OpMemberDecorate %22 0 Offset 0
+               OpDecorate %22 Block
+               OpDecorate %24 DescriptorSet 0
+               OpDecorate %24 Binding 0
+               OpDecorate %33 RelaxedPrecision
+               OpDecorate %43 RelaxedPrecision
+               OpDecorate %45 RelaxedPrecision
+               OpDecorate %47 RelaxedPrecision
+               OpDecorate %48 RelaxedPrecision
+               OpDecorate %50 RelaxedPrecision
+               OpDecorate %57 RelaxedPrecision
+               OpDecorate %58 RelaxedPrecision
+               OpDecorate %60 RelaxedPrecision
+               OpDecorate %66 RelaxedPrecision
+               OpDecorate %73 RelaxedPrecision
+               OpDecorate %75 RelaxedPrecision
+               OpDecorate %76 RelaxedPrecision
+               OpDecorate %83 RelaxedPrecision
+               OpDecorate %84 RelaxedPrecision
+               OpDecorate %85 RelaxedPrecision
+               OpDecorate %86 RelaxedPrecision
+               OpDecorate %88 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %9 = OpConstant %6 0
+         %16 = OpConstant %6 4
+         %17 = OpTypeBool
+         %19 = OpTypeFloat 32
+         %20 = OpConstant %19 0
+         %21 = OpTypeVector %19 2
+         %22 = OpTypeStruct %21
+         %23 = OpTypePointer Uniform %22
+         %24 = OpVariable %23 Uniform
+         %25 = OpTypeInt 32 0
+         %26 = OpConstant %25 1
+         %27 = OpTypePointer Uniform %19
+         %34 = OpConstant %6 1
+         %40 = OpConstant %25 10
+         %41 = OpTypeArray %6 %40
+         %42 = OpTypePointer Function %41
+         %51 = OpConstant %6 9
+         %62 = OpTypeVector %19 4
+         %63 = OpTypePointer Function %62
+         %65 = OpConstantComposite %62 %20 %20 %20 %20
+         %67 = OpConstant %6 3
+         %77 = OpTypePointer Function %19
+         %80 = OpConstant %19 1
+         %87 = OpTypePointer Output %62
+         %88 = OpVariable %87 Output
+         %89 = OpConstantComposite %62 %80 %20 %20 %80
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %8 = OpVariable %7 Function
+         %33 = OpVariable %7 Function
+         %43 = OpVariable %42 Function
+         %47 = OpVariable %7 Function
+         %54 = OpVariable %7 Function
+         %64 = OpVariable %63 Function
+         %66 = OpVariable %7 Function
+               OpStore %8 %9
+               OpBranch %10
+         %10 = OpLabel
+               OpLoopMerge %12 %13 None
+               OpBranch %14
+         %14 = OpLabel
+         %15 = OpLoad %6 %8
+         %18 = OpSLessThan %17 %15 %16
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+         %28 = OpAccessChain %27 %24 %9 %26
+         %29 = OpLoad %19 %28
+         %30 = OpFOrdGreaterThan %17 %20 %29
+               OpSelectionMerge %32 None
+               OpBranchConditional %30 %31 %32
+         %31 = OpLabel
+               OpStore %33 %34
+               OpBranch %35
+         %35 = OpLabel
+               OpLoopMerge %37 %38 None
+               OpBranch %39
+         %39 = OpLabel
+         %44 = OpAccessChain %7 %43 %9
+         %45 = OpLoad %6 %44
+         %46 = OpSLessThanEqual %17 %34 %45
+               OpBranchConditional %46 %36 %37
+         %36 = OpLabel
+               OpBranch %38
+         %38 = OpLabel
+               OpBranch %35
+         %37 = OpLabel
+         %48 = OpLoad %6 %47
+         %49 = OpSGreaterThanEqual %17 %48 %9
+         %50 = OpLoad %6 %47
+         %52 = OpSLessThan %17 %50 %51
+         %53 = OpLogicalAnd %17 %49 %52
+               OpSelectionMerge %56 None
+               OpBranchConditional %53 %55 %59
+         %55 = OpLabel
+         %57 = OpLoad %6 %47
+         %58 = OpIAdd %6 %57 %34
+               OpStore %47 %58
+               OpStore %54 %58
+               OpBranch %56
+         %59 = OpLabel
+               OpStore %54 %9
+               OpBranch %56
+         %56 = OpLabel
+         %60 = OpLoad %6 %54
+         %61 = OpAccessChain %7 %43 %60
+               OpStore %61 %34
+               OpBranch %32
+         %32 = OpLabel
+               OpStore %64 %65
+               OpStore %66 %67
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %70 %71 None
+               OpBranch %72
+         %72 = OpLabel
+         %73 = OpLoad %6 %66
+         %74 = OpSGreaterThanEqual %17 %73 %9
+               OpBranchConditional %74 %69 %70
+         %69 = OpLabel
+         %75 = OpLoad %6 %66
+         %76 = OpLoad %6 %66
+         %78 = OpAccessChain %77 %64 %76
+         %79 = OpLoad %19 %78
+         %81 = OpFSub %19 %79 %80
+         %82 = OpAccessChain %77 %64 %75
+               OpStore %82 %81
+               OpBranch %71
+         %71 = OpLabel
+         %83 = OpLoad %6 %66
+         %84 = OpISub %6 %83 %34
+               OpStore %66 %84
+               OpBranch %68
+         %70 = OpLabel
+               OpBranch %13
+         %13 = OpLabel
+         %85 = OpLoad %6 %8
+         %86 = OpIAdd %6 %85 %34
+               OpStore %8 %86
+               OpBranch %10
+         %12 = OpLabel
+               OpStore %88 %89
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-breaks-returns.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-breaks-returns.amber
new file mode 100644
index 0000000..4927d2a
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-breaks-returns.amber
@@ -0,0 +1,239 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A compute shader with loops, breaks, returns
+
+# The test passes because the shader immediately writes 42 to the 0th position
+# in the SSBO and that is the only thing we check. All loops terminate. All
+# other writes to the SSBO are at indices greater than 0.
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-dead-code-aggressive'
+# '--simplify-instructions'
+# '--redundancy-elimination'
+# '--copy-propagate-arrays'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--eliminate-local-multi-store'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-inserts'
+# '--eliminate-local-single-block'
+# '--redundancy-elimination'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 4a00a80c40484a6f6f72f48c9d34943cf8f180d4
+
+
+
+# variant_compute_shader is derived from the following GLSL:
+# #version 310 es
+#
+# layout(std430, binding = 0) buffer theSSBO
+# {
+#   uint data_out[5];
+# };
+#
+# layout(set = 0, binding = 1) uniform buf0 {
+#   vec2 injectionSwitch;
+# };
+#
+# layout(local_size_x = 100, local_size_y = 1, local_size_z = 1) in;
+#
+# void main()
+# {
+#   data_out[0] = 42u;
+#   uint gid = uint(injectionSwitch.y); // 1
+#   do
+#   {
+#     if (1u != gid) // always false
+#     {
+#       data_out[1] = 1u;
+#       return;
+#     }
+#   } while (false);
+#
+#   uint d;
+#   while (true)
+#   {
+#     if (d != 0u)
+#     {
+#       data_out[1] = 2u;
+#       for (int i = 0; i < 1; ++i)
+#       {
+#         data_out[1] = 3u;
+#         return;
+#       }
+#     }
+#     break;
+#   }
+#   data_out[gid] = 7u; // gid == 1
+# }
+SHADER compute variant_compute_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 86
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %4 "main"
+               OpExecutionMode %4 LocalSize 100 1 1
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "theSSBO"
+               OpMemberName %9 0 "data_out"
+               OpName %11 ""
+               OpName %18 "gid"
+               OpName %21 "buf0"
+               OpMemberName %21 0 "injectionSwitch"
+               OpName %23 ""
+               OpName %48 "d"
+               OpName %57 "i"
+               OpDecorate %8 ArrayStride 4
+               OpMemberDecorate %9 0 Offset 0
+               OpDecorate %9 BufferBlock
+               OpDecorate %11 DescriptorSet 0
+               OpDecorate %11 Binding 0
+               OpMemberDecorate %21 0 Offset 0
+               OpDecorate %21 Block
+               OpDecorate %23 DescriptorSet 0
+               OpDecorate %23 Binding 1
+               OpDecorate %76 BuiltIn WorkgroupSize
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 0
+          %7 = OpConstant %6 5
+          %8 = OpTypeArray %6 %7
+          %9 = OpTypeStruct %8
+         %10 = OpTypePointer Uniform %9
+         %11 = OpVariable %10 Uniform
+         %12 = OpTypeInt 32 1
+         %13 = OpConstant %12 0
+         %14 = OpConstant %6 42
+         %15 = OpTypePointer Uniform %6
+         %17 = OpTypePointer Function %6
+         %19 = OpTypeFloat 32
+         %20 = OpTypeVector %19 2
+         %21 = OpTypeStruct %20
+         %22 = OpTypePointer Uniform %21
+         %23 = OpVariable %22 Uniform
+         %24 = OpConstant %6 1
+         %25 = OpTypePointer Uniform %19
+         %34 = OpTypeBool
+         %38 = OpConstant %12 1
+         %41 = OpConstantFalse %34
+         %47 = OpConstantTrue %34
+         %50 = OpConstant %6 0
+         %54 = OpConstant %6 2
+         %56 = OpTypePointer Function %12
+         %65 = OpConstant %6 3
+         %72 = OpConstant %6 7
+         %74 = OpTypeVector %6 3
+         %75 = OpConstant %6 100
+         %76 = OpConstantComposite %74 %75 %24 %24
+         %80 = OpUndef %6
+         %85 = OpUndef %12
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %18 = OpVariable %17 Function
+         %48 = OpVariable %17 Function
+         %57 = OpVariable %56 Function
+         %16 = OpAccessChain %15 %11 %13 %13
+               OpStore %16 %14
+         %26 = OpAccessChain %25 %23 %13 %24
+         %27 = OpLoad %19 %26
+         %28 = OpConvertFToU %6 %27
+               OpStore %18 %28
+               OpBranch %29
+         %29 = OpLabel
+               OpLoopMerge %31 %32 None
+               OpBranch %30
+         %30 = OpLabel
+         %35 = OpINotEqual %34 %24 %28
+               OpSelectionMerge %37 None
+               OpBranchConditional %35 %36 %37
+         %36 = OpLabel
+         %39 = OpAccessChain %15 %11 %13 %38
+               OpStore %39 %24
+               OpReturn
+         %37 = OpLabel
+               OpBranch %32
+         %32 = OpLabel
+               OpBranchConditional %41 %29 %31
+         %31 = OpLabel
+               OpBranch %42
+         %42 = OpLabel
+               OpLoopMerge %44 %45 None
+               OpBranch %46
+         %46 = OpLabel
+               OpBranch %43
+         %43 = OpLabel
+         %51 = OpINotEqual %34 %80 %50
+               OpSelectionMerge %53 None
+               OpBranchConditional %51 %52 %53
+         %52 = OpLabel
+         %55 = OpAccessChain %15 %11 %13 %38
+               OpStore %55 %54
+               OpStore %57 %13
+               OpBranch %58
+         %58 = OpLabel
+               OpLoopMerge %60 %61 None
+               OpBranch %62
+         %62 = OpLabel
+         %64 = OpSLessThan %34 %13 %38
+               OpBranchConditional %64 %59 %60
+         %59 = OpLabel
+               OpStore %55 %65
+               OpReturn
+         %61 = OpLabel
+               OpBranch %58
+         %60 = OpLabel
+               OpBranch %53
+         %53 = OpLabel
+         %82 = OpPhi %6 %28 %43 %28 %60
+               OpBranch %44
+         %45 = OpLabel
+               OpBranch %42
+         %44 = OpLabel
+         %73 = OpAccessChain %15 %11 %13 %82
+               OpStore %73 %72
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_ssbo DATA_TYPE uint32 DATA
+ 0 0 0 0 0
+END
+
+PIPELINE compute variant_pipeline
+  ATTACH variant_compute_shader
+  BIND BUFFER variant_ssbo AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN variant_pipeline 1 1 1
+
+EXPECT variant_ssbo IDX 0 EQ 42
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-ifs-continues-call.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-ifs-continues-call.amber
new file mode 100644
index 0000000..bc4a692
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/loops-ifs-continues-call.amber
@@ -0,0 +1,294 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with nested control flow and a call
+
+# The test passes because all loops terminate or are not entered and the shader ends by writing red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct BinarySearchObject
+# {
+#   int prime_numbers[10];
+# };
+#
+# int binarySearch(BinarySearchObject obj)
+# {
+#   while (injectionSwitch.x > 1.0) // always false
+#   {
+#     int m = int(injectionSwitch.x);
+#     if (obj.prime_numbers[m] == 1)
+#     {
+#       return 1;
+#     }
+#   }
+#   return 1;
+# }
+#
+# void main()
+# {
+#   BinarySearchObject obj;
+#   for (
+#       int i = 0;
+#       i < 10;
+#       i++)
+#   {
+#     if (i != 3)
+#     {
+#       if ((i - int(injectionSwitch.x)) == 4)
+#       {
+#         obj.prime_numbers[i] = 11;
+#       }
+#       else
+#       {
+#         if (i == 6)
+#         {
+#           obj.prime_numbers[i] = 17;
+#         }
+#         continue;
+#       }
+#     }
+#     do
+#     {
+#     } while (0.0 > injectionSwitch.y); // always false
+#   }
+#   binarySearch(obj);
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 104
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %102
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %10 "BinarySearchObject"
+               OpMemberName %10 0 "prime_numbers"
+               OpName %14 "binarySearch(struct-BinarySearchObject-i1[10]1;"
+               OpName %13 "obj"
+               OpName %23 "buf0"
+               OpMemberName %23 0 "injectionSwitch"
+               OpName %25 ""
+               OpName %35 "m"
+               OpName %49 "i"
+               OpName %72 "obj"
+               OpName %97 "param"
+               OpName %102 "_GLF_color"
+               OpMemberDecorate %10 0 RelaxedPrecision
+               OpDecorate %14 RelaxedPrecision
+               OpMemberDecorate %23 0 Offset 0
+               OpDecorate %23 Block
+               OpDecorate %25 DescriptorSet 0
+               OpDecorate %25 Binding 0
+               OpDecorate %35 RelaxedPrecision
+               OpDecorate %38 RelaxedPrecision
+               OpDecorate %39 RelaxedPrecision
+               OpDecorate %41 RelaxedPrecision
+               OpDecorate %49 RelaxedPrecision
+               OpDecorate %55 RelaxedPrecision
+               OpDecorate %58 RelaxedPrecision
+               OpDecorate %63 RelaxedPrecision
+               OpDecorate %66 RelaxedPrecision
+               OpDecorate %67 RelaxedPrecision
+               OpDecorate %73 RelaxedPrecision
+               OpDecorate %77 RelaxedPrecision
+               OpDecorate %82 RelaxedPrecision
+               OpDecorate %95 RelaxedPrecision
+               OpDecorate %96 RelaxedPrecision
+               OpDecorate %99 RelaxedPrecision
+               OpDecorate %102 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeInt 32 0
+          %8 = OpConstant %7 10
+          %9 = OpTypeArray %6 %8
+         %10 = OpTypeStruct %9
+         %11 = OpTypePointer Function %10
+         %12 = OpTypeFunction %6 %11
+         %21 = OpTypeFloat 32
+         %22 = OpTypeVector %21 2
+         %23 = OpTypeStruct %22
+         %24 = OpTypePointer Uniform %23
+         %25 = OpVariable %24 Uniform
+         %26 = OpConstant %6 0
+         %27 = OpConstant %7 0
+         %28 = OpTypePointer Uniform %21
+         %31 = OpConstant %21 1
+         %32 = OpTypeBool
+         %34 = OpTypePointer Function %6
+         %42 = OpConstant %6 1
+         %56 = OpConstant %6 10
+         %59 = OpConstant %6 3
+         %68 = OpConstant %6 4
+         %74 = OpConstant %6 11
+         %78 = OpConstant %6 6
+         %83 = OpConstant %6 17
+         %90 = OpConstant %21 0
+         %91 = OpConstant %7 1
+        %100 = OpTypeVector %21 4
+        %101 = OpTypePointer Output %100
+        %102 = OpVariable %101 Output
+        %103 = OpConstantComposite %100 %31 %90 %90 %31
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %49 = OpVariable %34 Function
+         %72 = OpVariable %11 Function
+         %97 = OpVariable %11 Function
+               OpStore %49 %26
+               OpBranch %50
+         %50 = OpLabel
+               OpLoopMerge %52 %53 None
+               OpBranch %54
+         %54 = OpLabel
+         %55 = OpLoad %6 %49
+         %57 = OpSLessThan %32 %55 %56
+               OpBranchConditional %57 %51 %52
+         %51 = OpLabel
+         %58 = OpLoad %6 %49
+         %60 = OpINotEqual %32 %58 %59
+               OpSelectionMerge %62 None
+               OpBranchConditional %60 %61 %62
+         %61 = OpLabel
+         %63 = OpLoad %6 %49
+         %64 = OpAccessChain %28 %25 %26 %27
+         %65 = OpLoad %21 %64
+         %66 = OpConvertFToS %6 %65
+         %67 = OpISub %6 %63 %66
+         %69 = OpIEqual %32 %67 %68
+               OpSelectionMerge %71 None
+               OpBranchConditional %69 %70 %76
+         %70 = OpLabel
+         %73 = OpLoad %6 %49
+         %75 = OpAccessChain %34 %72 %26 %73
+               OpStore %75 %74
+               OpBranch %71
+         %76 = OpLabel
+         %77 = OpLoad %6 %49
+         %79 = OpIEqual %32 %77 %78
+               OpSelectionMerge %81 None
+               OpBranchConditional %79 %80 %81
+         %80 = OpLabel
+         %82 = OpLoad %6 %49
+         %84 = OpAccessChain %34 %72 %26 %82
+               OpStore %84 %83
+               OpBranch %81
+         %81 = OpLabel
+               OpBranch %53
+         %71 = OpLabel
+               OpBranch %62
+         %62 = OpLabel
+               OpBranch %86
+         %86 = OpLabel
+               OpLoopMerge %88 %89 None
+               OpBranch %87
+         %87 = OpLabel
+               OpBranch %89
+         %89 = OpLabel
+         %92 = OpAccessChain %28 %25 %26 %91
+         %93 = OpLoad %21 %92
+         %94 = OpFOrdGreaterThan %32 %90 %93
+               OpBranchConditional %94 %86 %88
+         %88 = OpLabel
+               OpBranch %53
+         %53 = OpLabel
+         %95 = OpLoad %6 %49
+         %96 = OpIAdd %6 %95 %42
+               OpStore %49 %96
+               OpBranch %50
+         %52 = OpLabel
+         %98 = OpLoad %10 %72
+               OpStore %97 %98
+         %99 = OpFunctionCall %6 %14 %97
+               OpStore %102 %103
+               OpReturn
+               OpFunctionEnd
+         %14 = OpFunction %6 None %12
+         %13 = OpFunctionParameter %11
+         %15 = OpLabel
+         %35 = OpVariable %34 Function
+               OpBranch %16
+         %16 = OpLabel
+               OpLoopMerge %18 %19 None
+               OpBranch %20
+         %20 = OpLabel
+         %29 = OpAccessChain %28 %25 %26 %27
+         %30 = OpLoad %21 %29
+         %33 = OpFOrdGreaterThan %32 %30 %31
+               OpBranchConditional %33 %17 %18
+         %17 = OpLabel
+         %36 = OpAccessChain %28 %25 %26 %27
+         %37 = OpLoad %21 %36
+         %38 = OpConvertFToS %6 %37
+               OpStore %35 %38
+         %39 = OpLoad %6 %35
+         %40 = OpAccessChain %34 %13 %26 %39
+         %41 = OpLoad %6 %40
+         %43 = OpIEqual %32 %41 %42
+               OpSelectionMerge %45 None
+               OpBranchConditional %43 %44 %45
+         %44 = OpLabel
+               OpReturnValue %42
+         %45 = OpLabel
+               OpBranch %19
+         %19 = OpLabel
+               OpBranch %16
+         %18 = OpLabel
+               OpReturnValue %42
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/mat-mul-in-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/mat-mul-in-loop.amber
new file mode 100644
index 0000000..304a305
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/mat-mul-in-loop.amber
@@ -0,0 +1,175 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Shader with matrix multiplication in loop
+
+# The test passes because 'm1' is the identity matrix, so that 'm2' is also the identity matrix, meaning that 'v' gets set to '(1.0, 0.0)'.  As a result, the colour that is written is guaranteed to be red
+
+# Optimized using spirv-opt with the following arguments:
+# '--simplify-instructions'
+# '--combine-access-chains'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--combine-access-chains'
+# '--eliminate-dead-code-aggressive'
+# '--reduce-load-size'
+# '--eliminate-local-single-block'
+# '--private-to-local'
+# '--inline-entry-points-exhaustive'
+# '--copy-propagate-arrays'
+# '--eliminate-local-multi-store'
+# '--scalar-replacement=100'
+# '--eliminate-dead-branches'
+# '--eliminate-local-single-store'
+# spirv-opt commit hash: f1e5cd73f658abcc23ee96d78f2dc27c4b7028c1
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main(void)
+# {
+#  vec2 v;
+#  mat2 m1 = mat2(1.0, 0.0, 0.0, 1.0);
+#  for(
+#      int i = 0;
+#      i < 1;
+#      i++
+#  )
+#   {
+#    do
+#     {
+#      mat2 m2;
+#      m2 = m1 * m1;
+#      v = m2 * vec2(1.0, 0.0);
+#     }
+#    while(false);
+#   }
+#   _GLF_color = vec4(v, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 56
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %46
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %10 "m1"
+               OpName %18 "i"
+               OpName %33 "m2"
+               OpName %38 "v"
+               OpName %46 "_GLF_color"
+               OpDecorate %46 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypeMatrix %7 2
+          %9 = OpTypePointer Function %8
+         %11 = OpConstant %6 1
+         %12 = OpConstant %6 0
+         %13 = OpConstantComposite %7 %11 %12
+         %14 = OpConstantComposite %7 %12 %11
+         %15 = OpConstantComposite %8 %13 %14
+         %16 = OpTypeInt 32 1
+         %17 = OpTypePointer Function %16
+         %19 = OpConstant %16 0
+         %26 = OpConstant %16 1
+         %27 = OpTypeBool
+         %37 = OpTypePointer Function %7
+         %41 = OpConstantFalse %27
+         %44 = OpTypeVector %6 4
+         %45 = OpTypePointer Output %44
+         %46 = OpVariable %45 Output
+         %53 = OpUndef %7
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %10 = OpVariable %9 Function
+         %18 = OpVariable %17 Function
+         %33 = OpVariable %9 Function
+         %38 = OpVariable %37 Function
+               OpStore %10 %15
+               OpStore %18 %19
+               OpBranch %20
+         %20 = OpLabel
+         %55 = OpPhi %8 %15 %5 %55 %23
+         %52 = OpPhi %7 %53 %5 %40 %23
+         %51 = OpPhi %16 %19 %5 %43 %23
+               OpLoopMerge %22 %23 None
+               OpBranch %24
+         %24 = OpLabel
+         %28 = OpSLessThan %27 %51 %26
+               OpBranchConditional %28 %21 %22
+         %21 = OpLabel
+               OpBranch %29
+         %29 = OpLabel
+               OpLoopMerge %31 %32 None
+               OpBranch %30
+         %30 = OpLabel
+         %36 = OpMatrixTimesMatrix %8 %55 %55
+               OpStore %33 %36
+         %40 = OpMatrixTimesVector %7 %36 %13
+               OpStore %38 %40
+               OpBranch %32
+         %32 = OpLabel
+               OpBranchConditional %41 %29 %31
+         %31 = OpLabel
+               OpBranch %23
+         %23 = OpLabel
+         %43 = OpIAdd %16 %51 %26
+               OpStore %18 %43
+               OpBranch %20
+         %22 = OpLabel
+         %48 = OpCompositeExtract %6 %52 0
+         %49 = OpCompositeExtract %6 %52 1
+         %50 = OpCompositeConstruct %44 %48 %49 %12 %11
+               OpStore %46 %50
+               OpReturn
+               OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-gl-color.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-gl-color.amber
new file mode 100644
index 0000000..83bfd91
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-gl-color.amber
@@ -0,0 +1,85 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with modf of gl color
+
+# The test passes because the shader writes the color red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#     modf(vec4(1.0, 0.0, 0.0, 1.0), _GLF_color);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 14
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %12
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %12 "_GLF_color"
+               OpDecorate %12 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpConstant %6 1
+          %9 = OpConstant %6 0
+         %10 = OpConstantComposite %7 %8 %9 %9 %8
+         %11 = OpTypePointer Output %7
+         %12 = OpVariable %11 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %13 = OpExtInst %7 %1 Modf %10 %12
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-temp-modf-color.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-temp-modf-color.amber
new file mode 100644
index 0000000..d9c5d2d
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/modf-temp-modf-color.amber
@@ -0,0 +1,90 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that calls modf twice, once with color
+
+# The test passes because the shader always writes the color red using modf.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#     vec4 temp;
+#     modf(vec4(1.0), temp);
+#     modf(vec4(1.0, 0.0, 0.0, 1.0), _GLF_color);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 18
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %16
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %11 "temp"
+               OpName %16 "_GLF_color"
+               OpDecorate %16 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpConstant %6 1
+          %9 = OpConstantComposite %7 %8 %8 %8 %8
+         %10 = OpTypePointer Function %7
+         %13 = OpConstant %6 0
+         %14 = OpConstantComposite %7 %8 %13 %13 %8
+         %15 = OpTypePointer Output %7
+         %16 = OpVariable %15 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %11 = OpVariable %10 Function
+         %12 = OpExtInst %7 %1 Modf %9 %11
+         %17 = OpExtInst %7 %1 Modf %14 %16
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-before-writing-wrong-color.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-before-writing-wrong-color.amber
new file mode 100644
index 0000000..57cc8a2
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-before-writing-wrong-color.amber
@@ -0,0 +1,162 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with return before writing wrong color
+
+# The test passes because the shader always writes color red.
+# Main writes red and returns. Code after writing red is never executed.
+
+# Optimized using spirv-opt with the following arguments:
+# '--private-to-local'
+# '--eliminate-local-multi-store'
+# '--redundancy-elimination'
+# '--eliminate-dead-code-aggressive'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--reduce-load-size'
+# '--combine-access-chains'
+# '--combine-access-chains'
+# '--eliminate-dead-branches'
+# '--ccp'
+# '--redundancy-elimination'
+# '--simplify-instructions'
+# '--vector-dce'
+# '--ccp'
+# '--private-to-local'
+# '--eliminate-dead-inserts'
+# spirv-opt commit hash: ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# struct _GLF_struct_0
+# {
+#   int msb9;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   _GLF_struct_0 _GLF_struct_replacement_0;
+#
+#   do
+#   {
+#     for (int j = 0; 1 < findLSB(1024); 1)
+#     {
+#       _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#       return; // We always return here. The code below is never executed.
+#     }
+#   } while (_GLF_struct_replacement_0.msb9 > 1);
+#   _GLF_color = vec4(1.0, 1.0, _GLF_struct_replacement_0.msb9, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 43
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %27
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %27 "_GLF_color"
+               OpName %32 "_GLF_struct_0"
+               OpMemberName %32 0 "msb9"
+               OpName %34 "_GLF_struct_replacement_0"
+               OpDecorate %21 RelaxedPrecision
+               OpDecorate %27 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+         %10 = OpTypeInt 32 1
+         %11 = OpTypePointer Function %10
+         %13 = OpConstant %10 0
+         %19 = OpConstant %10 1
+         %20 = OpConstant %10 1024
+         %22 = OpTypeBool
+         %24 = OpTypeFloat 32
+         %25 = OpTypeVector %24 4
+         %26 = OpTypePointer Output %25
+         %27 = OpVariable %26 Output
+         %28 = OpConstant %24 1
+         %29 = OpConstant %24 0
+         %30 = OpConstantComposite %25 %28 %29 %29 %28
+         %32 = OpTypeStruct %10
+         %33 = OpTypePointer Function %32
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %34 = OpVariable %33 Function
+               OpBranch %6
+          %6 = OpLabel
+               OpLoopMerge %8 %16 None
+               OpBranch %14
+         %14 = OpLabel
+         %21 = OpExtInst %10 %1 FindILsb %20
+         %23 = OpSLessThan %22 %19 %21
+               OpLoopMerge %42 %17 None
+               OpBranchConditional %23 %15 %42
+         %15 = OpLabel
+               OpStore %27 %30
+               OpReturn
+         %17 = OpLabel
+               OpBranch %14
+         %42 = OpLabel
+               OpBranch %16
+         %16 = OpLabel
+         %35 = OpAccessChain %11 %34 %13
+         %36 = OpLoad %10 %35
+         %37 = OpSGreaterThan %22 %36 %19
+               OpBranchConditional %37 %6 %8
+          %8 = OpLabel
+         %39 = OpLoad %10 %35
+         %40 = OpConvertSToF %24 %39
+         %41 = OpCompositeConstruct %25 %28 %28 %40 %28
+               OpStore %27 %41
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-float-from-while-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-float-from-while-loop.amber
new file mode 100644
index 0000000..61660fa
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/return-float-from-while-loop.amber
@@ -0,0 +1,190 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with unreachable while loop
+
+# The test passes because the shader always writes the color red.
+# The rest of the code is never reached.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# float deadCode()
+# {
+#     float s;
+#     for (int i = 1; true; 1)
+#     {
+#         if (gl_FragCoord.x < 0.0)
+#         {
+#             if (injectionSwitch.x > 1.0)
+#             {
+#                 return 1.0;
+#             }
+#             continue;
+#         }
+#         return s;
+#     }
+#     return 1.0;
+# }
+#
+# void main()
+# {
+#     if (injectionSwitch.x > 1.0) // Always false
+#     {
+#         vec4 c;
+#         c.y = deadCode();
+#         _GLF_color = c;
+#     }
+#
+#     // Always write color red because the other code is never reached.
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 120
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %23 %64
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %23 "gl_FragCoord"
+               OpName %34 "buf0"
+               OpMemberName %34 0 "injectionSwitch"
+               OpName %36 ""
+               OpName %64 "_GLF_color"
+               OpDecorate %23 BuiltIn FragCoord
+               OpMemberDecorate %34 0 Offset 0
+               OpDecorate %34 Block
+               OpDecorate %36 DescriptorSet 0
+               OpDecorate %36 Binding 0
+               OpDecorate %64 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+         %10 = OpTypeInt 32 1
+         %19 = OpTypeBool
+         %21 = OpTypeVector %6 4
+         %22 = OpTypePointer Input %21
+         %23 = OpVariable %22 Input
+         %24 = OpTypeInt 32 0
+         %25 = OpConstant %24 0
+         %26 = OpTypePointer Input %6
+         %29 = OpConstant %6 0
+         %33 = OpTypeVector %6 2
+         %34 = OpTypeStruct %33
+         %35 = OpTypePointer Uniform %34
+         %36 = OpVariable %35 Uniform
+         %37 = OpConstant %10 0
+         %38 = OpTypePointer Uniform %6
+         %41 = OpConstant %6 1
+         %63 = OpTypePointer Output %21
+         %64 = OpVariable %63 Output
+         %66 = OpConstantComposite %21 %41 %29 %29 %41
+        %110 = OpUndef %6
+        %118 = OpUndef %21
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %53 = OpAccessChain %38 %36 %37 %25
+         %54 = OpLoad %6 %53
+         %55 = OpFOrdGreaterThan %19 %54 %41
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %56 %57
+         %56 = OpLabel
+               OpBranch %83
+         %83 = OpLabel
+               OpLoopMerge %84 %85 None
+               OpBranch %87
+         %87 = OpLabel
+               OpLoopMerge %88 %100 None
+               OpBranch %91
+         %91 = OpLabel
+         %92 = OpAccessChain %26 %23 %25
+         %93 = OpLoad %6 %92
+         %94 = OpFOrdLessThan %19 %93 %29
+               OpSelectionMerge %95 None
+               OpBranchConditional %94 %96 %95
+         %96 = OpLabel
+               OpSelectionMerge %119 None
+               OpBranchConditional %55 %101 %100
+        %101 = OpLabel
+               OpBranch %88
+        %119 = OpLabel
+               OpBranch %100
+        %100 = OpLabel
+               OpBranch %87
+         %95 = OpLabel
+               OpBranch %88
+         %88 = OpLabel
+        %113 = OpPhi %6 %41 %101 %110 %95
+               OpBranch %84
+         %85 = OpLabel
+               OpBranch %83
+         %84 = OpLabel
+        %107 = OpCompositeInsert %21 %113 %118 1
+               OpStore %64 %107
+               OpBranch %57
+         %57 = OpLabel
+               OpStore %64 %66
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/returned-boolean-in-vector.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/returned-boolean-in-vector.amber
new file mode 100644
index 0000000..09c6913
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/returned-boolean-in-vector.amber
@@ -0,0 +1,231 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with returned boolean in vector
+
+# The test passes because the shader always writes the color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--inline-entry-points-exhaustive'
+# '--vector-dce'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--vector-dce'
+# '--eliminate-dead-code-aggressive'
+# '--scalar-replacement=100'
+# '--eliminate-dead-branches'
+# '--reduce-load-size'
+# '--eliminate-local-multi-store'
+# '--ccp'
+# spirv-opt commit hash: ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+#
+# bool puzzlelize()
+# {
+#   for (int i = 0; i < 1; i++)
+#   {
+#     return true;
+#   }
+# }
+# void main()
+# {
+#   vec2 uv;
+#   vec3 color;
+#
+#   do
+#   {
+#     if (injectionSwitch.y < 0.0)
+#     {
+#       color = vec3(1.0);
+#     }
+#   } while (false);
+#   _GLF_color = vec4(color, 1.0) + vec4(puzzlelize());
+#
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 108
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %53
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %33 "buf0"
+               OpMemberName %33 0 "injectionSwitch"
+               OpName %35 ""
+               OpName %47 "color"
+               OpName %53 "_GLF_color"
+               OpMemberDecorate %33 0 Offset 0
+               OpDecorate %33 Block
+               OpDecorate %35 DescriptorSet 0
+               OpDecorate %35 Binding 0
+               OpDecorate %53 Location 0
+               OpDecorate %76 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeBool
+         %10 = OpTypeInt 32 1
+         %11 = OpTypePointer Function %10
+         %13 = OpConstant %10 0
+         %20 = OpConstant %10 1
+         %22 = OpConstantTrue %6
+         %31 = OpTypeFloat 32
+         %32 = OpTypeVector %31 2
+         %33 = OpTypeStruct %32
+         %34 = OpTypePointer Uniform %33
+         %35 = OpVariable %34 Uniform
+         %36 = OpTypeInt 32 0
+         %37 = OpConstant %36 1
+         %38 = OpTypePointer Uniform %31
+         %41 = OpConstant %31 0
+         %45 = OpTypeVector %31 3
+         %46 = OpTypePointer Function %45
+         %48 = OpConstant %31 1
+         %49 = OpConstantComposite %45 %48 %48 %48
+         %50 = OpConstantFalse %6
+         %51 = OpTypeVector %31 4
+         %52 = OpTypePointer Output %51
+         %53 = OpVariable %52 Output
+         %63 = OpConstantComposite %51 %48 %41 %41 %48
+         %65 = OpTypePointer Function %6
+         %95 = OpUndef %45
+        %106 = OpUndef %6
+        %107 = OpUndef %10
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %74 = OpVariable %65 Function %50
+         %75 = OpVariable %65 Function
+         %76 = OpVariable %11 Function
+         %77 = OpVariable %65 Function
+         %47 = OpVariable %46 Function
+               OpBranch %27
+         %27 = OpLabel
+        %105 = OpPhi %6 %106 %5 %105 %30
+         %94 = OpPhi %45 %95 %5 %93 %30
+               OpLoopMerge %29 %30 None
+               OpBranch %28
+         %28 = OpLabel
+         %39 = OpAccessChain %38 %35 %13 %37
+         %40 = OpLoad %31 %39
+         %42 = OpFOrdLessThan %6 %40 %41
+               OpSelectionMerge %44 None
+               OpBranchConditional %42 %43 %44
+         %43 = OpLabel
+               OpStore %47 %49
+               OpBranch %44
+         %44 = OpLabel
+         %93 = OpPhi %45 %94 %28 %49 %43
+               OpBranch %30
+         %30 = OpLabel
+               OpBranchConditional %50 %27 %29
+         %29 = OpLabel
+         %55 = OpCompositeExtract %31 %93 0
+         %56 = OpCompositeExtract %31 %93 1
+         %57 = OpCompositeExtract %31 %93 2
+         %58 = OpCompositeConstruct %51 %55 %56 %57 %48
+               OpStore %74 %50
+               OpBranch %78
+         %78 = OpLabel
+        %103 = OpPhi %6 %105 %29 %106 %80
+         %99 = OpPhi %6 %50 %29 %106 %80
+               OpLoopMerge %79 %80 None
+               OpBranch %81
+         %81 = OpLabel
+               OpStore %76 %13
+               OpBranch %82
+         %82 = OpLabel
+        %102 = OpPhi %6 %103 %81 %106 %84
+         %98 = OpPhi %6 %50 %81 %106 %84
+         %96 = OpPhi %10 %13 %81 %107 %84
+               OpLoopMerge %83 %84 None
+               OpBranch %85
+         %85 = OpLabel
+         %87 = OpSLessThan %6 %13 %20
+               OpBranchConditional %22 %88 %83
+         %88 = OpLabel
+               OpStore %74 %22
+               OpStore %75 %22
+               OpBranch %83
+         %84 = OpLabel
+               OpBranch %82
+         %83 = OpLabel
+        %101 = OpPhi %6 %102 %85 %22 %88
+         %97 = OpPhi %6 %50 %85 %22 %88
+               OpSelectionMerge %90 None
+               OpBranchConditional %22 %79 %90
+         %90 = OpLabel
+               OpStore %74 %22
+               OpBranch %79
+         %80 = OpLabel
+               OpBranch %78
+         %79 = OpLabel
+               OpStore %77 %22
+         %60 = OpSelect %31 %22 %48 %41
+         %61 = OpCompositeConstruct %51 %60 %60 %60 %60
+         %62 = OpFAdd %51 %58 %61
+               OpStore %53 %62
+               OpStore %53 %63
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/smoothstep-after-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/smoothstep-after-loop.amber
new file mode 100644
index 0000000..6408240
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/smoothstep-after-loop.amber
@@ -0,0 +1,130 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Fragment shader with 1-iteration loop and smoothstep
+
+# The test passes because the loop exits immediately and red is written
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  while(true)
+#   {
+#    if(true)
+#     {
+#      break;
+#     }
+#    int GLF_live9r;
+#    vec2(1.0)[clamp(GLF_live9r, 0, 1)];
+#   }
+#  float g = 3.0;
+#  _GLF_color = vec4(smoothstep(0.0, 1.0, g), 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %32
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %22 "GLF_live9r"
+               OpName %28 "g"
+               OpName %32 "_GLF_color"
+               OpDecorate %32 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+         %11 = OpTypeBool
+         %12 = OpConstantTrue %11
+         %16 = OpTypeFloat 32
+         %17 = OpTypeVector %16 2
+         %18 = OpConstant %16 1
+         %19 = OpConstantComposite %17 %18 %18
+         %20 = OpTypeInt 32 1
+         %21 = OpTypePointer Function %20
+         %24 = OpConstant %20 0
+         %25 = OpConstant %20 1
+         %27 = OpTypePointer Function %16
+         %29 = OpConstant %16 3
+         %30 = OpTypeVector %16 4
+         %31 = OpTypePointer Output %30
+         %32 = OpVariable %31 Output
+         %33 = OpConstant %16 0
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %22 = OpVariable %21 Function
+         %28 = OpVariable %27 Function
+               OpBranch %6
+          %6 = OpLabel
+               OpLoopMerge %8 %9 None
+               OpBranch %10
+         %10 = OpLabel
+               OpBranchConditional %12 %7 %8
+          %7 = OpLabel
+               OpSelectionMerge %14 None
+               OpBranchConditional %12 %13 %14
+         %13 = OpLabel
+               OpBranch %8
+         %14 = OpLabel
+         %23 = OpLoad %20 %22
+         %26 = OpExtInst %20 %1 SClamp %23 %24 %25
+               OpBranch %9
+          %9 = OpLabel
+               OpBranch %6
+          %8 = OpLabel
+               OpStore %28 %29
+         %34 = OpLoad %16 %28
+         %35 = OpExtInst %16 %1 SmoothStep %33 %18 %34
+         %36 = OpCompositeConstruct %30 %35 %33 %33 %18
+               OpStore %32 %36
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-and-unreachable-infinite-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-and-unreachable-infinite-loop.amber
new file mode 100644
index 0000000..d72b4d3
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-and-unreachable-infinite-loop.amber
@@ -0,0 +1,207 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Fragment shader with struct and unreachable infinite loop
+
+# The test passes because 'tree[0].rightIndex' is set to 1, so that the infinite loop is not reached and the output colour red is written
+
+# Optimized using spirv-opt with the following arguments:
+# '--redundancy-elimination'
+# '--eliminate-dead-inserts'
+# '--combine-access-chains'
+# '--vector-dce'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--private-to-local'
+# '--simplify-instructions'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-local-multi-store'
+# '--eliminate-local-single-store'
+# '--eliminate-local-single-block'
+# '--simplify-instructions'
+# '--copy-propagate-arrays'
+# '--vector-dce'
+# '--simplify-instructions'
+# '--reduce-load-size'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--redundancy-elimination'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--private-to-local'
+# '--vector-dce'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--private-to-local'
+# '--private-to-local'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# struct BST {
+#  int data;
+#  int leftIndex;
+#  int rightIndex;
+# } ;
+#
+# BST tree[10];
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void makeTreeNode(inout BST tree)
+# {
+#  tree.rightIndex = 1;
+# }
+# void main()
+# {
+#  makeTreeNode(tree[0]);
+#  if (tree[0].rightIndex == 0) {
+#    while(true)
+#     {
+#     }
+#  }
+#
+#  _GLF_color = vec4(float(tree[0].rightIndex), 0.0, 0.0, 1.0);
+#
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 59
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %46
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %7 "BST"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %11 "makeTreeNode(struct-BST-i1-i1-i11;"
+               OpName %10 "tree"
+               OpName %21 "tree"
+               OpName %23 "param"
+               OpName %46 "_GLF_color"
+               OpMemberDecorate %7 0 RelaxedPrecision
+               OpMemberDecorate %7 1 RelaxedPrecision
+               OpMemberDecorate %7 2 RelaxedPrecision
+               OpDecorate %32 RelaxedPrecision
+               OpDecorate %46 Location 0
+               OpDecorate %48 RelaxedPrecision
+               OpDecorate %57 RelaxedPrecision
+               OpDecorate %58 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %2 %8
+         %13 = OpConstant %6 2
+         %14 = OpConstant %6 1
+         %15 = OpTypePointer Function %6
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 10
+         %19 = OpTypeArray %7 %18
+         %20 = OpTypePointer Private %19
+         %22 = OpConstant %6 0
+         %24 = OpTypePointer Private %7
+         %30 = OpTypePointer Private %6
+         %33 = OpTypeBool
+         %42 = OpConstantTrue %33
+         %43 = OpTypeFloat 32
+         %44 = OpTypeVector %43 4
+         %45 = OpTypePointer Output %44
+         %46 = OpVariable %45 Output
+         %50 = OpConstant %43 0
+         %51 = OpConstant %43 1
+         %53 = OpTypePointer Function %19
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %21 = OpVariable %53 Function
+         %23 = OpVariable %8 Function
+         %54 = OpLoad %19 %21
+         %26 = OpCompositeExtract %7 %54 0
+               OpStore %23 %26
+         %27 = OpFunctionCall %2 %11 %23
+         %28 = OpLoad %7 %23
+         %55 = OpLoad %19 %21
+         %56 = OpCompositeInsert %19 %28 %55 0
+               OpStore %21 %56
+         %31 = OpAccessChain %15 %21 %22 %13
+         %57 = OpLoad %19 %21
+         %32 = OpCompositeExtract %6 %57 0 2
+         %34 = OpIEqual %33 %32 %22
+               OpSelectionMerge %36 None
+               OpBranchConditional %34 %35 %36
+         %35 = OpLabel
+               OpBranch %37
+         %37 = OpLabel
+               OpLoopMerge %39 %37 None
+               OpBranch %37
+         %39 = OpLabel
+               OpUnreachable
+         %36 = OpLabel
+         %58 = OpLoad %19 %21
+         %48 = OpCompositeExtract %6 %58 0 2
+         %49 = OpConvertSToF %43 %48
+         %52 = OpCompositeConstruct %44 %49 %50 %50 %51
+               OpStore %46 %52
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %2 None %9
+         %10 = OpFunctionParameter %8
+         %12 = OpLabel
+         %16 = OpAccessChain %15 %10 %13
+               OpStore %16 %14
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-controlled-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-controlled-loop.amber
new file mode 100644
index 0000000..0161d53
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-controlled-loop.amber
@@ -0,0 +1,207 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Shader with loop controlled by struct
+
+# The test passes because 'sums[0]' ends up being 0, so that the colour that is written is guaranteed to be red
+
+# Optimized using spirv-opt with the following arguments:
+# '--private-to-local'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--reduce-load-size'
+# '--eliminate-dead-code-aggressive'
+# '--ccp'
+# '--eliminate-dead-code-aggressive'
+# '--if-conversion'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-local-single-store'
+# '--ccp'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-local-single-store'
+# '--eliminate-dead-inserts'
+# '--eliminate-local-multi-store'
+# '--copy-propagate-arrays'
+# '--combine-access-chains'
+# '--redundancy-elimination'
+# '--if-conversion'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-code-aggressive'
+# spirv-opt commit hash: f1e5cd73f658abcc23ee96d78f2dc27c4b7028c1
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# struct S {
+#  int f0;
+#  bvec3 f1;
+# } ;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  float sums[9];
+#  for(
+#      S ll = S(0, bvec3(true));
+#      ll.f0 != int((injectionSwitch.y));
+#      ll.f0 ++
+#  )
+#   {
+#    sums[0] = 0.0;
+#   }
+#  int overall_region = 0;
+#  _GLF_color = vec4(1.0, vec2(sums[overall_region]), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 63
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %50
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "S"
+               OpMemberName %9 0 "f0"
+               OpMemberName %9 1 "f1"
+               OpName %11 "ll"
+               OpName %26 "buf0"
+               OpMemberName %26 0 "injectionSwitch"
+               OpName %28 ""
+               OpName %39 "sums"
+               OpName %50 "_GLF_color"
+               OpMemberDecorate %9 0 RelaxedPrecision
+               OpDecorate %23 RelaxedPrecision
+               OpMemberDecorate %26 0 Offset 0
+               OpDecorate %26 Block
+               OpDecorate %28 DescriptorSet 0
+               OpDecorate %28 Binding 0
+               OpDecorate %44 RelaxedPrecision
+               OpDecorate %46 RelaxedPrecision
+               OpDecorate %50 Location 0
+               OpDecorate %59 RelaxedPrecision
+               OpDecorate %60 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeBool
+          %8 = OpTypeVector %7 3
+          %9 = OpTypeStruct %6 %8
+         %10 = OpTypePointer Function %9
+         %12 = OpConstant %6 0
+         %13 = OpConstantTrue %7
+         %14 = OpConstantComposite %8 %13 %13 %13
+         %15 = OpConstantComposite %9 %12 %14
+         %24 = OpTypeFloat 32
+         %25 = OpTypeVector %24 2
+         %26 = OpTypeStruct %25
+         %27 = OpTypePointer Uniform %26
+         %28 = OpVariable %27 Uniform
+         %29 = OpTypeInt 32 0
+         %30 = OpConstant %29 1
+         %31 = OpTypePointer Uniform %24
+         %36 = OpConstant %29 9
+         %37 = OpTypeArray %24 %36
+         %38 = OpTypePointer Function %37
+         %40 = OpConstant %24 0
+         %41 = OpTypePointer Function %24
+         %45 = OpConstant %6 1
+         %48 = OpTypeVector %24 4
+         %49 = OpTypePointer Output %48
+         %50 = OpVariable %49 Output
+         %51 = OpConstant %24 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %11 = OpVariable %10 Function
+         %39 = OpVariable %38 Function
+               OpStore %11 %15
+               OpBranch %16
+         %16 = OpLabel
+               OpLoopMerge %18 %19 None
+               OpBranch %20
+         %20 = OpLabel
+         %59 = OpLoad %9 %11
+         %23 = OpCompositeExtract %6 %59 0
+         %32 = OpAccessChain %31 %28 %12 %30
+         %33 = OpLoad %24 %32
+         %34 = OpConvertFToS %6 %33
+         %35 = OpINotEqual %7 %23 %34
+               OpBranchConditional %35 %17 %18
+         %17 = OpLabel
+         %42 = OpAccessChain %41 %39 %12
+               OpStore %42 %40
+               OpBranch %19
+         %19 = OpLabel
+         %60 = OpLoad %9 %11
+         %44 = OpCompositeExtract %6 %60 0
+         %46 = OpIAdd %6 %44 %45
+         %61 = OpLoad %9 %11
+         %62 = OpCompositeInsert %9 %46 %61 0
+               OpStore %11 %62
+               OpBranch %16
+         %18 = OpLabel
+         %53 = OpAccessChain %41 %39 %12
+         %54 = OpLoad %24 %53
+         %55 = OpCompositeConstruct %25 %54 %54
+         %56 = OpCompositeExtract %24 %55 0
+         %57 = OpCompositeExtract %24 %55 1
+         %58 = OpCompositeConstruct %48 %51 %56 %57 %51
+               OpStore %50 %58
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-if-discard.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-if-discard.amber
new file mode 100644
index 0000000..3e0a463
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-if-discard.amber
@@ -0,0 +1,138 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with a switch, if, and discard
+
+# The test passes because the shader always writes the color red;
+# the switch is always skipped.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   switch (int(injectionSwitch.y)) // always 1
+#   {
+#   case -1:
+#     if (injectionSwitch.y > injectionSwitch.x)
+#     {
+#       discard;
+#     }
+#   }
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 38
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %34
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "buf0"
+               OpMemberName %8 0 "injectionSwitch"
+               OpName %10 ""
+               OpName %34 "_GLF_color"
+               OpMemberDecorate %8 0 Offset 0
+               OpDecorate %8 Block
+               OpDecorate %10 DescriptorSet 0
+               OpDecorate %10 Binding 0
+               OpDecorate %34 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypeStruct %7
+          %9 = OpTypePointer Uniform %8
+         %10 = OpVariable %9 Uniform
+         %11 = OpTypeInt 32 1
+         %12 = OpConstant %11 0
+         %13 = OpTypeInt 32 0
+         %14 = OpConstant %13 1
+         %15 = OpTypePointer Uniform %6
+         %23 = OpConstant %13 0
+         %26 = OpTypeBool
+         %32 = OpTypeVector %6 4
+         %33 = OpTypePointer Output %32
+         %34 = OpVariable %33 Output
+         %35 = OpConstant %6 1
+         %36 = OpConstant %6 0
+         %37 = OpConstantComposite %32 %35 %36 %36 %35
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %16 = OpAccessChain %15 %10 %12 %14
+         %17 = OpLoad %6 %16
+         %18 = OpConvertFToS %11 %17
+               OpSelectionMerge %20 None
+               OpSwitch %18 %20 -1 %19
+         %19 = OpLabel
+         %21 = OpAccessChain %15 %10 %12 %14
+         %22 = OpLoad %6 %21
+         %24 = OpAccessChain %15 %10 %12 %23
+         %25 = OpLoad %6 %24
+         %27 = OpFOrdGreaterThan %26 %22 %25
+               OpSelectionMerge %29 None
+               OpBranchConditional %27 %28 %29
+         %28 = OpLabel
+               OpKill
+         %29 = OpLabel
+               OpBranch %20
+         %20 = OpLabel
+               OpStore %34 %37
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-with-empty-if-false.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-with-empty-if-false.amber
new file mode 100644
index 0000000..8bbb010
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/switch-with-empty-if-false.amber
@@ -0,0 +1,115 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with always false if in switch statement
+
+# The test passes because the shader always writes the color red
+
+# Optimized using spirv-opt with the following arguments:
+# '--private-to-local'
+# '--eliminate-local-multi-store'
+# '--simplify-instructions'
+# '--eliminate-dead-inserts'
+# spirv-opt commit hash: 4a00a80c40484a6f6f72f48c9d34943cf8f180d4
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+#
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   switch (0)
+#   {
+#   case 0:
+#     if (false)
+#     {
+#     }
+#   }
+#
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 22
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %18
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %18 "_GLF_color"
+               OpDecorate %18 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpConstant %6 0
+         %10 = OpTypeBool
+         %11 = OpConstantFalse %10
+         %15 = OpTypeFloat 32
+         %16 = OpTypeVector %15 4
+         %17 = OpTypePointer Output %16
+         %18 = OpVariable %17 Output
+         %19 = OpConstant %15 1
+         %20 = OpConstant %15 0
+         %21 = OpConstantComposite %16 %19 %20 %20 %19
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpSelectionMerge %9 None
+               OpSwitch %7 %9 0 %8
+          %8 = OpLabel
+               OpSelectionMerge %13 None
+               OpBranchConditional %11 %12 %13
+         %12 = OpLabel
+               OpBranch %13
+         %13 = OpLabel
+               OpBranch %9
+          %9 = OpLabel
+               OpStore %18 %21
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/transpose-rectangular-matrix.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/transpose-rectangular-matrix.amber
new file mode 100644
index 0000000..22967b7
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/transpose-rectangular-matrix.amber
@@ -0,0 +1,152 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Fragment shader that uses 'transpose'
+
+# The test passes because 'f' is invoked with a vector whose components are less than or equal to 1.0, so that it returns vec3(1.0, 0.0, 0.0), meaning that the output colour red is written
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# vec3 f(vec2 pos)
+# {
+#  if(pos.y > 1.0)
+#   {
+#    vec3 v;
+#    return v;
+#   }
+#  return vec3(1.0, 0.0, 0.0);
+# }
+# void main()
+# {
+#  _GLF_color = vec4(f(vec2(transpose((gl_FragCoord.y < 1.0) ? mat4x3(1.0) : transpose(mat3x4(1.0))))), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 99
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %34 %36
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %34 "_GLF_color"
+               OpName %36 "gl_FragCoord"
+               OpDecorate %34 Location 0
+               OpDecorate %36 BuiltIn FragCoord
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %9 = OpTypeVector %6 3
+         %14 = OpTypeInt 32 0
+         %15 = OpConstant %14 1
+         %19 = OpConstant %6 1
+         %20 = OpTypeBool
+         %28 = OpConstant %6 0
+         %29 = OpConstantComposite %9 %19 %28 %28
+         %32 = OpTypeVector %6 4
+         %33 = OpTypePointer Output %32
+         %34 = OpVariable %33 Output
+         %35 = OpTypePointer Input %32
+         %36 = OpVariable %35 Input
+         %37 = OpTypePointer Input %6
+         %41 = OpTypeMatrix %9 4
+         %46 = OpConstantComposite %9 %28 %19 %28
+         %47 = OpConstantComposite %9 %28 %28 %19
+         %48 = OpConstantComposite %9 %28 %28 %28
+         %49 = OpConstantComposite %41 %29 %46 %47 %48
+         %51 = OpTypeMatrix %32 3
+         %52 = OpConstantComposite %32 %19 %28 %28 %28
+         %53 = OpConstantComposite %32 %28 %19 %28 %28
+         %54 = OpConstantComposite %32 %28 %28 %19 %28
+         %55 = OpConstantComposite %51 %52 %53 %54
+         %97 = OpUndef %9
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %38 = OpAccessChain %37 %36 %15
+         %39 = OpLoad %6 %38
+         %40 = OpFOrdLessThan %20 %39 %19
+               OpSelectionMerge %45 None
+               OpBranchConditional %40 %44 %50
+         %44 = OpLabel
+               OpBranch %45
+         %50 = OpLabel
+         %56 = OpTranspose %41 %55
+               OpBranch %45
+         %45 = OpLabel
+         %94 = OpPhi %41 %49 %44 %56 %50
+         %58 = OpTranspose %51 %94
+         %60 = OpCompositeExtract %6 %58 0 1
+               OpBranch %82
+         %82 = OpLabel
+               OpLoopMerge %83 %84 None
+               OpBranch %85
+         %85 = OpLabel
+         %88 = OpFOrdGreaterThan %20 %60 %19
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
+         %90 = OpLabel
+               OpBranch %83
+         %89 = OpLabel
+               OpBranch %83
+         %84 = OpLabel
+               OpBranch %82
+         %83 = OpLabel
+         %98 = OpPhi %9 %97 %90 %29 %89
+         %64 = OpCompositeExtract %6 %98 0
+         %65 = OpCompositeExtract %6 %98 1
+         %66 = OpCompositeExtract %6 %98 2
+         %67 = OpCompositeConstruct %32 %64 %65 %66 %19
+               OpStore %34 %67
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-2-iteration-loops.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-2-iteration-loops.amber
new file mode 100644
index 0000000..406e5a4
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-2-iteration-loops.amber
@@ -0,0 +1,329 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Fragment shader with pair of outer loops
+
+# The test passes because fragments in the top-left quadrant write red, and all other fragments are guaranteed to be discarded
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#  _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#  if (gl_FragCoord.x < 128.0 && gl_FragCoord.y < 128.0) {
+#   return;
+#  }
+#  int odd_index = 0;
+#  while(odd_index <= 1)
+#   {
+#    _GLF_color.x += 0.25;
+#    odd_index ++;
+#   }
+#  int even_index = 1;
+#  while(even_index >= 0)
+#   {
+#    _GLF_color.x += 0.25;
+#    if(injectionSwitch.x > injectionSwitch.y)
+#     {
+#      // Unreachable
+#      continue;
+#     }
+#    if(even_index >= 1)
+#     {
+#      // Guaranteed to be reached during the first loop iteration
+#      discard;
+#     }
+#    int ll; // Uninitialized, but unreachable due to the above discard
+#    for(
+#        int j = 1;
+#        true;
+#        j ++
+#    )
+#     {
+#      if(ll >= 3)
+#       {
+#        break;
+#       }
+#      ll ++;
+#      if(uint(j) < uint(1))
+#       {
+#        continue;
+#       }
+#      if(injectionSwitch.x > injectionSwitch.y)
+#       {
+#        break;
+#       }
+#     }
+#    if(injectionSwitch.x > injectionSwitch.y)
+#     {
+#      _GLF_color = vec4(1.0);
+#     }
+#    even_index --;
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 125
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9 %15
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %15 "gl_FragCoord"
+               OpName %35 "odd_index"
+               OpName %53 "even_index"
+               OpName %66 "buf0"
+               OpMemberName %66 0 "injectionSwitch"
+               OpName %68 ""
+               OpName %83 "j"
+               OpName %90 "ll"
+               OpDecorate %9 Location 0
+               OpDecorate %15 BuiltIn FragCoord
+               OpDecorate %35 RelaxedPrecision
+               OpDecorate %42 RelaxedPrecision
+               OpDecorate %51 RelaxedPrecision
+               OpDecorate %52 RelaxedPrecision
+               OpDecorate %53 RelaxedPrecision
+               OpDecorate %59 RelaxedPrecision
+               OpMemberDecorate %66 0 Offset 0
+               OpDecorate %66 Block
+               OpDecorate %68 DescriptorSet 0
+               OpDecorate %68 Binding 0
+               OpDecorate %78 RelaxedPrecision
+               OpDecorate %83 RelaxedPrecision
+               OpDecorate %90 RelaxedPrecision
+               OpDecorate %91 RelaxedPrecision
+               OpDecorate %97 RelaxedPrecision
+               OpDecorate %98 RelaxedPrecision
+               OpDecorate %99 RelaxedPrecision
+               OpDecorate %113 RelaxedPrecision
+               OpDecorate %114 RelaxedPrecision
+               OpDecorate %123 RelaxedPrecision
+               OpDecorate %124 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %13 = OpTypeBool
+         %14 = OpTypePointer Input %7
+         %15 = OpVariable %14 Input
+         %16 = OpTypeInt 32 0
+         %17 = OpConstant %16 0
+         %18 = OpTypePointer Input %6
+         %21 = OpConstant %6 128
+         %25 = OpConstant %16 1
+         %33 = OpTypeInt 32 1
+         %34 = OpTypePointer Function %33
+         %36 = OpConstant %33 0
+         %43 = OpConstant %33 1
+         %45 = OpConstant %6 0.25
+         %46 = OpTypePointer Output %6
+         %65 = OpTypeVector %6 2
+         %66 = OpTypeStruct %65
+         %67 = OpTypePointer Uniform %66
+         %68 = OpVariable %67 Uniform
+         %69 = OpTypePointer Uniform %6
+         %89 = OpConstantTrue %13
+         %92 = OpConstant %33 3
+        %122 = OpConstantComposite %7 %10 %10 %10 %10
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %35 = OpVariable %34 Function
+         %53 = OpVariable %34 Function
+         %83 = OpVariable %34 Function
+         %90 = OpVariable %34 Function
+               OpStore %9 %12
+         %19 = OpAccessChain %18 %15 %17
+         %20 = OpLoad %6 %19
+         %22 = OpFOrdLessThan %13 %20 %21
+               OpSelectionMerge %24 None
+               OpBranchConditional %22 %23 %24
+         %23 = OpLabel
+         %26 = OpAccessChain %18 %15 %25
+         %27 = OpLoad %6 %26
+         %28 = OpFOrdLessThan %13 %27 %21
+               OpBranch %24
+         %24 = OpLabel
+         %29 = OpPhi %13 %22 %5 %28 %23
+               OpSelectionMerge %31 None
+               OpBranchConditional %29 %30 %31
+         %30 = OpLabel
+               OpReturn
+         %31 = OpLabel
+               OpStore %35 %36
+               OpBranch %37
+         %37 = OpLabel
+               OpLoopMerge %39 %40 None
+               OpBranch %41
+         %41 = OpLabel
+         %42 = OpLoad %33 %35
+         %44 = OpSLessThanEqual %13 %42 %43
+               OpBranchConditional %44 %38 %39
+         %38 = OpLabel
+         %47 = OpAccessChain %46 %9 %17
+         %48 = OpLoad %6 %47
+         %49 = OpFAdd %6 %48 %45
+         %50 = OpAccessChain %46 %9 %17
+               OpStore %50 %49
+         %51 = OpLoad %33 %35
+         %52 = OpIAdd %33 %51 %43
+               OpStore %35 %52
+               OpBranch %40
+         %40 = OpLabel
+               OpBranch %37
+         %39 = OpLabel
+               OpStore %53 %43
+               OpBranch %54
+         %54 = OpLabel
+               OpLoopMerge %56 %57 None
+               OpBranch %58
+         %58 = OpLabel
+         %59 = OpLoad %33 %53
+         %60 = OpSGreaterThanEqual %13 %59 %36
+               OpBranchConditional %60 %55 %56
+         %55 = OpLabel
+         %61 = OpAccessChain %46 %9 %17
+         %62 = OpLoad %6 %61
+         %63 = OpFAdd %6 %62 %45
+         %64 = OpAccessChain %46 %9 %17
+               OpStore %64 %63
+         %70 = OpAccessChain %69 %68 %36 %17
+         %71 = OpLoad %6 %70
+         %72 = OpAccessChain %69 %68 %36 %25
+         %73 = OpLoad %6 %72
+         %74 = OpFOrdGreaterThan %13 %71 %73
+               OpSelectionMerge %76 None
+               OpBranchConditional %74 %75 %76
+         %75 = OpLabel
+               OpBranch %57
+         %76 = OpLabel
+         %78 = OpLoad %33 %53
+         %79 = OpSGreaterThanEqual %13 %78 %43
+               OpSelectionMerge %81 None
+               OpBranchConditional %79 %80 %81
+         %80 = OpLabel
+               OpKill
+         %81 = OpLabel
+               OpStore %83 %43
+               OpBranch %84
+         %84 = OpLabel
+               OpLoopMerge %86 %87 None
+               OpBranch %88
+         %88 = OpLabel
+               OpBranchConditional %89 %85 %86
+         %85 = OpLabel
+         %91 = OpLoad %33 %90
+         %93 = OpSGreaterThanEqual %13 %91 %92
+               OpSelectionMerge %95 None
+               OpBranchConditional %93 %94 %95
+         %94 = OpLabel
+               OpBranch %86
+         %95 = OpLabel
+         %97 = OpLoad %33 %90
+         %98 = OpIAdd %33 %97 %43
+               OpStore %90 %98
+         %99 = OpLoad %33 %83
+        %100 = OpBitcast %16 %99
+        %101 = OpULessThan %13 %100 %25
+               OpSelectionMerge %103 None
+               OpBranchConditional %101 %102 %103
+        %102 = OpLabel
+               OpBranch %87
+        %103 = OpLabel
+        %105 = OpAccessChain %69 %68 %36 %17
+        %106 = OpLoad %6 %105
+        %107 = OpAccessChain %69 %68 %36 %25
+        %108 = OpLoad %6 %107
+        %109 = OpFOrdGreaterThan %13 %106 %108
+               OpSelectionMerge %111 None
+               OpBranchConditional %109 %110 %111
+        %110 = OpLabel
+               OpBranch %86
+        %111 = OpLabel
+               OpBranch %87
+         %87 = OpLabel
+        %113 = OpLoad %33 %83
+        %114 = OpIAdd %33 %113 %43
+               OpStore %83 %114
+               OpBranch %84
+         %86 = OpLabel
+        %115 = OpAccessChain %69 %68 %36 %17
+        %116 = OpLoad %6 %115
+        %117 = OpAccessChain %69 %68 %36 %25
+        %118 = OpLoad %6 %117
+        %119 = OpFOrdGreaterThan %13 %116 %118
+               OpSelectionMerge %121 None
+               OpBranchConditional %119 %120 %121
+        %120 = OpLabel
+               OpStore %9 %122
+               OpBranch %121
+        %121 = OpLabel
+        %123 = OpLoad %33 %53
+        %124 = OpISub %33 %123 %43
+               OpStore %53 %124
+               OpBranch %57
+         %57 = OpLabel
+               OpBranch %54
+         %56 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 100 100 EQ_RGBA 255 0 0 255
\ No newline at end of file
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-for-loops-with-barrier-function.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-for-loops-with-barrier-function.amber
new file mode 100644
index 0000000..e3edf46
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-for-loops-with-barrier-function.amber
@@ -0,0 +1,291 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A compute shader with two barrier functions
+
+# The test passes because main always outputs 42.
+
+# variant_compute_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(std430, binding = 0) buffer doesNotMatter
+# {
+#     uint _compute_data[];
+# };
+# layout(local_size_x = 1, local_size_y = 18, local_size_z = 6) in;
+# mediump vec4 GLF_live2gl_FragCoord;
+# layout(set = 0, binding = 1) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+#
+# void main()
+# {
+#     int GLF_live2_looplimiter1 = 0;
+#     for (
+#         int i = 0;
+#         i < 1;
+#         ++i)
+#     {
+#         if (GLF_live2_looplimiter1 >= 3) //always false
+#         {
+#             for (
+#                 int j = 0;
+#                 j < 1;
+#                 ++j)
+#             {
+#                 if (int(GLF_live2gl_FragCoord.x) < 120)
+#                 {
+#                 }
+#                 else
+#                 {
+#                     barrier();
+#                 }
+#             }
+#             break;
+#         }
+#     }
+#     float GLF_dead3x = (injectionSwitch.x > injectionSwitch.y ? GLF_live2gl_FragCoord.x : 0.0); // always 0.0
+#     for (
+#         int GLF_dead3k = 0;
+#         GLF_dead3k < 2;
+#         ++GLF_dead3k)
+#     {
+#         if (GLF_dead3x > 4.0) //always false
+#         {
+#             break;
+#         }
+#         GLF_dead3x = GLF_live2gl_FragCoord.x;
+#         barrier();
+#     }
+#
+#     _compute_data[0] = 42u;
+# }
+SHADER compute variant_compute_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 106
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %4 "main"
+               OpExecutionMode %4 LocalSize 1 18 6
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "GLF_live2_looplimiter1"
+               OpName %10 "i"
+               OpName %25 "j"
+               OpName %36 "GLF_live2gl_FragCoord"
+               OpName %56 "GLF_dead3x"
+               OpName %58 "buf0"
+               OpMemberName %58 0 "injectionSwitch"
+               OpName %60 ""
+               OpName %76 "GLF_dead3k"
+               OpName %96 "doesNotMatter"
+               OpMemberName %96 0 "_compute_data"
+               OpName %98 ""
+               OpDecorate %36 RelaxedPrecision
+               OpDecorate %41 RelaxedPrecision
+               OpMemberDecorate %58 0 Offset 0
+               OpDecorate %58 Block
+               OpDecorate %60 DescriptorSet 0
+               OpDecorate %60 Binding 1
+               OpDecorate %72 RelaxedPrecision
+               OpDecorate %75 RelaxedPrecision
+               OpDecorate %92 RelaxedPrecision
+               OpDecorate %95 ArrayStride 4
+               OpMemberDecorate %96 0 Offset 0
+               OpDecorate %96 BufferBlock
+               OpDecorate %98 DescriptorSet 0
+               OpDecorate %98 Binding 0
+               OpDecorate %105 BuiltIn WorkgroupSize
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %9 = OpConstant %6 0
+         %17 = OpConstant %6 1
+         %18 = OpTypeBool
+         %21 = OpConstant %6 3
+         %33 = OpTypeFloat 32
+         %34 = OpTypeVector %33 4
+         %35 = OpTypePointer Private %34
+         %36 = OpVariable %35 Private
+         %37 = OpTypeInt 32 0
+         %38 = OpConstant %37 0
+         %39 = OpTypePointer Private %33
+         %43 = OpConstant %6 120
+         %48 = OpConstant %37 2
+         %49 = OpConstant %37 264
+         %55 = OpTypePointer Function %33
+         %57 = OpTypeVector %33 2
+         %58 = OpTypeStruct %57
+         %59 = OpTypePointer Uniform %58
+         %60 = OpVariable %59 Uniform
+         %61 = OpTypePointer Uniform %33
+         %64 = OpConstant %37 1
+         %74 = OpConstant %33 0
+         %83 = OpConstant %6 2
+         %86 = OpConstant %33 4
+         %95 = OpTypeRuntimeArray %37
+         %96 = OpTypeStruct %95
+         %97 = OpTypePointer Uniform %96
+         %98 = OpVariable %97 Uniform
+         %99 = OpConstant %37 42
+        %100 = OpTypePointer Uniform %37
+        %102 = OpTypeVector %37 3
+        %103 = OpConstant %37 18
+        %104 = OpConstant %37 6
+        %105 = OpConstantComposite %102 %64 %103 %104
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %8 = OpVariable %7 Function
+         %10 = OpVariable %7 Function
+         %25 = OpVariable %7 Function
+         %56 = OpVariable %55 Function
+         %68 = OpVariable %55 Function
+         %76 = OpVariable %7 Function
+               OpStore %8 %9
+               OpStore %10 %9
+               OpBranch %11
+         %11 = OpLabel
+               OpLoopMerge %13 %14 None
+               OpBranch %15
+         %15 = OpLabel
+         %16 = OpLoad %6 %10
+         %19 = OpSLessThan %18 %16 %17
+               OpBranchConditional %19 %12 %13
+         %12 = OpLabel
+         %20 = OpLoad %6 %8
+         %22 = OpSGreaterThanEqual %18 %20 %21
+               OpSelectionMerge %24 None
+               OpBranchConditional %22 %23 %24
+         %23 = OpLabel
+               OpStore %25 %9
+               OpBranch %26
+         %26 = OpLabel
+               OpLoopMerge %28 %29 None
+               OpBranch %30
+         %30 = OpLabel
+         %31 = OpLoad %6 %25
+         %32 = OpSLessThan %18 %31 %17
+               OpBranchConditional %32 %27 %28
+         %27 = OpLabel
+         %40 = OpAccessChain %39 %36 %38
+         %41 = OpLoad %33 %40
+         %42 = OpConvertFToS %6 %41
+         %44 = OpSLessThan %18 %42 %43
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %45 %47
+         %45 = OpLabel
+               OpBranch %46
+         %47 = OpLabel
+               OpControlBarrier %48 %48 %49
+               OpBranch %46
+         %46 = OpLabel
+               OpBranch %29
+         %29 = OpLabel
+         %50 = OpLoad %6 %25
+         %51 = OpIAdd %6 %50 %17
+               OpStore %25 %51
+               OpBranch %26
+         %28 = OpLabel
+               OpBranch %13
+         %24 = OpLabel
+               OpBranch %14
+         %14 = OpLabel
+         %53 = OpLoad %6 %10
+         %54 = OpIAdd %6 %53 %17
+               OpStore %10 %54
+               OpBranch %11
+         %13 = OpLabel
+         %62 = OpAccessChain %61 %60 %9 %38
+         %63 = OpLoad %33 %62
+         %65 = OpAccessChain %61 %60 %9 %64
+         %66 = OpLoad %33 %65
+         %67 = OpFOrdGreaterThan %18 %63 %66
+               OpSelectionMerge %70 None
+               OpBranchConditional %67 %69 %73
+         %69 = OpLabel
+         %71 = OpAccessChain %39 %36 %38
+         %72 = OpLoad %33 %71
+               OpStore %68 %72
+               OpBranch %70
+         %73 = OpLabel
+               OpStore %68 %74
+               OpBranch %70
+         %70 = OpLabel
+         %75 = OpLoad %33 %68
+               OpStore %56 %75
+               OpStore %76 %9
+               OpBranch %77
+         %77 = OpLabel
+               OpLoopMerge %79 %80 None
+               OpBranch %81
+         %81 = OpLabel
+         %82 = OpLoad %6 %76
+         %84 = OpSLessThan %18 %82 %83
+               OpBranchConditional %84 %78 %79
+         %78 = OpLabel
+         %85 = OpLoad %33 %56
+         %87 = OpFOrdGreaterThan %18 %85 %86
+               OpSelectionMerge %89 None
+               OpBranchConditional %87 %88 %89
+         %88 = OpLabel
+               OpBranch %79
+         %89 = OpLabel
+         %91 = OpAccessChain %39 %36 %38
+         %92 = OpLoad %33 %91
+               OpStore %56 %92
+               OpControlBarrier %48 %48 %49
+               OpBranch %80
+         %80 = OpLabel
+         %93 = OpLoad %6 %76
+         %94 = OpIAdd %6 %93 %17
+               OpStore %76 %94
+               OpBranch %77
+         %79 = OpLabel
+        %101 = OpAccessChain %100 %98 %9 %9
+               OpStore %101 %99
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_ssbo DATA_TYPE uint32 DATA
+ 0 0 0 0 0 0 0 0 0 0
+END
+
+PIPELINE compute variant_pipeline
+  ATTACH variant_compute_shader
+  BIND BUFFER variant_ssbo AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN variant_pipeline 1 6 2
+
+EXPECT variant_ssbo IDX 0 EQ 42
\ No newline at end of file
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-do-whiles.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-do-whiles.amber
new file mode 100644
index 0000000..64e418d
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-do-whiles.amber
@@ -0,0 +1,252 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with nested do while
+
+# The test passes because the shader always writes color red. main() writes red and then returns at the end.
+
+# Optimized using spirv-opt with the following arguments:
+# '--ccp'
+# '--redundancy-elimination'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-branches'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#
+#   int i = 0;
+#   if (injectionSwitch.y < 0.0) // Always false
+#   {
+#   }
+#   else
+#   {
+#     if (gl_FragCoord.y < -1.0) // Always false
+#     {
+#     }
+#     else
+#     {
+#       do
+#       {
+#         if (i >= 256) // Always false
+#         {
+#           break;
+#         }
+#         do
+#         {
+#           for (int i = 0; i < 1; i++)
+#           {
+#             if (gl_FragCoord.y < -1.0) // Always false
+#             {
+#               for (int i = 0; i < 1; i++)
+#               {
+#               }
+#               continue;
+#             }
+#             return;
+#           }
+#         } while (false);
+#       } while (false);
+#     }
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 87
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9 %32
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %15 "i"
+               OpName %18 "buf0"
+               OpMemberName %18 0 "injectionSwitch"
+               OpName %20 ""
+               OpName %32 "gl_FragCoord"
+               OpName %55 "i"
+               OpName %69 "i"
+               OpDecorate %9 Location 0
+               OpMemberDecorate %18 0 Offset 0
+               OpDecorate %18 Block
+               OpDecorate %20 DescriptorSet 0
+               OpDecorate %20 Binding 0
+               OpDecorate %32 BuiltIn FragCoord
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %13 = OpTypeInt 32 1
+         %14 = OpTypePointer Function %13
+         %16 = OpConstant %13 0
+         %17 = OpTypeVector %6 2
+         %18 = OpTypeStruct %17
+         %19 = OpTypePointer Uniform %18
+         %20 = OpVariable %19 Uniform
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 1
+         %23 = OpTypePointer Uniform %6
+         %26 = OpTypeBool
+         %31 = OpTypePointer Input %7
+         %32 = OpVariable %31 Input
+         %33 = OpTypePointer Input %6
+         %36 = OpConstant %6 -1
+         %46 = OpConstant %13 256
+         %62 = OpConstant %13 1
+         %83 = OpConstantFalse %26
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %15 = OpVariable %14 Function
+         %55 = OpVariable %14 Function
+         %69 = OpVariable %14 Function
+               OpStore %9 %12
+               OpStore %15 %16
+         %24 = OpAccessChain %23 %20 %16 %22
+         %25 = OpLoad %6 %24
+         %27 = OpFOrdLessThan %26 %25 %11
+               OpSelectionMerge %29 None
+               OpBranchConditional %27 %28 %30
+         %28 = OpLabel
+               OpBranch %29
+         %30 = OpLabel
+         %34 = OpAccessChain %33 %32 %22
+         %35 = OpLoad %6 %34
+         %37 = OpFOrdLessThan %26 %35 %36
+               OpSelectionMerge %39 None
+               OpBranchConditional %37 %38 %40
+         %38 = OpLabel
+               OpBranch %39
+         %40 = OpLabel
+               OpBranch %41
+         %41 = OpLabel
+               OpLoopMerge %43 %53 None
+               OpBranch %42
+         %42 = OpLabel
+         %45 = OpLoad %13 %15
+         %47 = OpSGreaterThanEqual %26 %45 %46
+               OpSelectionMerge %49 None
+               OpBranchConditional %47 %48 %49
+         %48 = OpLabel
+               OpBranch %43
+         %49 = OpLabel
+               OpBranch %51
+         %51 = OpLabel
+               OpStore %55 %16
+               OpLoopMerge %84 %58 None
+               OpBranch %56
+         %56 = OpLabel
+         %61 = OpLoad %13 %55
+         %63 = OpSLessThan %26 %61 %62
+               OpLoopMerge %85 %72 None
+               OpBranchConditional %63 %57 %85
+         %57 = OpLabel
+               OpSelectionMerge %68 None
+               OpBranchConditional %37 %67 %68
+         %67 = OpLabel
+               OpStore %69 %16
+               OpBranch %70
+         %70 = OpLabel
+         %75 = OpLoad %13 %69
+         %76 = OpSLessThan %26 %75 %62
+               OpLoopMerge %86 %71 None
+               OpBranchConditional %76 %71 %86
+         %71 = OpLabel
+         %77 = OpLoad %13 %69
+         %78 = OpIAdd %13 %77 %62
+               OpStore %69 %78
+               OpBranch %70
+         %86 = OpLabel
+               OpBranch %72
+         %72 = OpLabel
+         %81 = OpLoad %13 %55
+         %82 = OpIAdd %13 %81 %62
+               OpStore %55 %82
+               OpBranch %56
+         %68 = OpLabel
+               OpReturn
+         %85 = OpLabel
+               OpBranch %58
+         %58 = OpLabel
+               OpBranchConditional %83 %51 %84
+         %84 = OpLabel
+               OpBranch %53
+         %53 = OpLabel
+               OpBranchConditional %83 %41 %43
+         %43 = OpLabel
+               OpBranch %39
+         %39 = OpLabel
+               OpBranch %29
+         %29 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-for-loops-with-returns.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-for-loops-with-returns.amber
new file mode 100644
index 0000000..61b573b
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-for-loops-with-returns.amber
@@ -0,0 +1,211 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A compute shader with two nested for loops
+
+# The test passes because main always outputs 42.0.
+
+# Optimized using spirv-opt with the following arguments:
+# '--private-to-local'
+# '--eliminate-local-multi-store'
+# '--simplify-instructions'
+# '--eliminate-dead-inserts'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 4a00a80c40484a6f6f72f48c9d34943cf8f180d4
+
+
+
+# variant_compute_shader is derived from the following GLSL:
+# #version 310 es
+#
+# precision highp float;
+#
+# layout(std430, binding = 0) buffer doesNotMatter
+# {
+#     float _compute_data[];
+# };
+#
+# float nb_mod()
+# {
+#     float s = 0.0;
+#
+#     // Loop is entered, but we always return 42.0 during the first iteration.
+#     for (
+#         int i = 5;
+#         i < 800;
+#         i++)
+#     {
+#         int GLF_live1_looplimiter2;
+#
+#         // Loop is entered and we possibly return.
+#         for (
+#             int GLF_live1i = 0;
+#             GLF_live1i < 20;
+#             ++GLF_live1i)
+#         {
+#             // GLF_live1_looplimiter2 is undefined, so we may break; doesn't matter.
+#             if (GLF_live1_looplimiter2 >= 5)
+#             {
+#                 ++s;
+#                 break;
+#             }
+#             // If we didn't break, we return 42.0 here.
+#             return 42.0;
+#         }
+#
+#         if (float(i) <= s) // Always false: s is 0.0 or 1.0.
+#         {
+#             break;
+#         }
+#         // We return 42.0 and we don't loop.
+#         return 42.0;
+#     }
+#     // Unreachable at runtime.
+#     return s;
+# }
+#
+# void main()
+# {
+#     _compute_data[0] = nb_mod(); // Always returns 42.0.
+# }
+SHADER compute variant_compute_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 82
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %4 "main"
+               OpExecutionMode %4 LocalSize 1 1 1
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "nb_mod("
+               OpName %11 "s"
+               OpName %15 "i"
+               OpName %26 "GLF_live1i"
+               OpName %36 "GLF_live1_looplimiter2"
+               OpName %64 "doesNotMatter"
+               OpMemberName %64 0 "_compute_data"
+               OpName %66 ""
+               OpDecorate %63 ArrayStride 4
+               OpMemberDecorate %64 0 Offset 0
+               OpDecorate %64 BufferBlock
+               OpDecorate %66 DescriptorSet 0
+               OpDecorate %66 Binding 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeFunction %6
+         %10 = OpTypePointer Function %6
+         %12 = OpConstant %6 0
+         %13 = OpTypeInt 32 1
+         %14 = OpTypePointer Function %13
+         %16 = OpConstant %13 5
+         %23 = OpConstant %13 800
+         %24 = OpTypeBool
+         %27 = OpConstant %13 0
+         %34 = OpConstant %13 20
+         %42 = OpConstant %6 1
+         %45 = OpConstant %6 42
+         %48 = OpConstant %13 1
+         %63 = OpTypeRuntimeArray %6
+         %64 = OpTypeStruct %63
+         %65 = OpTypePointer Uniform %64
+         %66 = OpVariable %65 Uniform
+         %68 = OpTypePointer Uniform %6
+         %74 = OpUndef %13
+         %81 = OpUndef %6
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %67 = OpFunctionCall %6 %8
+         %69 = OpAccessChain %68 %66 %27 %27
+               OpStore %69 %67
+               OpReturn
+               OpFunctionEnd
+          %8 = OpFunction %6 None %7
+          %9 = OpLabel
+         %11 = OpVariable %10 Function
+         %15 = OpVariable %14 Function
+         %26 = OpVariable %14 Function
+         %36 = OpVariable %14 Function
+               OpStore %11 %12
+               OpStore %15 %16
+               OpBranch %17
+         %17 = OpLabel
+               OpLoopMerge %19 %20 None
+               OpBranch %21
+         %21 = OpLabel
+         %25 = OpSLessThan %24 %16 %23
+               OpBranchConditional %25 %18 %19
+         %18 = OpLabel
+               OpStore %26 %27
+               OpBranch %28
+         %28 = OpLabel
+               OpLoopMerge %30 %31 None
+               OpBranch %32
+         %32 = OpLabel
+         %35 = OpSLessThan %24 %27 %34
+               OpBranchConditional %35 %29 %30
+         %29 = OpLabel
+         %38 = OpSGreaterThanEqual %24 %74 %16
+               OpSelectionMerge %40 None
+               OpBranchConditional %38 %39 %40
+         %39 = OpLabel
+         %43 = OpFAdd %6 %12 %42
+               OpStore %11 %43
+               OpBranch %30
+         %40 = OpLabel
+               OpReturnValue %45
+         %31 = OpLabel
+               OpBranch %28
+         %30 = OpLabel
+         %79 = OpPhi %6 %12 %32 %43 %39
+         %51 = OpConvertSToF %6 %16
+         %53 = OpFOrdLessThanEqual %24 %51 %79
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %54 %55
+         %54 = OpLabel
+               OpBranch %19
+         %55 = OpLabel
+               OpReturnValue %45
+         %20 = OpLabel
+               OpBranch %17
+         %19 = OpLabel
+         %80 = OpPhi %6 %12 %21 %79 %54
+               OpReturnValue %80
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_ssbo DATA_TYPE float DATA
+ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
+END
+
+PIPELINE compute variant_pipeline
+  ATTACH variant_compute_shader
+  BIND BUFFER variant_ssbo AS storage DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN variant_pipeline 7 3 4
+
+EXPECT variant_ssbo IDX 0 EQ 42.0
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-infinite-loops-discard.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-infinite-loops-discard.amber
new file mode 100644
index 0000000..4ce3c46
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/two-nested-infinite-loops-discard.amber
@@ -0,0 +1,207 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with an always false if function
+
+# The test passes because main always writes the color red. (Additionally the discard statement is never reached).
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-local-single-block'
+# '--reduce-load-size'
+# '--combine-access-chains'
+# '--eliminate-local-multi-store'
+# '--reduce-load-size'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--copy-propagate-arrays'
+# '--copy-propagate-arrays'
+# '--eliminate-dead-inserts'
+# '--merge-blocks'
+# '--copy-propagate-arrays'
+# '--combine-access-chains'
+# '--simplify-instructions'
+# '--convert-local-access-chains'
+# spirv-opt commit hash: 4a00a80c40484a6f6f72f48c9d34943cf8f180d4
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+#
+# // END OF GENERATED HEADER
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# vec3 mand()
+# {
+#     for (
+#         int k = 0;
+#         k < 1000;
+#         1)
+#     {
+#         discard;
+#     }
+#     return vec3(1.0);
+# }
+# void main()
+# {
+#     if (injectionSwitch.x > injectionSwitch.y)
+#     {
+#         for (
+#             int j = 0;
+#             j < 4;
+#             1)
+#         {
+#             mand();
+#         }
+#     }
+#
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 64
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %57
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "mand("
+               OpName %13 "k"
+               OpName %31 "buf0"
+               OpMemberName %31 0 "injectionSwitch"
+               OpName %33 ""
+               OpName %45 "j"
+               OpName %57 "_GLF_color"
+               OpDecorate %13 RelaxedPrecision
+               OpMemberDecorate %31 0 Offset 0
+               OpDecorate %31 Block
+               OpDecorate %33 DescriptorSet 0
+               OpDecorate %33 Binding 0
+               OpDecorate %45 RelaxedPrecision
+               OpDecorate %57 Location 0
+               OpDecorate %14 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 3
+          %8 = OpTypeFunction %7
+         %11 = OpTypeInt 32 1
+         %12 = OpTypePointer Function %11
+         %14 = OpConstant %11 0
+         %21 = OpConstant %11 1000
+         %22 = OpTypeBool
+         %25 = OpConstant %11 1
+         %26 = OpConstant %6 1
+         %27 = OpConstantComposite %7 %26 %26 %26
+         %30 = OpTypeVector %6 2
+         %31 = OpTypeStruct %30
+         %32 = OpTypePointer Uniform %31
+         %33 = OpVariable %32 Uniform
+         %34 = OpTypeInt 32 0
+         %35 = OpConstant %34 0
+         %36 = OpTypePointer Uniform %6
+         %39 = OpConstant %34 1
+         %52 = OpConstant %11 4
+         %55 = OpTypeVector %6 4
+         %56 = OpTypePointer Output %55
+         %57 = OpVariable %56 Output
+         %58 = OpConstant %6 0
+         %59 = OpConstantComposite %55 %26 %58 %58 %26
+         %62 = OpUndef %11
+         %63 = OpConstantTrue %22
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %45 = OpVariable %12 Function
+         %37 = OpAccessChain %36 %33 %14 %35
+         %38 = OpLoad %6 %37
+         %40 = OpAccessChain %36 %33 %14 %39
+         %41 = OpLoad %6 %40
+         %42 = OpFOrdGreaterThan %22 %38 %41
+               OpSelectionMerge %44 None
+               OpBranchConditional %42 %43 %44
+         %43 = OpLabel
+               OpStore %45 %14
+               OpBranch %46
+         %46 = OpLabel
+               OpLoopMerge %48 %47 None
+               OpBranchConditional %63 %47 %48
+         %47 = OpLabel
+         %54 = OpFunctionCall %7 %9
+               OpBranch %46
+         %48 = OpLabel
+               OpBranch %44
+         %44 = OpLabel
+               OpStore %57 %59
+               OpReturn
+               OpFunctionEnd
+          %9 = OpFunction %7 None %8
+         %10 = OpLabel
+         %13 = OpVariable %12 Function
+               OpStore %13 %14
+               OpBranch %15
+         %15 = OpLabel
+               OpLoopMerge %17 %18 None
+               OpBranchConditional %63 %16 %17
+         %16 = OpLabel
+               OpKill
+         %18 = OpLabel
+               OpBranch %15
+         %17 = OpLabel
+               OpReturnValue %27
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-assign-in-infinite-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-assign-in-infinite-loop.amber
new file mode 100644
index 0000000..59b08f6
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-assign-in-infinite-loop.amber
@@ -0,0 +1,164 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with uninitialized read in infinite loop
+
+# The test passes because the shader always writes the color red. Uninitialized read in loop is never reached.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+#
+# void main()
+# {
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#
+#   int donor_replacementGLF_dead6tree[1];
+#   int GLF_dead6currentNode;
+#   int GLF_dead6index = 0;
+#
+#   if (injectionSwitch.y < 0.0){ // always false
+#     while (true)
+#     {
+#       GLF_dead6currentNode = donor_replacementGLF_dead6tree[GLF_dead6index];
+#       GLF_dead6index = GLF_dead6currentNode;
+#     }
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 44
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %15 "GLF_dead6index"
+               OpName %18 "buf0"
+               OpMemberName %18 0 "injectionSwitch"
+               OpName %20 ""
+               OpName %36 "GLF_dead6currentNode"
+               OpName %39 "donor_replacementGLF_dead6tree"
+               OpDecorate %9 Location 0
+               OpDecorate %15 RelaxedPrecision
+               OpMemberDecorate %18 0 Offset 0
+               OpDecorate %18 Block
+               OpDecorate %20 DescriptorSet 0
+               OpDecorate %20 Binding 0
+               OpDecorate %36 RelaxedPrecision
+               OpDecorate %39 RelaxedPrecision
+               OpDecorate %40 RelaxedPrecision
+               OpDecorate %42 RelaxedPrecision
+               OpDecorate %43 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %13 = OpTypeInt 32 1
+         %14 = OpTypePointer Function %13
+         %16 = OpConstant %13 0
+         %17 = OpTypeVector %6 2
+         %18 = OpTypeStruct %17
+         %19 = OpTypePointer Uniform %18
+         %20 = OpVariable %19 Uniform
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 1
+         %23 = OpTypePointer Uniform %6
+         %26 = OpTypeBool
+         %35 = OpConstantTrue %26
+         %37 = OpTypeArray %13 %22
+         %38 = OpTypePointer Function %37
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %15 = OpVariable %14 Function
+         %36 = OpVariable %14 Function
+         %39 = OpVariable %38 Function
+               OpStore %9 %12
+               OpStore %15 %16
+         %24 = OpAccessChain %23 %20 %16 %22
+         %25 = OpLoad %6 %24
+         %27 = OpFOrdLessThan %26 %25 %11
+               OpSelectionMerge %29 None
+               OpBranchConditional %27 %28 %29
+         %28 = OpLabel
+               OpBranch %30
+         %30 = OpLabel
+               OpLoopMerge %32 %33 None
+               OpBranch %34
+         %34 = OpLabel
+               OpBranchConditional %35 %31 %32
+         %31 = OpLabel
+         %40 = OpLoad %13 %15
+         %41 = OpAccessChain %14 %39 %40
+         %42 = OpLoad %13 %41
+               OpStore %36 %42
+         %43 = OpLoad %13 %36
+               OpStore %15 %43
+               OpBranch %33
+         %33 = OpLabel
+               OpBranch %30
+         %32 = OpLabel
+               OpBranch %29
+         %29 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-integer-in-function.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-integer-in-function.amber
new file mode 100644
index 0000000..15ba532
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/undefined-integer-in-function.amber
@@ -0,0 +1,233 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with nested do while and undefined int
+
+# The test passes because the shader always writes color red. performPartition() writes the color red and then always returns early.
+
+# Optimized using spirv-opt with the following arguments:
+# '--if-conversion'
+# '--redundancy-elimination'
+# '--eliminate-local-multi-store'
+# '--ccp'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-inserts'
+# '--ccp'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-inserts'
+# '--ccp'
+# '--eliminate-dead-branches'
+# '--private-to-local'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch;
+# };
+#
+# int performPartition()
+# {
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+#   int i;
+#   do
+#   {
+#     if (injectionSwitch.y < 0.0) // Always false
+#     {
+#     }
+#     else
+#     {
+#       for (int GLF_live0i = 0; GLF_live0i < 1; GLF_live0i++)
+#       {
+#         if (injectionSwitch.y < 0.0) // Always false
+#         {
+#           break;
+#         }
+#         return 1; // We always return here. The code below is never executed.
+#       }
+#       if (injectionSwitch.y < 0.0)
+#       {
+#         do
+#         {
+#           return 1;
+#         } while (false);
+#       }
+#     }
+#   } while (false);
+#   return i;
+# }
+#
+# void main()
+# {
+#   performPartition();
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 80
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %13
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "performPartition("
+               OpName %13 "_GLF_color"
+               OpName %22 "buf0"
+               OpMemberName %22 0 "injectionSwitch"
+               OpName %24 ""
+               OpName %37 "GLF_live0i"
+               OpName %66 "i"
+               OpDecorate %8 RelaxedPrecision
+               OpDecorate %13 Location 0
+               OpMemberDecorate %22 0 Offset 0
+               OpDecorate %22 Block
+               OpDecorate %24 DescriptorSet 0
+               OpDecorate %24 Binding 0
+               OpDecorate %37 RelaxedPrecision
+               OpDecorate %66 RelaxedPrecision
+               OpDecorate %70 RelaxedPrecision
+               OpDecorate %73 RelaxedPrecision
+               OpDecorate %72 RelaxedPrecision
+               OpDecorate %73 RelaxedPrecision
+               OpDecorate %73 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeFunction %6
+         %10 = OpTypeFloat 32
+         %11 = OpTypeVector %10 4
+         %12 = OpTypePointer Output %11
+         %13 = OpVariable %12 Output
+         %14 = OpConstant %10 1
+         %15 = OpConstant %10 0
+         %16 = OpConstantComposite %11 %14 %15 %15 %14
+         %21 = OpTypeVector %10 2
+         %22 = OpTypeStruct %21
+         %23 = OpTypePointer Uniform %22
+         %24 = OpVariable %23 Uniform
+         %25 = OpConstant %6 0
+         %26 = OpTypeInt 32 0
+         %27 = OpConstant %26 1
+         %28 = OpTypePointer Uniform %10
+         %31 = OpTypeBool
+         %36 = OpTypePointer Function %6
+         %44 = OpConstant %6 1
+         %65 = OpConstantFalse %31
+         %74 = OpUndef %6
+         %78 = OpConstantTrue %31
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %70 = OpFunctionCall %6 %8
+               OpReturn
+               OpFunctionEnd
+          %8 = OpFunction %6 None %7
+          %9 = OpLabel
+         %37 = OpVariable %36 Function
+         %66 = OpVariable %36 Function
+               OpStore %13 %16
+               OpBranch %17
+         %17 = OpLabel
+         %73 = OpPhi %6 %74 %9 %72 %34
+               OpLoopMerge %19 %34 None
+               OpBranch %18
+         %18 = OpLabel
+         %29 = OpAccessChain %28 %24 %25 %27
+         %30 = OpLoad %10 %29
+         %32 = OpFOrdLessThan %31 %30 %15
+               OpSelectionMerge %79 None
+               OpBranchConditional %32 %33 %35
+         %35 = OpLabel
+               OpStore %37 %25
+               OpBranch %38
+         %38 = OpLabel
+         %45 = OpSLessThan %31 %25 %44
+               OpLoopMerge %49 %41 None
+               OpBranch %39
+         %39 = OpLabel
+               OpSelectionMerge %50 None
+               OpBranchConditional %32 %49 %50
+         %49 = OpLabel
+               OpSelectionMerge %59 None
+               OpBranchConditional %32 %58 %59
+         %50 = OpLabel
+               OpReturnValue %44
+         %41 = OpLabel
+               OpBranch %38
+         %58 = OpLabel
+               OpBranch %60
+         %60 = OpLabel
+               OpLoopMerge %62 %63 None
+               OpBranch %61
+         %61 = OpLabel
+               OpReturnValue %44
+         %63 = OpLabel
+               OpBranch %60
+         %62 = OpLabel
+               OpUnreachable
+         %59 = OpLabel
+               OpBranch %34
+         %33 = OpLabel
+               OpBranch %34
+         %79 = OpLabel
+               OpBranch %34
+         %34 = OpLabel
+         %72 = OpPhi %6 %73 %33 %73 %59 %25 %79
+               OpBranchConditional %65 %17 %19
+         %19 = OpLabel
+               OpReturnValue %72
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninit-element-cast-in-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninit-element-cast-in-loop.amber
new file mode 100644
index 0000000..fcbc7d1
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninit-element-cast-in-loop.amber
@@ -0,0 +1,180 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with uninitialized element cast in loop
+
+# The test passes because main always writes the color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--inline-entry-points-exhaustive'
+# '--eliminate-local-single-block'
+# '--ccp'
+# '--eliminate-local-multi-store'
+# '--inline-entry-points-exhaustive'
+# '--combine-access-chains'
+# '--combine-access-chains'
+# '--reduce-load-size'
+# '--copy-propagate-arrays'
+# '--reduce-load-size'
+# '--eliminate-local-multi-store'
+# '--scalar-replacement=100'
+# '--convert-local-access-chains'
+# '--scalar-replacement=100'
+# '--vector-dce'
+# '--eliminate-dead-inserts'
+# '--scalar-replacement=100'
+# '--eliminate-dead-inserts'
+# '--simplify-instructions'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--ccp'
+# '--copy-propagate-arrays'
+# '--combine-access-chains'
+# '--eliminate-local-multi-store'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0 { vec2 injectionSwitch; };
+#
+# void main()
+# {
+#   while(true)
+#   {
+#     while(false)
+#       break;
+#
+#     float uninit[1];
+#     float(uninit[0]);
+#
+#     if (injectionSwitch.x < injectionSwitch.y) // always true
+#     {
+#       _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#       return;
+#     }
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 56
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %46
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %32 "buf0"
+               OpMemberName %32 0 "injectionSwitch"
+               OpName %34 ""
+               OpName %46 "_GLF_color"
+               OpMemberDecorate %32 0 Offset 0
+               OpDecorate %32 Block
+               OpDecorate %34 DescriptorSet 0
+               OpDecorate %34 Binding 0
+               OpDecorate %46 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+         %11 = OpTypeBool
+         %12 = OpConstantTrue %11
+         %18 = OpConstantFalse %11
+         %20 = OpTypeFloat 32
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 1
+         %23 = OpTypeArray %20 %22
+         %24 = OpTypePointer Function %23
+         %26 = OpTypeInt 32 1
+         %27 = OpConstant %26 0
+         %28 = OpTypePointer Function %20
+         %31 = OpTypeVector %20 2
+         %32 = OpTypeStruct %31
+         %33 = OpTypePointer Uniform %32
+         %34 = OpVariable %33 Uniform
+         %35 = OpConstant %21 0
+         %36 = OpTypePointer Uniform %20
+         %44 = OpTypeVector %20 4
+         %45 = OpTypePointer Output %44
+         %46 = OpVariable %45 Output
+         %47 = OpConstant %20 1
+         %48 = OpConstant %20 0
+         %49 = OpConstantComposite %44 %47 %48 %48 %47
+         %54 = OpUndef %20
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %51 = OpVariable %28 Function
+               OpBranch %6
+          %6 = OpLabel
+         %53 = OpPhi %20 %54 %5 %52 %43
+               OpLoopMerge %8 %43 None
+               OpBranch %13
+         %13 = OpLabel
+         %52 = OpPhi %20 %53 %6 %54 %16
+         %37 = OpAccessChain %36 %34 %27 %35
+         %38 = OpLoad %20 %37
+         %39 = OpAccessChain %36 %34 %27 %22
+         %40 = OpLoad %20 %39
+         %41 = OpFOrdLessThan %11 %38 %40
+               OpSelectionMerge %55 None
+               OpBranchConditional %41 %42 %43
+         %16 = OpLabel
+               OpBranch %13
+         %42 = OpLabel
+               OpStore %46 %49
+               OpReturn
+         %55 = OpLabel
+               OpBranch %43
+         %43 = OpLabel
+               OpBranch %6
+          %8 = OpLabel
+               OpUnreachable
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninitialized-var-decrement-and-add.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninitialized-var-decrement-and-add.amber
new file mode 100644
index 0000000..04f06cf
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/uninitialized-var-decrement-and-add.amber
@@ -0,0 +1,133 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that uses an uninitialized variable
+
+# The test passes because the shader always writes the color red.
+# The update to _GLF_color.x has no effect on visible pixels.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#
+#     uint foo;
+#
+#     // For visible pixels, this is equivalent to: _GLF_color.x = _GLF_color.x;
+#     _GLF_color.x = gl_FragCoord.x > -1.0 ? _GLF_color.x : float(178493u + (--foo));
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 42
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9 %14
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %14 "gl_FragCoord"
+               OpName %33 "foo"
+               OpDecorate %9 Location 0
+               OpDecorate %14 BuiltIn FragCoord
+               OpDecorate %33 RelaxedPrecision
+               OpDecorate %34 RelaxedPrecision
+               OpDecorate %37 RelaxedPrecision
+               OpDecorate %38 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %13 = OpTypePointer Input %7
+         %14 = OpVariable %13 Input
+         %15 = OpTypeInt 32 0
+         %16 = OpConstant %15 0
+         %17 = OpTypePointer Input %6
+         %20 = OpConstant %6 -1
+         %21 = OpTypeBool
+         %23 = OpTypePointer Function %6
+         %27 = OpTypePointer Output %6
+         %31 = OpConstant %15 178493
+         %32 = OpTypePointer Function %15
+         %35 = OpTypeInt 32 1
+         %36 = OpConstant %35 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %24 = OpVariable %23 Function
+         %33 = OpVariable %32 Function
+               OpStore %9 %12
+         %18 = OpAccessChain %17 %14 %16
+         %19 = OpLoad %6 %18
+         %22 = OpFOrdGreaterThan %21 %19 %20
+               OpSelectionMerge %26 None
+               OpBranchConditional %22 %25 %30
+         %25 = OpLabel
+         %28 = OpAccessChain %27 %9 %16
+         %29 = OpLoad %6 %28
+               OpStore %24 %29
+               OpBranch %26
+         %30 = OpLabel
+         %34 = OpLoad %15 %33
+         %37 = OpISub %15 %34 %36
+               OpStore %33 %37
+         %38 = OpIAdd %15 %31 %37
+         %39 = OpConvertUToF %6 %38
+               OpStore %24 %39
+               OpBranch %26
+         %26 = OpLabel
+         %40 = OpLoad %6 %24
+         %41 = OpAccessChain %27 %9 %16
+               OpStore %41 %40
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement-in-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement-in-if.amber
new file mode 100644
index 0000000..a8eca58
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement-in-if.amber
@@ -0,0 +1,187 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with discard keyword and a return
+
+# The test passes because main always writes the color red; the discard statement is unreachable.
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# spirv-opt commit hash: 230c9e437146e48ec58adb4433890403c23c98fa
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# vec3 computePoint()
+# {
+#     if (injectionSwitch.x > injectionSwitch.y) // always false
+#     {
+#     discard;
+#     return vec3(1.0);
+#     }
+# }
+# void main()
+# {
+#
+#     computePoint();
+#     if (false)
+#     {
+#     }
+#     if (gl_FragCoord.x < 0.0)
+#     {
+#         return;
+#     }
+#     computePoint();
+#
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 60
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %40 %51
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "computePoint("
+               OpName %12 "buf0"
+               OpMemberName %12 0 "injectionSwitch"
+               OpName %14 ""
+               OpName %40 "gl_FragCoord"
+               OpName %51 "_GLF_color"
+               OpMemberDecorate %12 0 Offset 0
+               OpDecorate %12 Block
+               OpDecorate %14 DescriptorSet 0
+               OpDecorate %14 Binding 0
+               OpDecorate %40 BuiltIn FragCoord
+               OpDecorate %51 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 3
+          %8 = OpTypeFunction %7
+         %11 = OpTypeVector %6 2
+         %12 = OpTypeStruct %11
+         %13 = OpTypePointer Uniform %12
+         %14 = OpVariable %13 Uniform
+         %15 = OpTypeInt 32 1
+         %16 = OpConstant %15 0
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %19 = OpTypePointer Uniform %6
+         %22 = OpConstant %17 1
+         %25 = OpTypeBool
+         %30 = OpConstant %6 1
+         %31 = OpConstantComposite %7 %30 %30 %30
+         %35 = OpConstantFalse %25
+         %38 = OpTypeVector %6 4
+         %39 = OpTypePointer Input %38
+         %40 = OpVariable %39 Input
+         %41 = OpTypePointer Input %6
+         %44 = OpConstant %6 0
+         %50 = OpTypePointer Output %38
+         %51 = OpVariable %50 Output
+         %52 = OpConstantComposite %38 %30 %44 %44 %30
+         %57 = OpTypePointer Function %25
+         %59 = OpConstantTrue %25
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %58 = OpVariable %57 Function %35
+               OpBranch %54
+         %54 = OpLabel
+         %34 = OpFunctionCall %7 %9
+               OpLoopMerge %53 %56 None
+               OpBranch %37
+         %37 = OpLabel
+         %42 = OpAccessChain %41 %40 %18
+         %43 = OpLoad %6 %42
+         %45 = OpFOrdLessThan %25 %43 %44
+               OpSelectionMerge %47 None
+               OpBranchConditional %45 %46 %47
+         %46 = OpLabel
+               OpStore %58 %59
+               OpBranch %53
+         %47 = OpLabel
+         %49 = OpFunctionCall %7 %9
+               OpStore %51 %52
+               OpStore %58 %59
+               OpBranch %53
+         %56 = OpLabel
+               OpBranch %54
+         %53 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %9 = OpFunction %7 None %8
+         %10 = OpLabel
+         %20 = OpAccessChain %19 %14 %16 %18
+         %21 = OpLoad %6 %20
+         %23 = OpAccessChain %19 %14 %16 %22
+         %24 = OpLoad %6 %23
+         %26 = OpFOrdGreaterThan %25 %21 %24
+               OpSelectionMerge %28 None
+               OpBranchConditional %26 %27 %28
+         %27 = OpLabel
+               OpKill
+         %28 = OpLabel
+         %33 = OpUndef %7
+               OpReturnValue %33
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement.amber
new file mode 100644
index 0000000..70908b0
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-discard-statement.amber
@@ -0,0 +1,196 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with unreachable discard statement
+
+# The test passes because the shader always writes the color red. The discard statement is never reached.
+
+# Optimized using spirv-opt with the following arguments:
+# '--scalar-replacement=100'
+# '--private-to-local'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-dead-branches'
+# '--private-to-local'
+# '--copy-propagate-arrays'
+# '--scalar-replacement=100'
+# '--combine-access-chains'
+# '--vector-dce'
+# '--convert-local-access-chains'
+# '--if-conversion'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--ccp'
+# '--eliminate-dead-branches'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--combine-access-chains'
+# '--eliminate-local-single-block'
+# '--copy-propagate-arrays'
+# '--ccp'
+# '--private-to-local'
+# '--private-to-local'
+# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# vec3 mand()
+# {
+#     for (int k = 0; k < 1000; k++)
+#         return vec3(1.0);
+#
+#     discard;    // This statement is never reached
+#     return vec3(1.0);
+# }
+#
+# void main()
+# {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#
+#     for (int i = 0; i < 4; i++)
+#         mand();
+#
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 63
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %35
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "mand("
+               OpName %13 "k"
+               OpName %35 "_GLF_color"
+               OpName %38 "i"
+               OpDecorate %13 RelaxedPrecision
+               OpDecorate %20 RelaxedPrecision
+               OpDecorate %35 Location 0
+               OpDecorate %38 RelaxedPrecision
+               OpDecorate %44 RelaxedPrecision
+               OpDecorate %48 RelaxedPrecision
+               OpDecorate %49 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 3
+          %8 = OpTypeFunction %7
+         %11 = OpTypeInt 32 1
+         %12 = OpTypePointer Function %11
+         %14 = OpConstant %11 0
+         %21 = OpConstant %11 1000
+         %22 = OpTypeBool
+         %24 = OpConstant %6 1
+         %25 = OpConstantComposite %7 %24 %24 %24
+         %28 = OpConstant %11 1
+         %33 = OpTypeVector %6 4
+         %34 = OpTypePointer Output %33
+         %35 = OpVariable %34 Output
+         %36 = OpConstant %6 0
+         %37 = OpConstantComposite %33 %24 %36 %36 %24
+         %45 = OpConstant %11 4
+         %51 = OpTypePointer Function %7
+         %57 = OpConstantFalse %22
+         %58 = OpTypePointer Function %22
+         %60 = OpConstantTrue %22
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %38 = OpVariable %12 Function
+               OpStore %35 %37
+               OpStore %38 %14
+               OpBranch %39
+         %39 = OpLabel
+         %44 = OpLoad %11 %38
+         %46 = OpSLessThan %22 %44 %45
+               OpLoopMerge %41 %40 None
+               OpBranchConditional %46 %40 %41
+         %40 = OpLabel
+         %47 = OpFunctionCall %7 %9
+         %48 = OpLoad %11 %38
+         %49 = OpIAdd %11 %48 %28
+               OpStore %38 %49
+               OpBranch %39
+         %41 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %9 = OpFunction %7 None %8
+         %10 = OpLabel
+         %59 = OpVariable %58 Function %57
+         %52 = OpVariable %51 Function
+         %13 = OpVariable %12 Function
+               OpBranch %54
+         %54 = OpLabel
+               OpStore %13 %14
+               OpLoopMerge %50 %56 None
+               OpBranch %15
+         %15 = OpLabel
+         %20 = OpLoad %11 %13
+         %23 = OpSLessThan %22 %20 %21
+               OpLoopMerge %17 %18 None
+               OpBranchConditional %23 %16 %17
+         %16 = OpLabel
+               OpStore %59 %60
+               OpStore %52 %25
+               OpBranch %17
+         %18 = OpLabel
+               OpBranch %15
+         %17 = OpLabel
+         %62 = OpLoad %22 %59
+               OpSelectionMerge %61 None
+               OpBranchConditional %62 %50 %61
+         %61 = OpLabel
+               OpKill
+         %56 = OpLabel
+               OpBranch %54
+         %50 = OpLabel
+         %53 = OpLoad %7 %52
+               OpReturnValue %53
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-return-in-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-return-in-loop.amber
new file mode 100644
index 0000000..b6fe244
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-return-in-loop.amber
@@ -0,0 +1,150 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with an unreachable return in a loop
+
+# The test passes because main always writes the color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--simplify-instructions'
+# '--eliminate-local-single-store'
+# '--simplify-instructions'
+# '--inline-entry-points-exhaustive'
+# '--reduce-load-size'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--inline-entry-points-exhaustive'
+# '--private-to-local'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--copy-propagate-arrays'
+# '--convert-local-access-chains'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-local-single-store'
+# '--copy-propagate-arrays'
+# '--scalar-replacement=100'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-branches'
+# '--if-conversion'
+# '--copy-propagate-arrays'
+# '--reduce-load-size'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-code-aggressive'
+# '--convert-local-access-chains'
+# '--private-to-local'
+# '--if-conversion'
+# spirv-opt commit hash: ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#   for(int i = 1; i < 0; i++)
+#     return;
+#
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 43
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %25
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %25 "_GLF_color"
+               OpDecorate %25 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %9 = OpConstant %6 1
+         %16 = OpConstant %6 0
+         %17 = OpTypeBool
+         %22 = OpTypeFloat 32
+         %23 = OpTypeVector %22 4
+         %24 = OpTypePointer Output %23
+         %25 = OpVariable %24 Output
+         %26 = OpConstant %22 1
+         %27 = OpConstant %22 0
+         %28 = OpConstantComposite %23 %26 %27 %27 %26
+         %33 = OpConstantFalse %17
+         %36 = OpConstantTrue %17
+         %42 = OpUndef %17
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpBranch %30
+         %30 = OpLabel
+         %41 = OpPhi %17 %33 %5 %42 %32
+               OpLoopMerge %29 %32 None
+               OpBranch %10
+         %10 = OpLabel
+         %40 = OpPhi %17 %41 %30 %42 %13
+         %18 = OpSLessThan %17 %9 %16
+               OpLoopMerge %12 %13 None
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+               OpBranch %12
+         %13 = OpLabel
+               OpBranch %10
+         %12 = OpLabel
+         %39 = OpPhi %17 %40 %10 %36 %11
+               OpSelectionMerge %37 None
+               OpBranchConditional %39 %29 %37
+         %37 = OpLabel
+               OpStore %25 %28
+               OpBranch %29
+         %32 = OpLabel
+               OpBranch %30
+         %29 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-switch-case-with-discards.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-switch-case-with-discards.amber
new file mode 100644
index 0000000..2cc1706
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/unreachable-switch-case-with-discards.amber
@@ -0,0 +1,228 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader with a switch statement containing unreachable discards
+
+# The test passes because the shader always writes the color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 6b072126595dd8c2448eb1fda616251c5e6d7079
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# vec3 drawShape(vec2 square)
+# {
+#  switch(int(injectionSwitch.x))
+#   {
+#    case 0:
+#    return vec3(1.0, 0.0, 0.0);
+#    case 67:
+#    do
+#     {
+#      if(1.0 < square.x)
+#       {
+#       }
+#      else
+#       {
+#        discard;
+#       }
+#      discard;
+#     }
+#    while(true);
+#   }
+#  return vec3(1.0);
+# }
+# void main()
+# {
+#  vec2 center;
+#  vec3 color = vec3(0.0);
+#  for(
+#      int i = 0;
+#      i < 1;
+#      i++
+#  )
+#   {
+#    color = drawShape(center);
+#    if(length(color) <= 0.0)
+#     {
+#      continue;
+#     }
+#   }
+#   _GLF_color = vec4(color, 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 139
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %78
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %14 "buf0"
+               OpMemberName %14 0 "injectionSwitch"
+               OpName %16 ""
+               OpName %78 "_GLF_color"
+               OpMemberDecorate %14 0 Offset 0
+               OpDecorate %14 Block
+               OpDecorate %16 DescriptorSet 0
+               OpDecorate %16 Binding 0
+               OpDecorate %75 RelaxedPrecision
+               OpDecorate %78 Location 0
+               OpDecorate %132 RelaxedPrecision
+               OpDecorate %132 RelaxedPrecision
+               OpDecorate %132 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %9 = OpTypeVector %6 3
+         %14 = OpTypeStruct %7
+         %15 = OpTypePointer Uniform %14
+         %16 = OpVariable %15 Uniform
+         %17 = OpTypeInt 32 1
+         %18 = OpConstant %17 0
+         %19 = OpTypeInt 32 0
+         %20 = OpConstant %19 0
+         %21 = OpTypePointer Uniform %6
+         %28 = OpConstant %6 1
+         %29 = OpConstant %6 0
+         %30 = OpConstantComposite %9 %28 %29 %29
+         %39 = OpTypeBool
+         %48 = OpConstantComposite %9 %28 %28 %28
+         %53 = OpConstantComposite %9 %29 %29 %29
+         %62 = OpConstant %17 1
+         %76 = OpTypeVector %6 4
+         %77 = OpTypePointer Output %76
+         %78 = OpVariable %77 Output
+        %135 = OpUndef %7
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpBranch %56
+         %56 = OpLabel
+        %133 = OpPhi %9 %53 %5 %137 %59
+        %132 = OpPhi %17 %18 %5 %75 %59
+         %63 = OpSLessThan %39 %132 %62
+               OpLoopMerge %58 %59 None
+               OpBranchConditional %63 %57 %58
+         %57 = OpLabel
+               OpBranch %104
+        %104 = OpLabel
+               OpLoopMerge %105 %106 None
+               OpBranch %107
+        %107 = OpLabel
+        %108 = OpAccessChain %21 %16 %18 %20
+        %109 = OpLoad %6 %108
+        %110 = OpConvertFToS %17 %109
+               OpSelectionMerge %111 None
+               OpSwitch %110 %111 0 %112 67 %113
+        %113 = OpLabel
+               OpBranch %114
+        %114 = OpLabel
+               OpLoopMerge %115 %116 None
+               OpBranch %117
+        %117 = OpLabel
+        %119 = OpCompositeExtract %6 %135 0
+        %120 = OpFOrdLessThan %39 %28 %119
+               OpSelectionMerge %122 None
+               OpBranchConditional %120 %122 %123
+        %123 = OpLabel
+        %124 = OpFunctionCall %2 %84
+        %125 = OpUndef %9
+               OpBranch %115
+        %122 = OpLabel
+        %126 = OpFunctionCall %2 %84
+        %127 = OpUndef %9
+               OpBranch %115
+        %116 = OpLabel
+               OpBranch %114
+        %115 = OpLabel
+        %138 = OpPhi %9 %125 %123 %127 %122
+               OpBranch %105
+        %112 = OpLabel
+               OpBranch %105
+        %111 = OpLabel
+               OpBranch %105
+        %106 = OpLabel
+               OpBranch %104
+        %105 = OpLabel
+        %137 = OpPhi %9 %138 %115 %30 %112 %48 %111
+         %69 = OpExtInst %6 %1 Length %137
+         %70 = OpFOrdLessThanEqual %39 %69 %29
+               OpSelectionMerge %72 None
+               OpBranchConditional %70 %71 %72
+         %71 = OpLabel
+               OpBranch %59
+         %72 = OpLabel
+               OpBranch %59
+         %59 = OpLabel
+         %75 = OpIAdd %17 %132 %62
+               OpBranch %56
+         %58 = OpLabel
+         %80 = OpCompositeExtract %6 %133 0
+         %81 = OpCompositeExtract %6 %133 1
+         %82 = OpCompositeExtract %6 %133 2
+         %83 = OpCompositeConstruct %76 %80 %81 %82 %28
+               OpStore %78 %83
+               OpReturn
+               OpFunctionEnd
+         %84 = OpFunction %2 None %3
+         %85 = OpLabel
+               OpKill
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/while-function-always-false.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/while-function-always-false.amber
new file mode 100644
index 0000000..786b18c
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/while-function-always-false.amber
@@ -0,0 +1,166 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with an always false while function
+
+# The test passes because the shader always writes the color red (while function in the shader is always false)
+
+# Optimized using spirv-opt with the following arguments:
+# '--redundancy-elimination'
+# '--reduce-load-size'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# spirv-opt commit hash: 230c9e437146e48ec58adb4433890403c23c98fa
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# void main()
+# {
+#   _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#  do
+#   {
+#    for(
+#        int j = int(injectionSwitch.x);
+#        j < 2;
+#        ++j
+#    )
+#     {
+#      return;
+#     }
+#   }
+#  while(0.0 > injectionSwitch.y);
+#  int(injectionSwitch.y);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 52
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %9
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %9 "_GLF_color"
+               OpName %19 "j"
+               OpName %21 "buf0"
+               OpMemberName %21 0 "injectionSwitch"
+               OpName %23 ""
+               OpDecorate %9 Location 0
+               OpDecorate %19 RelaxedPrecision
+               OpMemberDecorate %21 0 Offset 0
+               OpDecorate %21 Block
+               OpDecorate %23 DescriptorSet 0
+               OpDecorate %23 Binding 0
+               OpDecorate %30 RelaxedPrecision
+               OpDecorate %36 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 4
+          %8 = OpTypePointer Output %7
+          %9 = OpVariable %8 Output
+         %10 = OpConstant %6 1
+         %11 = OpConstant %6 0
+         %12 = OpConstantComposite %7 %10 %11 %11 %10
+         %17 = OpTypeInt 32 1
+         %18 = OpTypePointer Function %17
+         %20 = OpTypeVector %6 2
+         %21 = OpTypeStruct %20
+         %22 = OpTypePointer Uniform %21
+         %23 = OpVariable %22 Uniform
+         %24 = OpConstant %17 0
+         %25 = OpTypeInt 32 0
+         %26 = OpConstant %25 0
+         %27 = OpTypePointer Uniform %6
+         %37 = OpConstant %17 2
+         %38 = OpTypeBool
+         %42 = OpConstant %17 1
+         %44 = OpConstant %25 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %19 = OpVariable %18 Function
+               OpStore %9 %12
+               OpBranch %13
+         %13 = OpLabel
+         %28 = OpAccessChain %27 %23 %24 %26
+         %29 = OpLoad %6 %28
+         %30 = OpConvertFToS %17 %29
+               OpStore %19 %30
+               OpLoopMerge %15 %33 None
+               OpBranch %31
+         %31 = OpLabel
+         %36 = OpLoad %17 %19
+         %39 = OpSLessThan %38 %36 %37
+               OpLoopMerge %51 %34 None
+               OpBranchConditional %39 %32 %51
+         %32 = OpLabel
+               OpReturn
+         %34 = OpLabel
+               OpBranch %31
+         %51 = OpLabel
+               OpBranch %33
+         %33 = OpLabel
+         %45 = OpAccessChain %27 %23 %24 %44
+         %46 = OpLoad %6 %45
+         %47 = OpFOrdGreaterThan %38 %11 %46
+               OpBranchConditional %47 %13 %15
+         %15 = OpLabel
+         %50 = OpConvertFToS %17 %46
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/wrong-color-in-always-false-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/wrong-color-in-always-false-if.amber
new file mode 100644
index 0000000..302d42a
--- /dev/null
+++ b/external/vulkancts/data/vulkan/amber/graphicsfuzz/wrong-color-in-always-false-if.amber
@@ -0,0 +1,151 @@
+#!amber
+
+# Copyright 2019 Google LLC
+#
+# 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.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with wrong color write in false if
+
+# The test passes because the shader always writes color red.
+# Wrong color mix and write is inside a false if statement.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+#
+# void main()
+# {
+#     float height;
+#     height = 256.0;
+#
+#     if (injectionSwitch.y < 0.0) // always false
+#     {
+#         _GLF_color = mix(vec4(30.18, 8840.7235, 469.970, 18.24), vec4(9.9, 0.1, 1169.5387, 55.79), vec4(7612.9451, 797.011, height, 9.0));
+#     }
+#
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0); // Write color red
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 47
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %28
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 310
+               OpName %4 "main"
+               OpName %8 "height"
+               OpName %11 "buf0"
+               OpMemberName %11 0 "injectionSwitch"
+               OpName %13 ""
+               OpName %28 "_GLF_color"
+               OpMemberDecorate %11 0 Offset 0
+               OpDecorate %11 Block
+               OpDecorate %13 DescriptorSet 0
+               OpDecorate %13 Binding 0
+               OpDecorate %28 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypePointer Function %6
+          %9 = OpConstant %6 256
+         %10 = OpTypeVector %6 2
+         %11 = OpTypeStruct %10
+         %12 = OpTypePointer Uniform %11
+         %13 = OpVariable %12 Uniform
+         %14 = OpTypeInt 32 1
+         %15 = OpConstant %14 0
+         %16 = OpTypeInt 32 0
+         %17 = OpConstant %16 1
+         %18 = OpTypePointer Uniform %6
+         %21 = OpConstant %6 0
+         %22 = OpTypeBool
+         %26 = OpTypeVector %6 4
+         %27 = OpTypePointer Output %26
+         %28 = OpVariable %27 Output
+         %29 = OpConstant %6 30.1800003
+         %30 = OpConstant %6 8840.72363
+         %31 = OpConstant %6 469.970001
+         %32 = OpConstant %6 18.2399998
+         %33 = OpConstantComposite %26 %29 %30 %31 %32
+         %34 = OpConstant %6 9.89999962
+         %35 = OpConstant %6 0.100000001
+         %36 = OpConstant %6 1169.5387
+         %37 = OpConstant %6 55.7900009
+         %38 = OpConstantComposite %26 %34 %35 %36 %37
+         %39 = OpConstant %6 7612.94531
+         %40 = OpConstant %6 797.010986
+         %42 = OpConstant %6 9
+         %45 = OpConstant %6 1
+         %46 = OpConstantComposite %26 %45 %21 %21 %45
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %8 = OpVariable %7 Function
+               OpStore %8 %9
+         %19 = OpAccessChain %18 %13 %15 %17
+         %20 = OpLoad %6 %19
+         %23 = OpFOrdLessThan %22 %20 %21
+               OpSelectionMerge %25 None
+               OpBranchConditional %23 %24 %25
+         %24 = OpLabel
+         %41 = OpLoad %6 %8
+         %43 = OpCompositeConstruct %26 %39 %40 %41 %42
+         %44 = OpExtInst %26 %1 FMix %33 %38 %43
+               OpStore %28 %44
+               OpBranch %25
+         %25 = OpLabel
+               OpStore %28 %46
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/function_nonwritable.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/function_nonwritable.amber
index c2492d6..e83ff19 100644
--- a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/function_nonwritable.amber
+++ b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/function_nonwritable.amber
@@ -86,8 +86,11 @@
 %out_gep = OpAccessChain %ptr_ssbo_uint %out_var %uint_0 %out_idx
 OpStore %out_gep %add
 %inner_eq = OpIEqual %bool %inc_j %uint_4
-OpLoopMerge %outer_latch %inner_loop None
-OpBranchConditional %inner_eq %outer_latch %inner_loop
+OpLoopMerge %inner_merge %inner_loop None
+OpBranchConditional %inner_eq %inner_merge %inner_loop
+
+%inner_merge = OpLabel
+OpBranch %outer_latch
 
 %outer_latch = OpLabel
 OpBranchConditional %outer_eq %outer_merge %outer_loop
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/private_nonwritable.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/private_nonwritable.amber
index 980db3e..4b198d2 100644
--- a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/private_nonwritable.amber
+++ b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/nonwritable/private_nonwritable.amber
@@ -86,8 +86,11 @@
 %out_gep = OpAccessChain %ptr_ssbo_uint %out_var %uint_0 %out_idx
 OpStore %out_gep %add
 %inner_eq = OpIEqual %bool %inc_j %uint_4
-OpLoopMerge %outer_latch %inner_loop None
-OpBranchConditional %inner_eq %outer_latch %inner_loop
+OpLoopMerge %inner_merge %inner_loop None
+OpBranchConditional %inner_eq %inner_merge %inner_loop
+
+%inner_merge = OpLabel
+OpBranch %outer_latch
 
 %outer_latch = OpLabel
 OpBranchConditional %outer_eq %outer_merge %outer_loop
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrdiff/variable_pointers_vars_ssbo_2_diff.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrdiff/variable_pointers_vars_ssbo_2_diff.amber
index 093e160..a5ae58c 100644
--- a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrdiff/variable_pointers_vars_ssbo_2_diff.amber
+++ b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrdiff/variable_pointers_vars_ssbo_2_diff.amber
@@ -101,21 +101,24 @@
 %body = OpLabel
 %i_mod_3 = OpSMod %int %i %int_3
 %cmp_vs_0 = OpIEqual %bool %i_mod_3 %int_0
-OpSelectionMerge %continue None
+OpSelectionMerge %if_merge None
 OpBranchConditional %cmp_vs_0 %then %else
 
 %then = OpLabel
 %then_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_n1
 %then_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_1
-OpBranch %continue
+OpBranch %if_merge
 %else = OpLabel
 %else_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_1
 %else_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_n1
+OpBranch %if_merge
+
+%if_merge = OpLabel
+%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
+%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpBranch %continue
 
 %continue = OpLabel
-%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
-%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpStore %func_gep_0 %next_0
 OpStore %func_gep_1 %next_1
 %cmp = OpSGreaterThanEqual %bool %i %n
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrequal/variable_pointers_ssbo_2_equal.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrequal/variable_pointers_ssbo_2_equal.amber
index bc895b6..6da8ebb 100644
--- a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrequal/variable_pointers_ssbo_2_equal.amber
+++ b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrequal/variable_pointers_ssbo_2_equal.amber
@@ -92,21 +92,24 @@
 %body = OpLabel
 %i_mod_3 = OpSMod %int %i %int_3
 %cmp_vs_0 = OpIEqual %bool %i_mod_3 %int_0
-OpSelectionMerge %continue None
+OpSelectionMerge %if_merge None
 OpBranchConditional %cmp_vs_0 %then %else
 
 %then = OpLabel
 %then_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_n1
 %then_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_1
-OpBranch %continue
+OpBranch %if_merge
 %else = OpLabel
 %else_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_1
 %else_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_n1
+OpBranch %if_merge
+
+%if_merge = OpLabel
+%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
+%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpBranch %continue
 
 %continue = OpLabel
-%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
-%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpStore %func_gep_0 %next_0
 OpStore %func_gep_1 %next_1
 %cmp = OpSGreaterThanEqual %bool %i %n
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrnotequal/variable_pointers_ssbo_2_not_equal.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrnotequal/variable_pointers_ssbo_2_not_equal.amber
index 2c7a306..0bcd960 100644
--- a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrnotequal/variable_pointers_ssbo_2_not_equal.amber
+++ b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/spirv1p4/opptrnotequal/variable_pointers_ssbo_2_not_equal.amber
@@ -92,21 +92,24 @@
 %body = OpLabel
 %i_mod_3 = OpSMod %int %i %int_3
 %cmp_vs_0 = OpIEqual %bool %i_mod_3 %int_0
-OpSelectionMerge %continue None
+OpSelectionMerge %if_merge None
 OpBranchConditional %cmp_vs_0 %then %else
 
 %then = OpLabel
 %then_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_n1
 %then_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_1
-OpBranch %continue
+OpBranch %if_merge
 %else = OpLabel
 %else_0_next = OpPtrAccessChain %ptr_ssbo_int %gep_0 %int_1
 %else_1_next = OpPtrAccessChain %ptr_ssbo_int %gep_1 %int_n1
+OpBranch %if_merge
+
+%if_merge = OpLabel
+%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
+%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpBranch %continue
 
 %continue = OpLabel
-%next_0 = OpPhi %ptr_ssbo_int %then_0_next %then %else_0_next %else
-%next_1 = OpPhi %ptr_ssbo_int %then_1_next %then %else_1_next %else
 OpStore %func_gep_0 %next_0
 OpStore %func_gep_1 %next_1
 %cmp = OpSGreaterThanEqual %bool %i %n
diff --git a/external/vulkancts/framework/vulkan/CMakeLists.txt b/external/vulkancts/framework/vulkan/CMakeLists.txt
index ee7c3fe..c307da7 100644
--- a/external/vulkancts/framework/vulkan/CMakeLists.txt
+++ b/external/vulkancts/framework/vulkan/CMakeLists.txt
@@ -71,6 +71,9 @@
 	vkDeviceFeatures.hpp
 	vkDeviceFeatures.cpp
 	vkDeviceFeatures.inl
+	vkDeviceProperties.hpp
+	vkDeviceProperties.cpp
+	vkDeviceProperties.inl
 	)
 
 set(VKUTIL_SRCS
@@ -126,5 +129,16 @@
 add_library(vkutilnoshader STATIC ${VKUTILNOSHADER_SRCS})
 target_link_libraries(vkutilnoshader ${VKUTILNOSHADER_LIBS})
 
+if (DEQP_USE_X11)
+	find_package(X11 REQUIRED)
+	target_link_libraries(vkutilnoshader ${X11_LIBRARIES})
+	add_definitions(-DDEQP_SUPPORT_X11=1)
+	if (DEQP_USE_XCB)
+		find_package(XCB REQUIRED)
+		target_link_libraries(vkutilnoshader ${XCB_LIBRARIES})
+		add_definitions(-DDEQP_SUPPORT_XCB=1)
+	endif ()
+endif()
+
 add_library(vkutil STATIC ${VKUTIL_SRCS})
 target_link_libraries(vkutil ${VKUTIL_LIBS})
diff --git a/external/vulkancts/framework/vulkan/vkBasicTypes.inl b/external/vulkancts/framework/vulkan/vkBasicTypes.inl
index beabf32..4ee37bd 100644
--- a/external/vulkancts/framework/vulkan/vkBasicTypes.inl
+++ b/external/vulkancts/framework/vulkan/vkBasicTypes.inl
@@ -3,10 +3,11 @@
  */
 #define VK_API_VERSION_1_0					(static_cast<deUint32>			(VK_MAKE_VERSION(1, 0, 0)))
 #define VK_API_VERSION_1_1					(static_cast<deUint32>			(VK_MAKE_VERSION(1, 1, 0)))
+#define VK_API_VERSION_1_2					(static_cast<deUint32>			(VK_MAKE_VERSION(1, 2, 0)))
 #define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE	(static_cast<size_t>			(256))
 #define VK_MAX_EXTENSION_NAME_SIZE			(static_cast<size_t>			(256))
-#define VK_MAX_DRIVER_NAME_SIZE_KHR			(static_cast<size_t>			(256))
-#define VK_MAX_DRIVER_INFO_SIZE_KHR			(static_cast<size_t>			(256))
+#define VK_MAX_DRIVER_NAME_SIZE				(static_cast<size_t>			(256))
+#define VK_MAX_DRIVER_INFO_SIZE				(static_cast<size_t>			(256))
 #define VK_UUID_SIZE						(static_cast<size_t>			(16))
 #define VK_LUID_SIZE						(static_cast<size_t>			(8))
 #define VK_MAX_MEMORY_TYPES					(static_cast<size_t>			(32))
@@ -22,7 +23,7 @@
 #define VK_WHOLE_SIZE						(static_cast<vk::VkDeviceSize>	((~0ULL)))
 #define VK_TRUE								(static_cast<vk::VkBool32>		(1))
 #define VK_FALSE							(static_cast<vk::VkBool32>		(0))
-#define VK_API_MAX_FRAMEWORK_VERSION		VK_API_VERSION_1_1
+#define VK_API_MAX_FRAMEWORK_VERSION		VK_API_VERSION_1_2
 
 VK_DEFINE_HANDLE					(VkInstance,						HANDLE_TYPE_INSTANCE);
 VK_DEFINE_HANDLE					(VkPhysicalDevice,					HANDLE_TYPE_PHYSICAL_DEVICE);
@@ -89,8 +90,11 @@
 	VK_ERROR_TOO_MANY_OBJECTS								= -10,
 	VK_ERROR_FORMAT_NOT_SUPPORTED							= -11,
 	VK_ERROR_FRAGMENTED_POOL								= -12,
+	VK_ERROR_UNKNOWN										= -13,
 	VK_ERROR_OUT_OF_POOL_MEMORY								= -1000069000,
 	VK_ERROR_INVALID_EXTERNAL_HANDLE						= -1000072003,
+	VK_ERROR_FRAGMENTATION									= -1000161000,
+	VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS					= -1000257000,
 	VK_ERROR_SURFACE_LOST_KHR								= -1000000000,
 	VK_ERROR_NATIVE_WINDOW_IN_USE_KHR						= -1000000001,
 	VK_SUBOPTIMAL_KHR										= 1000001003,
@@ -99,13 +103,13 @@
 	VK_ERROR_VALIDATION_FAILED_EXT							= -1000011001,
 	VK_ERROR_INVALID_SHADER_NV								= -1000012000,
 	VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT	= -1000158000,
-	VK_ERROR_FRAGMENTATION_EXT								= -1000161000,
 	VK_ERROR_NOT_PERMITTED_EXT								= -1000174001,
 	VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT			= -1000255000,
-	VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR				= -1000244000,
 	VK_ERROR_OUT_OF_POOL_MEMORY_KHR							= VK_ERROR_OUT_OF_POOL_MEMORY,
 	VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR					= VK_ERROR_INVALID_EXTERNAL_HANDLE,
-	VK_ERROR_INVALID_DEVICE_ADDRESS_EXT						= VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR,
+	VK_ERROR_FRAGMENTATION_EXT								= VK_ERROR_FRAGMENTATION,
+	VK_ERROR_INVALID_DEVICE_ADDRESS_EXT						= VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+	VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR				= VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
 	VK_RESULT_MAX_ENUM										= 0x7FFFFFFF,
 };
 
@@ -225,6 +229,56 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES							= 1000168000,
 	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT										= 1000168001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES					= 1000063000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES								= 49,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES								= 50,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES								= 51,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES								= 52,
+	VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO										= 1000147000,
+	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2											= 1000109000,
+	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2											= 1000109001,
+	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2												= 1000109002,
+	VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2												= 1000109003,
+	VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2											= 1000109004,
+	VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO												= 1000109005,
+	VK_STRUCTURE_TYPE_SUBPASS_END_INFO													= 1000109006,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES								= 1000177000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES									= 1000196000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES						= 1000180000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES						= 1000082000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES							= 1000197000,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO					= 1000161000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES						= 1000161001,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES					= 1000161002,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO			= 1000161003,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT			= 1000161004,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES					= 1000199000,
+	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE							= 1000199001,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES						= 1000221000,
+	VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO									= 1000246000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES					= 1000130000,
+	VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO								= 1000130001,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES						= 1000211000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES					= 1000108000,
+	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO								= 1000108001,
+	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO									= 1000108002,
+	VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO									= 1000108003,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES			= 1000253000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES			= 1000175000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES			= 1000241000,
+	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT								= 1000241001,
+	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT								= 1000241002,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES							= 1000261000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES						= 1000207000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES						= 1000207001,
+	VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO										= 1000207002,
+	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO									= 1000207003,
+	VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO												= 1000207004,
+	VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO												= 1000207005,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES					= 1000257000,
+	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO										= 1000244001,
+	VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO							= 1000257002,
+	VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO						= 1000257003,
+	VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO							= 1000257004,
 	VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR											= 1000001000,
 	VK_STRUCTURE_TYPE_PRESENT_INFO_KHR													= 1000001001,
 	VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR								= 1000060007,
@@ -284,7 +338,6 @@
 	VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT			= 1000081000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT				= 1000081001,
 	VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT								= 1000081002,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR					= 1000082000,
 	VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR												= 1000084000,
 	VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX										= 1000086000,
 	VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX							= 1000086001,
@@ -308,17 +361,6 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT					= 1000102000,
 	VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT			= 1000102001,
 	VK_STRUCTURE_TYPE_HDR_METADATA_EXT													= 1000105000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR				= 1000108000,
-	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR							= 1000108001,
-	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR								= 1000108002,
-	VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR								= 1000108003,
-	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR										= 1000109000,
-	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR										= 1000109001,
-	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR											= 1000109002,
-	VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR											= 1000109003,
-	VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR										= 1000109004,
-	VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR											= 1000109005,
-	VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR												= 1000109006,
 	VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR							= 1000111000,
 	VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR								= 1000114000,
 	VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR								= 1000114001,
@@ -353,8 +395,6 @@
 	VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID						= 1000129003,
 	VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID					= 1000129004,
 	VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID											= 1000129005,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT				= 1000130000,
-	VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT							= 1000130001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT					= 1000138000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT				= 1000138001,
 	VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT						= 1000138002,
@@ -364,7 +404,6 @@
 	VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT					= 1000143002,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT					= 1000143003,
 	VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT										= 1000143004,
-	VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR									= 1000147000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT				= 1000148000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT			= 1000148001,
 	VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT				= 1000148002,
@@ -380,11 +419,6 @@
 	VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT							= 1000158005,
 	VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT									= 1000160000,
 	VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT					= 1000160001,
-	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT				= 1000161000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT					= 1000161001,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT				= 1000161002,
-	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT		= 1000161003,
-	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT		= 1000161004,
 	VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV			= 1000164000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV					= 1000164001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV					= 1000164002,
@@ -405,12 +439,9 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT					= 1000170000,
 	VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT				= 1000170001,
 	VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT						= 1000174000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR		= 1000175000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR							= 1000177000,
 	VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT								= 1000178000,
 	VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT								= 1000178001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT				= 1000178002,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR					= 1000180000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR							= 1000181000,
 	VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD							= 1000183000,
 	VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT										= 1000184000,
@@ -421,10 +452,6 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT				= 1000190002,
 	VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP											= 1000191000,
 	VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT						= 1000192000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR								= 1000196000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR						= 1000197000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR				= 1000199000,
-	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR						= 1000199001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV			= 1000201000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV							= 1000202000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV							= 1000202001,
@@ -434,12 +461,6 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV						= 1000205002,
 	VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV												= 1000206000,
 	VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV								= 1000206001,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR					= 1000207000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR					= 1000207001,
-	VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR									= 1000207002,
-	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR								= 1000207003,
-	VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR											= 1000207004,
-	VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR											= 1000207005,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL			= 1000209000,
 	VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL										= 1000210000,
 	VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL								= 1000210001,
@@ -447,7 +468,6 @@
 	VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL								= 1000210003,
 	VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL									= 1000210004,
 	VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL						= 1000210005,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR					= 1000211000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT						= 1000212000,
 	VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD						= 1000213000,
 	VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD						= 1000213001,
@@ -456,7 +476,6 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT					= 1000218000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT				= 1000218001,
 	VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT					= 1000218002,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT					= 1000221000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT				= 1000225000,
 	VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT		= 1000225001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT				= 1000225002,
@@ -467,12 +486,9 @@
 	VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT									= 1000238001,
 	VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR								= 1000239000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV	= 1000240000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR		= 1000241000,
-	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR							= 1000241001,
-	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR							= 1000241002,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT				= 1000244000,
 	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT								= 1000244002,
-	VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT								= 1000246000,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT								= 1000245000,
 	VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT											= 1000247000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV					= 1000249000,
 	VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV									= 1000249001,
@@ -482,20 +498,13 @@
 	VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV							= 1000250002,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT			= 1000251000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT					= 1000252000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR		= 1000253000,
 	VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT							= 1000255000,
 	VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT					= 1000255002,
 	VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT						= 1000255001,
 	VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT									= 1000256000,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR				= 1000257000,
-	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR									= 1000244001,
-	VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR						= 1000257002,
-	VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR					= 1000257003,
-	VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR						= 1000257004,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT					= 1000259000,
 	VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT					= 1000259001,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT					= 1000259002,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT						= 1000261000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT						= 1000265000,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR		= 1000269000,
 	VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR													= 1000269001,
@@ -541,10 +550,22 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
 	VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR									= VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
 	VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR									= VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
-	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR							= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR							= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
 	VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR						= VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
 	VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT											= VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR							= VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
+	VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR								= VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
+	VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR								= VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
+	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR										= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
+	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR										= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
+	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR											= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
+	VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR											= VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+	VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR										= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
+	VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR											= VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
+	VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR												= VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR							= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
 	VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR										= VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
 	VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR										= VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
@@ -556,11 +577,14 @@
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES,
 	VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR									= VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
 	VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR								= VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
+	VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT							= VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
 	VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR								= VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
 	VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
 	VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR						= VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
 	VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR											= VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
 	VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR							= VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
+	VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR									= VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
 	VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR							= VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
 	VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR									= VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
 	VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR									= VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
@@ -569,10 +593,41 @@
 	VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR				= VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
 	VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR										= VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
 	VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR										= VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT				= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT		= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
+	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT		= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
 	VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR									= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR							= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR								= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
+	VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR						= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
+	VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR									= VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR								= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
+	VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR											= VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+	VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR											= VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+	VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR							= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
+	VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR							= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
 	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
-	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT									= VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
+	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT									= VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+	VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT								= VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+	VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR									= VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+	VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR						= VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
+	VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR					= VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
+	VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR						= VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
+	VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
 	VK_STRUCTURE_TYPE_MAX_ENUM															= 0x7FFFFFFF,
 };
 
@@ -935,16 +990,20 @@
 	VK_IMAGE_LAYOUT_PREINITIALIZED									= 8,
 	VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL		= 1000117000,
 	VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL		= 1000117001,
+	VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL						= 1000241000,
+	VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL							= 1000241001,
+	VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL						= 1000241002,
+	VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL						= 1000241003,
 	VK_IMAGE_LAYOUT_PRESENT_SRC_KHR									= 1000001002,
 	VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR								= 1000111000,
 	VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV							= 1000164003,
 	VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT				= 1000218000,
-	VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR					= 1000241000,
-	VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR						= 1000241001,
-	VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR					= 1000241002,
-	VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR					= 1000241003,
 	VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR	= VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
 	VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR	= VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+	VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR					= VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
+	VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR						= VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
+	VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR					= VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
+	VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR					= VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
 	VK_IMAGE_LAYOUT_MAX_ENUM										= 0x7FFFFFFF,
 };
 
@@ -1396,6 +1455,69 @@
 	VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM				= 0x7FFFFFFF,
 };
 
+enum VkDriverId
+{
+	VK_DRIVER_ID_AMD_PROPRIETARY				= 1,
+	VK_DRIVER_ID_AMD_OPEN_SOURCE				= 2,
+	VK_DRIVER_ID_MESA_RADV						= 3,
+	VK_DRIVER_ID_NVIDIA_PROPRIETARY				= 4,
+	VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS		= 5,
+	VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA			= 6,
+	VK_DRIVER_ID_IMAGINATION_PROPRIETARY		= 7,
+	VK_DRIVER_ID_QUALCOMM_PROPRIETARY			= 8,
+	VK_DRIVER_ID_ARM_PROPRIETARY				= 9,
+	VK_DRIVER_ID_GOOGLE_SWIFTSHADER				= 10,
+	VK_DRIVER_ID_GGP_PROPRIETARY				= 11,
+	VK_DRIVER_ID_BROADCOM_PROPRIETARY			= 12,
+	VK_DRIVER_ID_AMD_PROPRIETARY_KHR			= VK_DRIVER_ID_AMD_PROPRIETARY,
+	VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR			= VK_DRIVER_ID_AMD_OPEN_SOURCE,
+	VK_DRIVER_ID_MESA_RADV_KHR					= VK_DRIVER_ID_MESA_RADV,
+	VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR			= VK_DRIVER_ID_NVIDIA_PROPRIETARY,
+	VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR	= VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
+	VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR		= VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
+	VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR	= VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
+	VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR		= VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+	VK_DRIVER_ID_ARM_PROPRIETARY_KHR			= VK_DRIVER_ID_ARM_PROPRIETARY,
+	VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR			= VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
+	VK_DRIVER_ID_GGP_PROPRIETARY_KHR			= VK_DRIVER_ID_GGP_PROPRIETARY,
+	VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR		= VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+	VK_DRIVER_ID_MAX_ENUM						= 0x7FFFFFFF,
+};
+
+enum VkShaderFloatControlsIndependence
+{
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY		= 0,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL				= 1,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE				= 2,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR	= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR			= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR			= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_LAST,
+	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM			= 0x7FFFFFFF,
+};
+
+enum VkSamplerReductionMode
+{
+	VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE		= 0,
+	VK_SAMPLER_REDUCTION_MODE_MIN					= 1,
+	VK_SAMPLER_REDUCTION_MODE_MAX					= 2,
+	VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT	= VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+	VK_SAMPLER_REDUCTION_MODE_MIN_EXT				= VK_SAMPLER_REDUCTION_MODE_MIN,
+	VK_SAMPLER_REDUCTION_MODE_MAX_EXT				= VK_SAMPLER_REDUCTION_MODE_MAX,
+	VK_SAMPLER_REDUCTION_MODE_LAST,
+	VK_SAMPLER_REDUCTION_MODE_MAX_ENUM				= 0x7FFFFFFF,
+};
+
+enum VkSemaphoreType
+{
+	VK_SEMAPHORE_TYPE_BINARY		= 0,
+	VK_SEMAPHORE_TYPE_TIMELINE		= 1,
+	VK_SEMAPHORE_TYPE_BINARY_KHR	= VK_SEMAPHORE_TYPE_BINARY,
+	VK_SEMAPHORE_TYPE_TIMELINE_KHR	= VK_SEMAPHORE_TYPE_TIMELINE,
+	VK_SEMAPHORE_TYPE_LAST,
+	VK_SEMAPHORE_TYPE_MAX_ENUM		= 0x7FFFFFFF,
+};
+
 enum VkColorSpaceKHR
 {
 	VK_COLOR_SPACE_SRGB_NONLINEAR_KHR			= 0,
@@ -1449,11 +1571,14 @@
 
 enum VkPerformanceCounterScopeKHR
 {
-	VK_QUERY_SCOPE_COMMAND_BUFFER_KHR			= 0,
-	VK_QUERY_SCOPE_RENDER_PASS_KHR				= 1,
-	VK_QUERY_SCOPE_COMMAND_KHR					= 2,
+	VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR	= 0,
+	VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR	= 1,
+	VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR		= 2,
+	VK_QUERY_SCOPE_COMMAND_BUFFER_KHR				= VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+	VK_QUERY_SCOPE_RENDER_PASS_KHR					= VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR,
+	VK_QUERY_SCOPE_COMMAND_KHR						= VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
 	VK_PERFORMANCE_COUNTER_SCOPE_KHR_LAST,
-	VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR	= 0x7FFFFFFF,
+	VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR		= 0x7FFFFFFF,
 };
 
 enum VkPerformanceCounterStorageKHR
@@ -1468,40 +1593,6 @@
 	VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR	= 0x7FFFFFFF,
 };
 
-enum VkDriverIdKHR
-{
-	VK_DRIVER_ID_AMD_PROPRIETARY_KHR			= 1,
-	VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR			= 2,
-	VK_DRIVER_ID_MESA_RADV_KHR					= 3,
-	VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR			= 4,
-	VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR	= 5,
-	VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR		= 6,
-	VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR	= 7,
-	VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR		= 8,
-	VK_DRIVER_ID_ARM_PROPRIETARY_KHR			= 9,
-	VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR			= 10,
-	VK_DRIVER_ID_GGP_PROPRIETARY_KHR			= 11,
-	VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR		= 12,
-	VK_DRIVER_ID_MAX_ENUM_KHR					= 0x7FFFFFFF,
-};
-
-enum VkShaderFloatControlsIndependenceKHR
-{
-	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR	= 0,
-	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR			= 1,
-	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR			= 2,
-	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_KHR_LAST,
-	VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR		= 0x7FFFFFFF,
-};
-
-enum VkSemaphoreTypeKHR
-{
-	VK_SEMAPHORE_TYPE_BINARY_KHR	= 0,
-	VK_SEMAPHORE_TYPE_TIMELINE_KHR	= 1,
-	VK_SEMAPHORE_TYPE_KHR_LAST,
-	VK_SEMAPHORE_TYPE_MAX_ENUM_KHR	= 0x7FFFFFFF,
-};
-
 enum VkPipelineExecutableStatisticFormatKHR
 {
 	VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR		= 0,
@@ -1662,15 +1753,6 @@
 	VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT			= 0x7FFFFFFF,
 };
 
-enum VkSamplerReductionModeEXT
-{
-	VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT	= 0,
-	VK_SAMPLER_REDUCTION_MODE_MIN_EXT				= 1,
-	VK_SAMPLER_REDUCTION_MODE_MAX_EXT				= 2,
-	VK_SAMPLER_REDUCTION_MODE_EXT_LAST,
-	VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT			= 0x7FFFFFFF,
-};
-
 enum VkBlendOverlapEXT
 {
 	VK_BLEND_OVERLAP_UNCORRELATED_EXT	= 0,
@@ -1917,6 +1999,10 @@
 
 
 
+
+
+
+
 enum VkFormatFeatureFlagBits
 {
 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT																	= 0x00000001,
@@ -1941,11 +2027,12 @@
 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT		= 0x00200000,
 	VK_FORMAT_FEATURE_DISJOINT_BIT																		= 0x00400000,
 	VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT														= 0x00800000,
+	VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT													= 0x00010000,
 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG												= 0x00002000,
-	VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT												= 0x00010000,
 	VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT														= 0x01000000,
 	VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR																= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT,
 	VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR																= VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
+	VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT												= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT,
 	VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR													= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT,
 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR								= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR				= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT,
@@ -2163,8 +2250,9 @@
 	VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT					= 0x00000002,
 	VK_BUFFER_CREATE_SPARSE_ALIASED_BIT						= 0x00000004,
 	VK_BUFFER_CREATE_PROTECTED_BIT							= 0x00000008,
-	VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR	= 0x00000010,
-	VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT	= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,
+	VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT		= 0x00000010,
+	VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT	= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+	VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR	= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
 	VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM						= 0x7FFFFFFF,
 };
 typedef deUint32 VkBufferCreateFlags;
@@ -2180,12 +2268,13 @@
 	VK_BUFFER_USAGE_INDEX_BUFFER_BIT							= 0x00000040,
 	VK_BUFFER_USAGE_VERTEX_BUFFER_BIT							= 0x00000080,
 	VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT							= 0x00000100,
+	VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT					= 0x00020000,
 	VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT			= 0x00000800,
 	VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT	= 0x00001000,
 	VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT				= 0x00000200,
 	VK_BUFFER_USAGE_RAY_TRACING_BIT_NV							= 0x00000400,
-	VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR				= 0x00020000,
-	VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT				= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,
+	VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT				= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+	VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR				= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
 	VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM							= 0x7FFFFFFF,
 };
 typedef deUint32 VkBufferUsageFlags;
@@ -2280,8 +2369,9 @@
 
 enum VkDescriptorSetLayoutCreateFlagBits
 {
+	VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT		= 0x00000002,
 	VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR			= 0x00000001,
-	VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT	= 0x00000002,
+	VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT	= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
 	VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM				= 0x7FFFFFFF,
 };
 typedef deUint32 VkDescriptorSetLayoutCreateFlags;
@@ -2289,14 +2379,16 @@
 enum VkDescriptorPoolCreateFlagBits
 {
 	VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT	= 0x00000001,
-	VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT	= 0x00000002,
+	VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT		= 0x00000002,
+	VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT	= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
 	VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM		= 0x7FFFFFFF,
 };
 typedef deUint32 VkDescriptorPoolCreateFlags;
 
 enum VkFramebufferCreateFlagBits
 {
-	VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR		= 0x00000001,
+	VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT			= 0x00000001,
+	VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR		= VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,
 	VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM	= 0x7FFFFFFF,
 };
 typedef deUint32 VkFramebufferCreateFlags;
@@ -2448,9 +2540,11 @@
 enum VkMemoryAllocateFlagBits
 {
 	VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT							= 0x00000001,
-	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR					= 0x00000002,
-	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR	= 0x00000004,
+	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT						= 0x00000002,
+	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT		= 0x00000004,
 	VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR						= VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,
+	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR					= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
+	VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR	= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
 	VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM						= 0x7FFFFFFF,
 };
 typedef deUint32 VkMemoryAllocateFlags;
@@ -2557,6 +2651,44 @@
 };
 typedef deUint32 VkExternalSemaphoreFeatureFlags;
 
+enum VkResolveModeFlagBits
+{
+	VK_RESOLVE_MODE_NONE				= 0,
+	VK_RESOLVE_MODE_SAMPLE_ZERO_BIT		= 0x00000001,
+	VK_RESOLVE_MODE_AVERAGE_BIT			= 0x00000002,
+	VK_RESOLVE_MODE_MIN_BIT				= 0x00000004,
+	VK_RESOLVE_MODE_MAX_BIT				= 0x00000008,
+	VK_RESOLVE_MODE_NONE_KHR			= VK_RESOLVE_MODE_NONE,
+	VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR	= VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+	VK_RESOLVE_MODE_AVERAGE_BIT_KHR		= VK_RESOLVE_MODE_AVERAGE_BIT,
+	VK_RESOLVE_MODE_MIN_BIT_KHR			= VK_RESOLVE_MODE_MIN_BIT,
+	VK_RESOLVE_MODE_MAX_BIT_KHR			= VK_RESOLVE_MODE_MAX_BIT,
+	VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM	= 0x7FFFFFFF,
+};
+typedef deUint32 VkResolveModeFlags;
+
+enum VkDescriptorBindingFlagBits
+{
+	VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT					= 0x00000001,
+	VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT		= 0x00000002,
+	VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT					= 0x00000004,
+	VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT			= 0x00000008,
+	VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT				= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
+	VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT	= VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+	VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT				= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
+	VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT		= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
+	VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM					= 0x7FFFFFFF,
+};
+typedef deUint32 VkDescriptorBindingFlags;
+
+enum VkSemaphoreWaitFlagBits
+{
+	VK_SEMAPHORE_WAIT_ANY_BIT				= 0x00000001,
+	VK_SEMAPHORE_WAIT_ANY_BIT_KHR			= VK_SEMAPHORE_WAIT_ANY_BIT,
+	VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM	= 0x7FFFFFFF,
+};
+typedef deUint32 VkSemaphoreWaitFlags;
+
 enum VkSurfaceTransformFlagBitsKHR
 {
 	VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR						= 0x00000001,
@@ -2625,24 +2757,6 @@
 };
 typedef deUint32 VkAcquireProfilingLockFlagsKHR;
 
-enum VkResolveModeFlagBitsKHR
-{
-	VK_RESOLVE_MODE_NONE_KHR				= 0,
-	VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR		= 0x00000001,
-	VK_RESOLVE_MODE_AVERAGE_BIT_KHR			= 0x00000002,
-	VK_RESOLVE_MODE_MIN_BIT_KHR				= 0x00000004,
-	VK_RESOLVE_MODE_MAX_BIT_KHR				= 0x00000008,
-	VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR	= 0x7FFFFFFF,
-};
-typedef deUint32 VkResolveModeFlagsKHR;
-
-enum VkSemaphoreWaitFlagBitsKHR
-{
-	VK_SEMAPHORE_WAIT_ANY_BIT_KHR				= 0x00000001,
-	VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM_KHR	= 0x7FFFFFFF,
-};
-typedef deUint32 VkSemaphoreWaitFlagsKHR;
-
 enum VkDebugReportFlagBitsEXT
 {
 	VK_DEBUG_REPORT_INFORMATION_BIT_EXT			= 0x00000001,
@@ -2724,16 +2838,6 @@
 };
 typedef deUint32 VkDebugUtilsMessageTypeFlagsEXT;
 
-enum VkDescriptorBindingFlagBitsEXT
-{
-	VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT				= 0x00000001,
-	VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT	= 0x00000002,
-	VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT				= 0x00000004,
-	VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT		= 0x00000008,
-	VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT				= 0x7FFFFFFF,
-};
-typedef deUint32 VkDescriptorBindingFlagsEXT;
-
 enum VkGeometryFlagBitsNV
 {
 	VK_GEOMETRY_OPAQUE_BIT_NV							= 0x00000001,
@@ -2784,6 +2888,19 @@
 };
 typedef deUint32 VkShaderCorePropertiesFlagsAMD;
 
+enum VkToolPurposeFlagBitsEXT
+{
+	VK_TOOL_PURPOSE_VALIDATION_BIT_EXT			= 0x00000001,
+	VK_TOOL_PURPOSE_PROFILING_BIT_EXT			= 0x00000002,
+	VK_TOOL_PURPOSE_TRACING_BIT_EXT				= 0x00000004,
+	VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT	= 0x00000008,
+	VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT	= 0x00000010,
+	VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT		= 0x00000020,
+	VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT		= 0x00000040,
+	VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT		= 0x7FFFFFFF,
+};
+typedef deUint32 VkToolPurposeFlagsEXT;
+
 typedef deUint32 VkInstanceCreateFlags;
 
 typedef deUint32 VkDeviceCreateFlags;
@@ -2888,6 +3005,9 @@
 
 
 
+
+
+
 VK_DEFINE_PLATFORM_TYPE(XlibDisplayPtr,				void*);
 VK_DEFINE_PLATFORM_TYPE(XlibWindow,					deUintptr);
 VK_DEFINE_PLATFORM_TYPE(XlibVisualID,				deUint32);
@@ -2905,6 +3025,7 @@
 VK_DEFINE_PLATFORM_TYPE(Win32SecurityAttributesPtr,	const void*);
 VK_DEFINE_PLATFORM_TYPE(AndroidHardwareBufferPtr,	void*);
 VK_DEFINE_PLATFORM_TYPE(Win32MonitorHandle,			void*);
+VK_DEFINE_PLATFORM_TYPE(Win32LPCWSTR,				const void*);
 VK_DEFINE_PLATFORM_TYPE(RROutput,					void*);
 VK_DEFINE_PLATFORM_TYPE(zx_handle_t,				deInt32);
 VK_DEFINE_PLATFORM_TYPE(GgpFrameToken,				deInt32);
@@ -2960,6 +3081,8 @@
 #define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1
 #define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1
 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1
+#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE
+#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE
 #define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4
 #define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1
 #define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1
@@ -3041,7 +3164,7 @@
 #define VK_NV_RAY_TRACING_SPEC_VERSION 3
 #define VK_SHADER_UNUSED_NV (~0U)
 #define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 2
-#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 2
+#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3
 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2
 #define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1
 #define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
@@ -3073,6 +3196,7 @@
 #define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1
 #define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION 1
 #define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2
+#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1
 #define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
 #define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 2
 #define VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION 1
diff --git a/external/vulkancts/framework/vulkan/vkConcreteDeviceInterface.inl b/external/vulkancts/framework/vulkan/vkConcreteDeviceInterface.inl
index 7f01495..c46db92 100644
--- a/external/vulkancts/framework/vulkan/vkConcreteDeviceInterface.inl
+++ b/external/vulkancts/framework/vulkan/vkConcreteDeviceInterface.inl
@@ -138,6 +138,19 @@
 virtual void				destroyDescriptorUpdateTemplate					(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator) const;
 virtual void				updateDescriptorSetWithTemplate					(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) const;
 virtual void				getDescriptorSetLayoutSupport					(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport) const;
+virtual void				cmdDrawIndirectCount							(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const;
+virtual void				cmdDrawIndexedIndirectCount						(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const;
+virtual VkResult			createRenderPass2								(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const;
+virtual void				cmdBeginRenderPass2								(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo) const;
+virtual void				cmdNextSubpass2									(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo) const;
+virtual void				cmdEndRenderPass2								(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo) const;
+virtual void				resetQueryPool									(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const;
+virtual VkResult			getSemaphoreCounterValue						(VkDevice device, VkSemaphore semaphore, deUint64* pValue) const;
+virtual VkResult			waitSemaphores									(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout) const;
+virtual VkResult			signalSemaphore									(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) const;
+virtual VkDeviceAddress		getBufferDeviceAddress							(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const;
+virtual uint64_t			getBufferOpaqueCaptureAddress					(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const;
+virtual uint64_t			getDeviceMemoryOpaqueCaptureAddress				(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) const;
 virtual VkResult			createSwapchainKHR								(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) const;
 virtual void				destroySwapchainKHR								(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) const;
 virtual VkResult			getSwapchainImagesKHR							(VkDevice device, VkSwapchainKHR swapchain, deUint32* pSwapchainImageCount, VkImage* pSwapchainImages) const;
@@ -153,23 +166,11 @@
 virtual VkResult			getSemaphoreFdKHR								(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) const;
 virtual void				cmdPushDescriptorSetKHR							(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, deUint32 set, deUint32 descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites) const;
 virtual void				cmdPushDescriptorSetWithTemplateKHR				(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, deUint32 set, const void* pData) const;
-virtual VkResult			createRenderPass2KHR							(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const;
-virtual void				cmdBeginRenderPass2KHR							(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo) const;
-virtual void				cmdNextSubpass2KHR								(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo) const;
-virtual void				cmdEndRenderPass2KHR							(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo) const;
 virtual VkResult			getSwapchainStatusKHR							(VkDevice device, VkSwapchainKHR swapchain) const;
 virtual VkResult			importFenceFdKHR								(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo) const;
 virtual VkResult			getFenceFdKHR									(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) const;
 virtual VkResult			acquireProfilingLockKHR							(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo) const;
 virtual void				releaseProfilingLockKHR							(VkDevice device) const;
-virtual void				cmdDrawIndirectCountKHR							(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const;
-virtual void				cmdDrawIndexedIndirectCountKHR					(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const;
-virtual VkResult			getSemaphoreCounterValueKHR						(VkDevice device, VkSemaphore semaphore, deUint64* pValue) const;
-virtual VkResult			waitSemaphoresKHR								(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout) const;
-virtual VkResult			signalSemaphoreKHR								(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo) const;
-virtual VkDeviceAddress		getBufferDeviceAddressKHR						(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const;
-virtual uint64_t			getBufferOpaqueCaptureAddressKHR				(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const;
-virtual uint64_t			getDeviceMemoryOpaqueCaptureAddressKHR			(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo) const;
 virtual VkResult			getPipelineExecutablePropertiesKHR				(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, deUint32* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) const;
 virtual VkResult			getPipelineExecutableStatisticsKHR				(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics) const;
 virtual VkResult			getPipelineExecutableInternalRepresentationsKHR	(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) const;
@@ -255,9 +256,8 @@
 virtual VkResult			queueSetPerformanceConfigurationINTEL			(VkQueue queue, VkPerformanceConfigurationINTEL configuration) const;
 virtual VkResult			getPerformanceParameterINTEL					(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue) const;
 virtual void				setLocalDimmingAMD								(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable) const;
-virtual VkDeviceAddress		getBufferDeviceAddressEXT						(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const;
+virtual VkDeviceAddress		getBufferDeviceAddressEXT						(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const;
 virtual void				cmdSetLineStippleEXT							(VkCommandBuffer commandBuffer, deUint32 lineStippleFactor, deUint16 lineStipplePattern) const;
-virtual void				resetQueryPoolEXT								(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const;
 virtual VkResult			getAndroidHardwareBufferPropertiesANDROID		(VkDevice device, const struct pt::AndroidHardwareBufferPtr buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties) const;
 virtual VkResult			getMemoryAndroidHardwareBufferANDROID			(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct pt::AndroidHardwareBufferPtr* pBuffer) const;
 virtual VkResult			getMemoryWin32HandleKHR							(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, pt::Win32Handle* pHandle) const;
diff --git a/external/vulkancts/framework/vulkan/vkConcreteInstanceInterface.inl b/external/vulkancts/framework/vulkan/vkConcreteInstanceInterface.inl
index 2d40ced..0316326 100644
--- a/external/vulkancts/framework/vulkan/vkConcreteInstanceInterface.inl
+++ b/external/vulkancts/framework/vulkan/vkConcreteInstanceInterface.inl
@@ -57,6 +57,7 @@
 virtual void		submitDebugUtilsMessageEXT										(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) const;
 virtual void		getPhysicalDeviceMultisamplePropertiesEXT						(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties) const;
 virtual VkResult	getPhysicalDeviceCalibrateableTimeDomainsEXT					(VkPhysicalDevice physicalDevice, deUint32* pTimeDomainCount, VkTimeDomainEXT* pTimeDomains) const;
+virtual VkResult	getPhysicalDeviceToolPropertiesEXT								(VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties) const;
 virtual VkResult	getPhysicalDeviceCooperativeMatrixPropertiesNV					(VkPhysicalDevice physicalDevice, deUint32* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties) const;
 virtual VkResult	getPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV	(VkPhysicalDevice physicalDevice, deUint32* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations) const;
 virtual VkResult	createHeadlessSurfaceEXT										(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) const;
diff --git a/external/vulkancts/framework/vulkan/vkCoreFunctionalities.inl b/external/vulkancts/framework/vulkan/vkCoreFunctionalities.inl
index 4513861..3d19478 100644
--- a/external/vulkancts/framework/vulkan/vkCoreFunctionalities.inl
+++ b/external/vulkancts/framework/vulkan/vkCoreFunctionalities.inl
@@ -18,6 +18,7 @@
 	apis.clear();
 	apis.insert(::std::pair<deUint32, FunctionInfosList>(VK_API_VERSION_1_0, FunctionInfosList()));
 	apis.insert(::std::pair<deUint32, FunctionInfosList>(VK_API_VERSION_1_1, FunctionInfosList()));
+	apis.insert(::std::pair<deUint32, FunctionInfosList>(VK_API_VERSION_1_2, FunctionInfosList()));
 
 	apis[VK_API_VERSION_1_0].push_back(FunctionInfo("vkCreateInstance",									FUNCTIONORIGIN_PLATFORM));
 	apis[VK_API_VERSION_1_0].push_back(FunctionInfo("vkDestroyInstance",								FUNCTIONORIGIN_INSTANCE));
@@ -322,5 +323,185 @@
 	apis[VK_API_VERSION_1_1].push_back(FunctionInfo("vkGetPhysicalDeviceExternalFenceProperties",		FUNCTIONORIGIN_INSTANCE));
 	apis[VK_API_VERSION_1_1].push_back(FunctionInfo("vkGetPhysicalDeviceExternalSemaphoreProperties",	FUNCTIONORIGIN_INSTANCE));
 	apis[VK_API_VERSION_1_1].push_back(FunctionInfo("vkGetDescriptorSetLayoutSupport",					FUNCTIONORIGIN_DEVICE));
+
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateInstance",									FUNCTIONORIGIN_PLATFORM));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyInstance",								FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumeratePhysicalDevices",						FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceFeatures",						FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceFormatProperties",				FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceImageFormatProperties",			FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceProperties",					FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceQueueFamilyProperties",			FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceMemoryProperties",				FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetInstanceProcAddr",							FUNCTIONORIGIN_PLATFORM));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceProcAddr",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateDevice",									FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyDevice",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumerateInstanceExtensionProperties",			FUNCTIONORIGIN_PLATFORM));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumerateDeviceExtensionProperties",				FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumerateInstanceLayerProperties",				FUNCTIONORIGIN_PLATFORM));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumerateDeviceLayerProperties",					FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceQueue",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkQueueSubmit",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkQueueWaitIdle",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDeviceWaitIdle",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkAllocateMemory",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkFreeMemory",										FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkMapMemory",										FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkUnmapMemory",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkFlushMappedMemoryRanges",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkInvalidateMappedMemoryRanges",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceMemoryCommitment",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkBindBufferMemory",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkBindImageMemory",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetBufferMemoryRequirements",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetImageMemoryRequirements",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetImageSparseMemoryRequirements",				FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceSparseImageFormatProperties",	FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkQueueBindSparse",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateFence",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyFence",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetFences",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetFenceStatus",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkWaitForFences",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateSemaphore",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroySemaphore",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateEvent",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyEvent",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetEventStatus",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkSetEvent",										FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetEvent",										FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateQueryPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyQueryPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetQueryPoolResults",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateBuffer",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyBuffer",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateBufferView",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyBufferView",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateImage",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyImage",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetImageSubresourceLayout",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateImageView",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyImageView",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateShaderModule",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyShaderModule",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreatePipelineCache",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyPipelineCache",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPipelineCacheData",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkMergePipelineCaches",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateGraphicsPipelines",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateComputePipelines",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyPipeline",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreatePipelineLayout",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyPipelineLayout",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateSampler",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroySampler",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateDescriptorSetLayout",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyDescriptorSetLayout",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateDescriptorPool",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyDescriptorPool",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetDescriptorPool",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkAllocateDescriptorSets",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkFreeDescriptorSets",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkUpdateDescriptorSets",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateFramebuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyFramebuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateRenderPass",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyRenderPass",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetRenderAreaGranularity",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateCommandPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyCommandPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetCommandPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkAllocateCommandBuffers",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkFreeCommandBuffers",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkBeginCommandBuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEndCommandBuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetCommandBuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBindPipeline",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetViewport",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetScissor",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetLineWidth",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetDepthBias",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetBlendConstants",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetDepthBounds",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetStencilCompareMask",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetStencilWriteMask",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetStencilReference",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBindDescriptorSets",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBindIndexBuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBindVertexBuffers",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDraw",										FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDrawIndexed",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDrawIndirect",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDrawIndexedIndirect",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDispatch",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDispatchIndirect",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdCopyBuffer",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdCopyImage",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBlitImage",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdCopyBufferToImage",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdCopyImageToBuffer",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdUpdateBuffer",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdFillBuffer",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdClearColorImage",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdClearDepthStencilImage",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdClearAttachments",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdResolveImage",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetEvent",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdResetEvent",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdWaitEvents",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdPipelineBarrier",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBeginQuery",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdEndQuery",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdResetQueryPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdWriteTimestamp",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdCopyQueryPoolResults",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdPushConstants",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBeginRenderPass",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdNextSubpass",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdEndRenderPass",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdExecuteCommands",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumerateInstanceVersion",						FUNCTIONORIGIN_PLATFORM));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkBindBufferMemory2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkBindImageMemory2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceGroupPeerMemoryFeatures",				FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdSetDeviceMask",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDispatchBase",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkEnumeratePhysicalDeviceGroups",					FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetImageMemoryRequirements2",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetBufferMemoryRequirements2",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetImageSparseMemoryRequirements2",				FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceFeatures2",						FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceProperties2",					FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceFormatProperties2",				FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceImageFormatProperties2",		FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceQueueFamilyProperties2",		FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceMemoryProperties2",				FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceSparseImageFormatProperties2",	FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkTrimCommandPool",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceQueue2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateSamplerYcbcrConversion",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroySamplerYcbcrConversion",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateDescriptorUpdateTemplate",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkDestroyDescriptorUpdateTemplate",				FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkUpdateDescriptorSetWithTemplate",				FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceExternalBufferProperties",		FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceExternalFenceProperties",		FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetPhysicalDeviceExternalSemaphoreProperties",	FUNCTIONORIGIN_INSTANCE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDescriptorSetLayoutSupport",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDrawIndirectCount",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdDrawIndexedIndirectCount",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCreateRenderPass2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdBeginRenderPass2",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdNextSubpass2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkCmdEndRenderPass2",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkResetQueryPool",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetSemaphoreCounterValue",						FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkWaitSemaphores",									FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkSignalSemaphore",								FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetBufferDeviceAddress",							FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetBufferOpaqueCaptureAddress",					FUNCTIONORIGIN_DEVICE));
+	apis[VK_API_VERSION_1_2].push_back(FunctionInfo("vkGetDeviceMemoryOpaqueCaptureAddress",			FUNCTIONORIGIN_DEVICE));
+
 }
 
diff --git a/external/vulkancts/framework/vulkan/vkDefs.hpp b/external/vulkancts/framework/vulkan/vkDefs.hpp
index a83d726..8335792 100644
--- a/external/vulkancts/framework/vulkan/vkDefs.hpp
+++ b/external/vulkancts/framework/vulkan/vkDefs.hpp
@@ -108,6 +108,7 @@
 	SPIRV_VERSION_1_2	= 2,	//!< SPIR-V 1.2
 	SPIRV_VERSION_1_3	= 3,	//!< SPIR-V 1.3
 	SPIRV_VERSION_1_4	= 4,	//!< SPIR-V 1.4
+	SPIRV_VERSION_1_5	= 5,	//!< SPIR-V 1.5
 
 	SPIRV_VERSION_LAST
 };
diff --git a/external/vulkancts/framework/vulkan/vkDeviceDriverImpl.inl b/external/vulkancts/framework/vulkan/vkDeviceDriverImpl.inl
index 074513e..298c2bf 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceDriverImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceDriverImpl.inl
@@ -687,6 +687,71 @@
 	m_vk.getDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
 }
 
+void DeviceDriver::cmdDrawIndirectCount (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const
+{
+	m_vk.cmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+void DeviceDriver::cmdDrawIndexedIndirectCount (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const
+{
+	m_vk.cmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+VkResult DeviceDriver::createRenderPass2 (VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const
+{
+	return m_vk.createRenderPass2(device, pCreateInfo, pAllocator, pRenderPass);
+}
+
+void DeviceDriver::cmdBeginRenderPass2 (VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo) const
+{
+	m_vk.cmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
+}
+
+void DeviceDriver::cmdNextSubpass2 (VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo) const
+{
+	m_vk.cmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
+}
+
+void DeviceDriver::cmdEndRenderPass2 (VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo) const
+{
+	m_vk.cmdEndRenderPass2(commandBuffer, pSubpassEndInfo);
+}
+
+void DeviceDriver::resetQueryPool (VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const
+{
+	m_vk.resetQueryPool(device, queryPool, firstQuery, queryCount);
+}
+
+VkResult DeviceDriver::getSemaphoreCounterValue (VkDevice device, VkSemaphore semaphore, deUint64* pValue) const
+{
+	return m_vk.getSemaphoreCounterValue(device, semaphore, pValue);
+}
+
+VkResult DeviceDriver::waitSemaphores (VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout) const
+{
+	return m_vk.waitSemaphores(device, pWaitInfo, timeout);
+}
+
+VkResult DeviceDriver::signalSemaphore (VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) const
+{
+	return m_vk.signalSemaphore(device, pSignalInfo);
+}
+
+VkDeviceAddress DeviceDriver::getBufferDeviceAddress (VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const
+{
+	return m_vk.getBufferDeviceAddress(device, pInfo);
+}
+
+uint64_t DeviceDriver::getBufferOpaqueCaptureAddress (VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const
+{
+	return m_vk.getBufferOpaqueCaptureAddress(device, pInfo);
+}
+
+uint64_t DeviceDriver::getDeviceMemoryOpaqueCaptureAddress (VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) const
+{
+	return m_vk.getDeviceMemoryOpaqueCaptureAddress(device, pInfo);
+}
+
 VkResult DeviceDriver::createSwapchainKHR (VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) const
 {
 	return m_vk.createSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
@@ -762,26 +827,6 @@
 	m_vk.cmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
 }
 
-VkResult DeviceDriver::createRenderPass2KHR (VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const
-{
-	return m_vk.createRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
-}
-
-void DeviceDriver::cmdBeginRenderPass2KHR (VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo) const
-{
-	m_vk.cmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
-}
-
-void DeviceDriver::cmdNextSubpass2KHR (VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo) const
-{
-	m_vk.cmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
-}
-
-void DeviceDriver::cmdEndRenderPass2KHR (VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo) const
-{
-	m_vk.cmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo);
-}
-
 VkResult DeviceDriver::getSwapchainStatusKHR (VkDevice device, VkSwapchainKHR swapchain) const
 {
 	return m_vk.getSwapchainStatusKHR(device, swapchain);
@@ -807,46 +852,6 @@
 	m_vk.releaseProfilingLockKHR(device);
 }
 
-void DeviceDriver::cmdDrawIndirectCountKHR (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const
-{
-	m_vk.cmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
-}
-
-void DeviceDriver::cmdDrawIndexedIndirectCountKHR (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const
-{
-	m_vk.cmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
-}
-
-VkResult DeviceDriver::getSemaphoreCounterValueKHR (VkDevice device, VkSemaphore semaphore, deUint64* pValue) const
-{
-	return m_vk.getSemaphoreCounterValueKHR(device, semaphore, pValue);
-}
-
-VkResult DeviceDriver::waitSemaphoresKHR (VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout) const
-{
-	return m_vk.waitSemaphoresKHR(device, pWaitInfo, timeout);
-}
-
-VkResult DeviceDriver::signalSemaphoreKHR (VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo) const
-{
-	return m_vk.signalSemaphoreKHR(device, pSignalInfo);
-}
-
-VkDeviceAddress DeviceDriver::getBufferDeviceAddressKHR (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const
-{
-	return m_vk.getBufferDeviceAddressKHR(device, pInfo);
-}
-
-uint64_t DeviceDriver::getBufferOpaqueCaptureAddressKHR (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const
-{
-	return m_vk.getBufferOpaqueCaptureAddressKHR(device, pInfo);
-}
-
-uint64_t DeviceDriver::getDeviceMemoryOpaqueCaptureAddressKHR (VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo) const
-{
-	return m_vk.getDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo);
-}
-
 VkResult DeviceDriver::getPipelineExecutablePropertiesKHR (VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, deUint32* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) const
 {
 	return m_vk.getPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties);
@@ -1272,7 +1277,7 @@
 	m_vk.setLocalDimmingAMD(device, swapChain, localDimmingEnable);
 }
 
-VkDeviceAddress DeviceDriver::getBufferDeviceAddressEXT (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const
+VkDeviceAddress DeviceDriver::getBufferDeviceAddressEXT (VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const
 {
 	return m_vk.getBufferDeviceAddressEXT(device, pInfo);
 }
@@ -1282,11 +1287,6 @@
 	m_vk.cmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern);
 }
 
-void DeviceDriver::resetQueryPoolEXT (VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const
-{
-	m_vk.resetQueryPoolEXT(device, queryPool, firstQuery, queryCount);
-}
-
 VkResult DeviceDriver::getAndroidHardwareBufferPropertiesANDROID (VkDevice device, const struct pt::AndroidHardwareBufferPtr buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties) const
 {
 	return m_vk.getAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties);
diff --git a/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl b/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl
index 31f3a0c..9c20e4b 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl
@@ -47,13 +47,19 @@
 	"VK_KHR_vulkan_memory_model",
 	"VK_KHR_uniform_buffer_standard_layout",
 	"VK_KHR_imageless_framebuffer",
-	"VK_KHR_pipeline_executable_properties",
-	"VK_KHR_timeline_semaphore",
-	"VK_KHR_shader_clock",
-	"VK_KHR_spirv_1_4",
 	"VK_KHR_shader_subgroup_extended_types",
-	"VK_KHR_separate_depth_stencil_layouts",
-	"VK_KHR_performance_query",
+	"VK_EXT_sampler_filter_minmax",
+	"VK_EXT_shader_viewport_index_layer",
+	"VK_EXT_descriptor_indexing",
+	"VK_EXT_scalar_block_layout",
 	"VK_KHR_buffer_device_address",
+	"VK_EXT_host_query_reset",
+	"VK_KHR_separate_depth_stencil_layouts",
+	"VK_KHR_timeline_semaphore",
+	"VK_KHR_spirv_1_4",
+	"VK_EXT_separate_stencil_usage",
+	"VK_KHR_pipeline_executable_properties",
+	"VK_KHR_shader_clock",
+	"VK_KHR_performance_query",
 };
 
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp b/external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp
index 520423e..9eed63f 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp
@@ -32,33 +32,71 @@
 								 const std::vector<std::string>&	instanceExtensions,
 								 const std::vector<std::string>&	deviceExtensions)
 {
-	deMemset(&m_coreFeatures2, 0, sizeof(m_coreFeatures2));
-	m_coreFeatures2.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+	m_coreFeatures2		= initVulkanStructure();
+	m_vulkan11Features	= initVulkanStructure();
+	m_vulkan12Features	= initVulkanStructure();
 
 	if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
 	{
 		const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
 		void**										nextPtr						= &m_coreFeatures2.pNext;
+		std::vector<FeatureStructWrapperBase*>		featuresToFillFromBlob;
+		bool										vk12Supported				= (apiVersion >= VK_MAKE_VERSION(1, 2, 0));
 
-		for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(featureStructCreatorMap); ++i)
+		// in vk12 we have blob structures combining features of couple previously
+		// available feature structures, that now in vk12 must be removed from chain
+		if (vk12Supported)
 		{
-			const char* featureName = featureStructCreatorMap[i].name;
+			addToChainVulkanStructure(&nextPtr, m_vulkan11Features);
+			addToChainVulkanStructure(&nextPtr, m_vulkan12Features);
+		}
 
-			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), featureName)
-				&& verifyFeatureAddCriteria(featureStructCreatorMap[i], deviceExtensionProperties))
+		// iterate over data for all feature that are defined in specification
+		for (const auto& featureStructCreationData : featureStructCreationArray)
+		{
+			const char* featureName = featureStructCreationData.name;
+
+			// check if this feature is available on current device
+			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), featureName) &&
+				verifyFeatureAddCriteria(featureStructCreationData, deviceExtensionProperties))
 			{
-				FeatureStruct* p = createFeatureStructWrapper(featureName);
+				FeatureStructWrapperBase* p = (*featureStructCreationData.creatorFunction)();
+				if (p == DE_NULL)
+					continue;
 
-				if (p)
+				// if feature struct is part of VkPhysicalDeviceVulkan1{1,2}Features
+				// we dont add it to the chain but store and fill later from blob data
+				bool featureFilledFromBlob = false;
+				if (vk12Supported)
+					featureFilledFromBlob = isPartOfBlobFeatures(p->getFeatureDesc().sType);
+
+				if (featureFilledFromBlob)
+					featuresToFillFromBlob.push_back(p);
+				else
 				{
+					// add to chain
 					*nextPtr = p->getFeatureTypeRaw();
 					nextPtr = p->getFeatureTypeNext();
-					m_features.push_back(p);
 				}
+				m_features.push_back(p);
 			}
 		}
 
 		vki.getPhysicalDeviceFeatures2(physicalDevice, &m_coreFeatures2);
+
+		// fill data from VkPhysicalDeviceVulkan1{1,2}Features
+		if (vk12Supported)
+		{
+			AllBlobs allBlobs =
+			{
+				m_vulkan11Features,
+				m_vulkan12Features,
+				// add blobs from future vulkan versions here
+			};
+
+			for (auto feature : featuresToFillFromBlob)
+				feature->initializeFromBlob(allBlobs);
+		}
 	}
 	else
 		m_coreFeatures2.features = getPhysicalDeviceFeatures(vki, physicalDevice);
@@ -67,67 +105,51 @@
 	m_coreFeatures2.features.robustBufferAccess = false;
 }
 
-bool DeviceFeatures::verifyFeatureAddCriteria (const FeatureStructMapItem& item, const std::vector<VkExtensionProperties>& properties)
+bool DeviceFeatures::verifyFeatureAddCriteria (const FeatureStructCreationData& item, const std::vector<VkExtensionProperties>& properties)
 {
-	bool criteriaOK = true;
-
 	if (deStringEqual(item.name, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME))
 	{
-		const size_t propSize = properties.size();
-
-		for (size_t propIdx = 0; propIdx < propSize; ++propIdx)
+		for (const auto& property : properties)
 		{
-			if (deStringEqual(properties[propIdx].extensionName, item.name))
-			{
-				criteriaOK = properties[propIdx].specVersion == item.specVersion;
-				break;
-			}
+			if (deStringEqual(property.extensionName, item.name))
+				return (property.specVersion == item.specVersion);
 		}
 	}
 
-	return criteriaOK;
+	return true;
 }
 
 bool DeviceFeatures::contains (const std::string& feature, bool throwIfNotExists) const
 {
-	const size_t typesSize	= m_features.size();
-
-	for (size_t typeIdx = 0; typeIdx < typesSize; ++typeIdx)
+	for (const auto f : m_features)
 	{
-		if (deStringEqual(m_features[typeIdx]->getFeatureDesc().name, feature.c_str()))
-		{
+		if (deStringEqual(f->getFeatureDesc().name, feature.c_str()))
 			return true;
-		}
 	}
 
 	if (throwIfNotExists)
+		TCU_THROW(NotSupportedError, "Feature " + feature + " is not supported");
+
+	return false;
+}
+
+bool DeviceFeatures::isDeviceFeatureInitialized (VkStructureType sType) const
+{
+	for (const auto f : m_features)
 	{
-		std::string msg("Feature " + feature + " is not supported");
-
-		TCU_THROW(NotSupportedError, msg);
+		if (f->getFeatureDesc().sType == sType)
+			return true;
 	}
-
 	return false;
 }
 
 DeviceFeatures::~DeviceFeatures (void)
 {
-	for (size_t i = 0; i < m_features.size(); ++i)
-		delete m_features[i];
+	for (auto p : m_features)
+		delete p;
 
 	m_features.clear();
 }
 
-FeatureStruct* DeviceFeatures::createFeatureStructWrapper (const std::string& s)
-{
-	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(featureStructCreatorMap); ++i)
-	{
-		if (deStringEqual(featureStructCreatorMap[i].name, s.c_str()))
-			return (*featureStructCreatorMap[i].creator)();
-	}
-
-	return DE_NULL;
-}
-
 } // vk
 
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeatures.hpp b/external/vulkancts/framework/vulkan/vkDeviceFeatures.hpp
index 966e94d..0301978 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeatures.hpp
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeatures.hpp
@@ -34,144 +34,151 @@
 namespace vk
 {
 
+// Structure describing vulkan feature structure
 struct FeatureDesc
 {
-						FeatureDesc (VkStructureType sType_, const char* name_, deUint32 specVersion_, deUint32 typeId_)
-							: name			(name_)
-							, sType			(sType_)
-							, specVersion	(specVersion_)
-							, typeId		(typeId_)
-						{}
-
-	const char*			name;
 	VkStructureType		sType;
+	const char*			name;
 	const deUint32		specVersion;
 	const deUint32		typeId;
 };
 
-struct FeatureStruct
+// Structure containg all feature blobs - this simplifies generated code
+struct AllBlobs
 {
-	virtual deUint32		getFeatureTypeId		(void) const = 0;
-	virtual FeatureDesc		getFeatureDesc			(void) const = 0;
-	virtual void**			getFeatureTypeNext		(void) = 0;
-	virtual void*			getFeatureTypeRaw		(void) = 0;
-	virtual					~FeatureStruct			(void) {}
+	VkPhysicalDeviceVulkan11Features& vk11;
+	VkPhysicalDeviceVulkan12Features& vk12;
+	// add blobs from future vulkan versions here
 };
 
-
-struct FeatureStructMapItem
+// Base class for all FeatureStructWrapper specializations
+class FeatureStructWrapperBase
 {
-	FeatureStruct*	(*creator)(void);
-	const char*		name;
-	deUint32		specVersion;
+public:
+	virtual					~FeatureStructWrapperBase	(void) {}
+	virtual void			initializeFromBlob			(const AllBlobs& allBlobs) = 0;
+	virtual deUint32		getFeatureTypeId			(void) const = 0;
+	virtual FeatureDesc		getFeatureDesc				(void) const = 0;
+	virtual void**			getFeatureTypeNext			(void) = 0;
+	virtual void*			getFeatureTypeRaw			(void) = 0;
 };
 
-template<class FeatureType> struct FeatureStructWrapper;
+using FeatureStructWrapperCreator	= FeatureStructWrapperBase* (*) (void);
+struct FeatureStructCreationData
+{
+	FeatureStructWrapperCreator	creatorFunction;
+	const char*					name;
+	deUint32					specVersion;
+};
+
+template<class FeatureType> class FeatureStructWrapper;
 template<class FeatureType> FeatureDesc makeFeatureDesc (void);
 
 template<class FeatureType>
-FeatureStruct* createFeatureStructWrapper (void)
+FeatureStructWrapperBase* createFeatureStructWrapper (void)
 {
 	return new FeatureStructWrapper<FeatureType>(makeFeatureDesc<FeatureType>());
 }
 
+template<class FeatureType>
+void initFromBlob(FeatureType& featureType, const AllBlobs& allBlobs);
+
+template<class FeatureType>
+void initFromBlobWrapper(FeatureType& featureType, const AllBlobs& allBlobs)
+{
+	initFromBlob<FeatureType>(featureType, allBlobs);
+}
+
 class DeviceFeatures
 {
 public:
-										DeviceFeatures		(const InstanceInterface&			vki,
-															 const deUint32						apiVersion,
-															 const VkPhysicalDevice				physicalDevice,
-															 const std::vector<std::string>&	instanceExtensions,
-															 const std::vector<std::string>&	deviceExtensions);
+												DeviceFeatures				(const InstanceInterface&			vki,
+																			 const deUint32						apiVersion,
+																			 const VkPhysicalDevice				physicalDevice,
+																			 const std::vector<std::string>&	instanceExtensions,
+																			 const std::vector<std::string>&	deviceExtensions);
 
-										~DeviceFeatures		(void);
+												~DeviceFeatures				(void);
 
 	template<class FeatureType>
-	bool								getFeatureType		(FeatureType&						featureType) const
-	{
-		typedef FeatureStructWrapper<FeatureType>	*FeatureWrapperPtr;
+	const FeatureType&							getFeatureType				(void) const;
 
-		const VkStructureType	sType		= makeFeatureDesc<FeatureType>().sType;
-		const size_t			featCount	= m_features.size();
+	const VkPhysicalDeviceFeatures2&			getCoreFeatures2			(void) const { return m_coreFeatures2; }
+	const VkPhysicalDeviceVulkan11Features&		getVulkan11Features			(void) const { return m_vulkan11Features; }
+	const VkPhysicalDeviceVulkan12Features&		getVulkan12Features			(void) const { return m_vulkan12Features; }
 
-		for (size_t featIdx = 0; featIdx < featCount; ++featIdx)
-		{
-			if (sType == m_features[featIdx]->getFeatureDesc().sType)
-			{
-				featureType = static_cast<FeatureWrapperPtr>(m_features[featIdx])->getFeatureTypeRef();
-				return true;
-			}
-		}
-		return false;
-	}
+	bool										contains					(const std::string& feature, bool throwIfNotExists = false) const;
 
-	template<class FeatureType>
-	const FeatureType&					getFeatureType		(void) const
-	{
-		typedef FeatureStructWrapper<FeatureType>	*FeatureWrapperPtr;
-
-		const FeatureDesc		featDesc	= makeFeatureDesc<FeatureType>();
-		const VkStructureType	sType		= featDesc.sType;
-		const size_t			featCount	= m_features.size();
-
-		for (size_t featIdx = 0; featIdx < featCount; ++featIdx)
-		{
-			if (sType == m_features[featIdx]->getFeatureDesc().sType)
-				return static_cast<FeatureWrapperPtr>(m_features[featIdx])->getFeatureTypeRef();
-		}
-
-		const deUint32			featureId = featDesc.typeId;
-
-		for (size_t featIdx = 0; featIdx < featCount; ++featIdx)
-		{
-			if (featureId == m_features[featIdx]->getFeatureTypeId())
-				return static_cast<FeatureWrapperPtr>(m_features[featIdx])->getFeatureTypeRef();
-		}
-
-		FeatureStruct* p = vk::createFeatureStructWrapper<FeatureType>();
-		m_features.push_back(p);
-
-		return static_cast<FeatureWrapperPtr>(p)->getFeatureTypeRef();
-	}
-
-	const VkPhysicalDeviceFeatures2&	getCoreFeatures2	(void) const { return m_coreFeatures2; }
-
-	bool								contains			(const std::string& feature, bool throwIfNotExists = false) const;
+	bool										isDeviceFeatureInitialized	(VkStructureType sType) const;
 
 private:
 
-	static FeatureStruct*				createFeatureStructWrapper	(const std::string& s);
+	static bool							verifyFeatureAddCriteria	(const FeatureStructCreationData& item, const std::vector<VkExtensionProperties>& properties);
 
-	static bool							verifyFeatureAddCriteria	(const FeatureStructMapItem& item, const std::vector<VkExtensionProperties>& properties);
+private:
 
-	VkPhysicalDeviceFeatures2			m_coreFeatures2;
-	mutable std::vector<FeatureStruct*>	m_features;
+	VkPhysicalDeviceFeatures2						m_coreFeatures2;
+	mutable std::vector<FeatureStructWrapperBase*>	m_features;
+	VkPhysicalDeviceVulkan11Features				m_vulkan11Features;
+	VkPhysicalDeviceVulkan12Features				m_vulkan12Features;
 };
 
 template<class FeatureType>
-struct FeatureStructWrapper : FeatureStruct
+const FeatureType& DeviceFeatures::getFeatureType(void) const
 {
+	typedef FeatureStructWrapper<FeatureType>* FeatureWrapperPtr;
+
+	const FeatureDesc		featDesc	= makeFeatureDesc<FeatureType>();
+	const VkStructureType	sType		= featDesc.sType;
+
+	// try to find feature by sType
+	for (auto feature : m_features)
+	{
+		if (sType == feature->getFeatureDesc().sType)
+			return static_cast<FeatureWrapperPtr>(feature)->getFeatureTypeRef();
+	}
+
+	// try to find feature by id that was assigned by gen_framework script
+	const deUint32 featureId = featDesc.typeId;
+	for (auto feature : m_features)
+	{
+		if (featureId == feature->getFeatureTypeId())
+			return static_cast<FeatureWrapperPtr>(feature)->getFeatureTypeRef();
+	}
+
+	// if initialized feature structure was not found create empty one and return it
+	m_features.push_back(vk::createFeatureStructWrapper<FeatureType>());
+	return static_cast<FeatureWrapperPtr>(m_features.back())->getFeatureTypeRef();
+}
+
+template<class FeatureType>
+class FeatureStructWrapper : public FeatureStructWrapperBase
+{
+public:
+	FeatureStructWrapper (const FeatureDesc& featureDesc)
+		: m_featureDesc(featureDesc)
+	{
+		deMemset(&m_featureType, 0, sizeof(m_featureType));
+		m_featureType.sType = featureDesc.sType;
+	}
+
+	void initializeFromBlob (const AllBlobs& allBlobs)
+	{
+		initFromBlobWrapper(m_featureType, allBlobs);
+	}
+
+	deUint32		getFeatureTypeId	(void) const	{ return m_featureDesc.typeId;	}
+	FeatureDesc		getFeatureDesc		(void) const	{ return m_featureDesc;			}
+	void**			getFeatureTypeNext	(void)			{ return &m_featureType.pNext;	}
+	void*			getFeatureTypeRaw	(void)			{ return &m_featureType;		}
+	FeatureType&	getFeatureTypeRef	(void)			{ return m_featureType;			}
+
+public:
+	// metadata about feature structure
 	const FeatureDesc	m_featureDesc;
+
+	// actual vulkan feature structure
 	FeatureType			m_featureType;
-
-						FeatureStructWrapper	(void)
-							: m_featureDesc	(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, ~0u, 0u)
-						{
-							deMemset(&m_featureType, 0, sizeof(m_featureType));
-						}
-
-						FeatureStructWrapper	(const FeatureDesc& featureDesc)
-							: m_featureDesc	(featureDesc)
-						{
-							deMemset(&m_featureType, 0, sizeof(m_featureType));
-							m_featureType.sType = featureDesc.sType;
-						}
-
-	deUint32			getFeatureTypeId		(void) const	{ return m_featureDesc.typeId;	}
-	FeatureDesc			getFeatureDesc			(void) const	{ return m_featureDesc;			}
-	void**				getFeatureTypeNext		(void)			{ return &m_featureType.pNext;	}
-	void*				getFeatureTypeRaw		(void)			{ return &m_featureType;		}
-	FeatureType&		getFeatureTypeRef		(void)			{ return m_featureType;			}
 };
 
 } // vk
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl b/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl
index c9ebf11..4c499d6 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl
@@ -7,9 +7,10 @@
 {
 #define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage"
 #define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
+#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode"
 #define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced"
-#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address"
 #define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address"
+#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address"
 #define DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME "not_existent_feature"
 #define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives"
 #define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering"
@@ -45,6 +46,7 @@
 #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8"
 #define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint"
 #define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2"
+#define VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME "VK_NV_shader_sm_builtins"
 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types"
 #define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
 #define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control"
@@ -58,66 +60,217 @@
 #define VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME "VK_EXT_ycbcr_image_arrays"
 
 
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDevice16BitStorageFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION, 51); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDevice8BitStorageFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, VK_KHR_8BIT_STORAGE_EXTENSION_NAME, VK_KHR_8BIT_STORAGE_SPEC_VERSION, 50); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION, 49); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION, 48); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBufferDeviceAddressFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION, 47); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME, 0, 46); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION, 45); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION, 44); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME, VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION, 43); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCornerSampledImageFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME, VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION, 42); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCoverageReductionModeFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME, VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION, 41); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION, 40); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDepthClipEnableFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION, 39); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION, 38); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceExclusiveScissorFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME, VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION, 37); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION, 36); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION, 35); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION, 34); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceHostQueryResetFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_EXT_HOST_QUERY_RESET_SPEC_VERSION, 33); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceImagelessFramebufferFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION, 32); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION, 31); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION, 30); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceLineRasterizationFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION, 29); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMemoryPriorityFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, VK_EXT_MEMORY_PRIORITY_SPEC_VERSION, 28); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMeshShaderFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, VK_NV_MESH_SHADER_EXTENSION_NAME, VK_NV_MESH_SHADER_SPEC_VERSION, 27); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMultiviewFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION, 26); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDevicePerformanceQueryFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION, 25); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION, 24); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceProtectedMemoryFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 23); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION, 22); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION, 21); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION, 20); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION, 19); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderAtomicInt64FeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION, 18); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderClockFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, VK_KHR_SHADER_CLOCK_EXTENSION_NAME, VK_KHR_SHADER_CLOCK_SPEC_VERSION, 17); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION, 16); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderDrawParametersFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION, 15); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderFloat16Int8FeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION, 14); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME, VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION, 13); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION, 12); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION, 11); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShadingRateImageFeaturesNV>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME, VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION, 10); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION, 9); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION, 8); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION, 7); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION, 6); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION, 5); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVariablePointersFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION, 4); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION, 3); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVulkanMemoryModelFeaturesKHR>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION, 2); }
-template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME, VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION, 1); }
+template<> void initFromBlob<VkPhysicalDevice16BitStorageFeatures>(VkPhysicalDevice16BitStorageFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.storageBuffer16BitAccess = allBlobs.vk11.storageBuffer16BitAccess;
+	featureType.uniformAndStorageBuffer16BitAccess = allBlobs.vk11.uniformAndStorageBuffer16BitAccess;
+	featureType.storagePushConstant16 = allBlobs.vk11.storagePushConstant16;
+	featureType.storageInputOutput16 = allBlobs.vk11.storageInputOutput16;
+}
+template<> void initFromBlob<VkPhysicalDeviceMultiviewFeatures>(VkPhysicalDeviceMultiviewFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.multiview = allBlobs.vk11.multiview;
+	featureType.multiviewGeometryShader = allBlobs.vk11.multiviewGeometryShader;
+	featureType.multiviewTessellationShader = allBlobs.vk11.multiviewTessellationShader;
+}
+template<> void initFromBlob<VkPhysicalDeviceVariablePointersFeatures>(VkPhysicalDeviceVariablePointersFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.variablePointersStorageBuffer = allBlobs.vk11.variablePointersStorageBuffer;
+	featureType.variablePointers = allBlobs.vk11.variablePointers;
+}
+template<> void initFromBlob<VkPhysicalDeviceProtectedMemoryFeatures>(VkPhysicalDeviceProtectedMemoryFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.protectedMemory = allBlobs.vk11.protectedMemory;
+}
+template<> void initFromBlob<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(VkPhysicalDeviceSamplerYcbcrConversionFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.samplerYcbcrConversion = allBlobs.vk11.samplerYcbcrConversion;
+}
+template<> void initFromBlob<VkPhysicalDeviceShaderDrawParametersFeatures>(VkPhysicalDeviceShaderDrawParametersFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.shaderDrawParameters = allBlobs.vk11.shaderDrawParameters;
+}
+template<> void initFromBlob<VkPhysicalDevice8BitStorageFeatures>(VkPhysicalDevice8BitStorageFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.storageBuffer8BitAccess = allBlobs.vk12.storageBuffer8BitAccess;
+	featureType.uniformAndStorageBuffer8BitAccess = allBlobs.vk12.uniformAndStorageBuffer8BitAccess;
+	featureType.storagePushConstant8 = allBlobs.vk12.storagePushConstant8;
+}
+template<> void initFromBlob<VkPhysicalDeviceShaderAtomicInt64Features>(VkPhysicalDeviceShaderAtomicInt64Features& featureType, const AllBlobs& allBlobs)
+{
+	featureType.shaderBufferInt64Atomics = allBlobs.vk12.shaderBufferInt64Atomics;
+	featureType.shaderSharedInt64Atomics = allBlobs.vk12.shaderSharedInt64Atomics;
+}
+template<> void initFromBlob<VkPhysicalDeviceShaderFloat16Int8Features>(VkPhysicalDeviceShaderFloat16Int8Features& featureType, const AllBlobs& allBlobs)
+{
+	featureType.shaderFloat16 = allBlobs.vk12.shaderFloat16;
+	featureType.shaderInt8 = allBlobs.vk12.shaderInt8;
+}
+template<> void initFromBlob<VkPhysicalDeviceDescriptorIndexingFeatures>(VkPhysicalDeviceDescriptorIndexingFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.shaderInputAttachmentArrayDynamicIndexing = allBlobs.vk12.shaderInputAttachmentArrayDynamicIndexing;
+	featureType.shaderUniformTexelBufferArrayDynamicIndexing = allBlobs.vk12.shaderUniformTexelBufferArrayDynamicIndexing;
+	featureType.shaderStorageTexelBufferArrayDynamicIndexing = allBlobs.vk12.shaderStorageTexelBufferArrayDynamicIndexing;
+	featureType.shaderUniformBufferArrayNonUniformIndexing = allBlobs.vk12.shaderUniformBufferArrayNonUniformIndexing;
+	featureType.shaderSampledImageArrayNonUniformIndexing = allBlobs.vk12.shaderSampledImageArrayNonUniformIndexing;
+	featureType.shaderStorageBufferArrayNonUniformIndexing = allBlobs.vk12.shaderStorageBufferArrayNonUniformIndexing;
+	featureType.shaderStorageImageArrayNonUniformIndexing = allBlobs.vk12.shaderStorageImageArrayNonUniformIndexing;
+	featureType.shaderInputAttachmentArrayNonUniformIndexing = allBlobs.vk12.shaderInputAttachmentArrayNonUniformIndexing;
+	featureType.shaderUniformTexelBufferArrayNonUniformIndexing = allBlobs.vk12.shaderUniformTexelBufferArrayNonUniformIndexing;
+	featureType.shaderStorageTexelBufferArrayNonUniformIndexing = allBlobs.vk12.shaderStorageTexelBufferArrayNonUniformIndexing;
+	featureType.descriptorBindingUniformBufferUpdateAfterBind = allBlobs.vk12.descriptorBindingUniformBufferUpdateAfterBind;
+	featureType.descriptorBindingSampledImageUpdateAfterBind = allBlobs.vk12.descriptorBindingSampledImageUpdateAfterBind;
+	featureType.descriptorBindingStorageImageUpdateAfterBind = allBlobs.vk12.descriptorBindingStorageImageUpdateAfterBind;
+	featureType.descriptorBindingStorageBufferUpdateAfterBind = allBlobs.vk12.descriptorBindingStorageBufferUpdateAfterBind;
+	featureType.descriptorBindingUniformTexelBufferUpdateAfterBind = allBlobs.vk12.descriptorBindingUniformTexelBufferUpdateAfterBind;
+	featureType.descriptorBindingStorageTexelBufferUpdateAfterBind = allBlobs.vk12.descriptorBindingStorageTexelBufferUpdateAfterBind;
+	featureType.descriptorBindingUpdateUnusedWhilePending = allBlobs.vk12.descriptorBindingUpdateUnusedWhilePending;
+	featureType.descriptorBindingPartiallyBound = allBlobs.vk12.descriptorBindingPartiallyBound;
+	featureType.descriptorBindingVariableDescriptorCount = allBlobs.vk12.descriptorBindingVariableDescriptorCount;
+	featureType.runtimeDescriptorArray = allBlobs.vk12.runtimeDescriptorArray;
+}
+template<> void initFromBlob<VkPhysicalDeviceScalarBlockLayoutFeatures>(VkPhysicalDeviceScalarBlockLayoutFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.scalarBlockLayout = allBlobs.vk12.scalarBlockLayout;
+}
+template<> void initFromBlob<VkPhysicalDeviceVulkanMemoryModelFeatures>(VkPhysicalDeviceVulkanMemoryModelFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.vulkanMemoryModel = allBlobs.vk12.vulkanMemoryModel;
+	featureType.vulkanMemoryModelDeviceScope = allBlobs.vk12.vulkanMemoryModelDeviceScope;
+	featureType.vulkanMemoryModelAvailabilityVisibilityChains = allBlobs.vk12.vulkanMemoryModelAvailabilityVisibilityChains;
+}
+template<> void initFromBlob<VkPhysicalDeviceImagelessFramebufferFeatures>(VkPhysicalDeviceImagelessFramebufferFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.imagelessFramebuffer = allBlobs.vk12.imagelessFramebuffer;
+}
+template<> void initFromBlob<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(VkPhysicalDeviceUniformBufferStandardLayoutFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.uniformBufferStandardLayout = allBlobs.vk12.uniformBufferStandardLayout;
+}
+template<> void initFromBlob<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.shaderSubgroupExtendedTypes = allBlobs.vk12.shaderSubgroupExtendedTypes;
+}
+template<> void initFromBlob<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.separateDepthStencilLayouts = allBlobs.vk12.separateDepthStencilLayouts;
+}
+template<> void initFromBlob<VkPhysicalDeviceHostQueryResetFeatures>(VkPhysicalDeviceHostQueryResetFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.hostQueryReset = allBlobs.vk12.hostQueryReset;
+}
+template<> void initFromBlob<VkPhysicalDeviceTimelineSemaphoreFeatures>(VkPhysicalDeviceTimelineSemaphoreFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.timelineSemaphore = allBlobs.vk12.timelineSemaphore;
+}
+template<> void initFromBlob<VkPhysicalDeviceBufferDeviceAddressFeatures>(VkPhysicalDeviceBufferDeviceAddressFeatures& featureType, const AllBlobs& allBlobs)
+{
+	featureType.bufferDeviceAddress = allBlobs.vk12.bufferDeviceAddress;
+	featureType.bufferDeviceAddressCaptureReplay = allBlobs.vk12.bufferDeviceAddressCaptureReplay;
+	featureType.bufferDeviceAddressMultiDevice = allBlobs.vk12.bufferDeviceAddressMultiDevice;
+}
+
+// generic template is not enough for some compilers
+template<> void initFromBlob<VkPhysicalDevicePerformanceQueryFeaturesKHR>(VkPhysicalDevicePerformanceQueryFeaturesKHR&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShaderClockFeaturesKHR>(VkPhysicalDeviceShaderClockFeaturesKHR&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(VkPhysicalDeviceTransformFeedbackFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceCornerSampledImageFeaturesNV>(VkPhysicalDeviceCornerSampledImageFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT>(VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceASTCDecodeFeaturesEXT>(VkPhysicalDeviceASTCDecodeFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(VkPhysicalDeviceConditionalRenderingFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceDepthClipEnableFeaturesEXT>(VkPhysicalDeviceDepthClipEnableFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(VkPhysicalDeviceInlineUniformBlockFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(VkPhysicalDeviceShaderSMBuiltinsFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShadingRateImageFeaturesNV>(VkPhysicalDeviceShadingRateImageFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>(VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceMeshShaderFeaturesNV>(VkPhysicalDeviceMeshShaderFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(VkPhysicalDeviceShaderImageFootprintFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceExclusiveScissorFeaturesNV>(VkPhysicalDeviceExclusiveScissorFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(VkPhysicalDeviceFragmentDensityMapFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>(VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(VkPhysicalDeviceCoherentMemoryFeaturesAMD&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceMemoryPriorityFeaturesEXT>(VkPhysicalDeviceMemoryPriorityFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(VkPhysicalDeviceCooperativeMatrixFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceCoverageReductionModeFeaturesNV>(VkPhysicalDeviceCoverageReductionModeFeaturesNV&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceLineRasterizationFeaturesEXT>(VkPhysicalDeviceLineRasterizationFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>(VkPhysicalDeviceIndexTypeUint8FeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&, const AllBlobs&) {}
+template<> void initFromBlob<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&, const AllBlobs&) {}
 
 
-static const FeatureStructMapItem featureStructCreatorMap[] =
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDevice16BitStorageFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION, 53}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDevice8BitStorageFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VK_KHR_8BIT_STORAGE_EXTENSION_NAME, VK_KHR_8BIT_STORAGE_SPEC_VERSION, 52}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceASTCDecodeFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION, 51}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION, 50}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBufferDeviceAddressFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION, 49}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION, 48}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME, 0, 47}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION, 46}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION, 45}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME, VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION, 44}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCornerSampledImageFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME, VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION, 43}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCoverageReductionModeFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME, VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION, 42}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION, 41}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDepthClipEnableFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION, 40}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceDescriptorIndexingFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION, 39}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceExclusiveScissorFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME, VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION, 38}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION, 37}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION, 36}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION, 35}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceHostQueryResetFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_EXT_HOST_QUERY_RESET_SPEC_VERSION, 34}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceImagelessFramebufferFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION, 33}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION, 32}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION, 31}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceLineRasterizationFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION, 30}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMemoryPriorityFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, VK_EXT_MEMORY_PRIORITY_SPEC_VERSION, 29}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMeshShaderFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, VK_NV_MESH_SHADER_EXTENSION_NAME, VK_NV_MESH_SHADER_SPEC_VERSION, 28}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMultiviewFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION, 27}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDevicePerformanceQueryFeaturesKHR>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION, 26}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION, 25}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceProtectedMemoryFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 24}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION, 23}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION, 22}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceScalarBlockLayoutFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION, 21}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION, 20}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderAtomicInt64Features>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION, 19}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderClockFeaturesKHR>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, VK_KHR_SHADER_CLOCK_EXTENSION_NAME, VK_KHR_SHADER_CLOCK_SPEC_VERSION, 18}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION, 17}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderDrawParametersFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION, 16}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderFloat16Int8Features>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION, 15}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME, VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION, 14}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION, 13}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME, VK_NV_SHADER_SM_BUILTINS_SPEC_VERSION, 12}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION, 11}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceShadingRateImageFeaturesNV>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME, VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION, 10}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION, 9}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION, 8}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTimelineSemaphoreFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION, 7}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION, 6}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION, 5}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVariablePointersFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION, 4}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION, 3}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceVulkanMemoryModelFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION, 2}; }
+template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME, VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION, 1}; }
+
+
+static const FeatureStructCreationData featureStructCreationArray[] =
 {
 	{ createFeatureStructWrapper<VkPhysicalDevice16BitStorageFeatures>, VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDevice8BitStorageFeaturesKHR>, VK_KHR_8BIT_STORAGE_EXTENSION_NAME, VK_KHR_8BIT_STORAGE_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDevice8BitStorageFeatures>, VK_KHR_8BIT_STORAGE_EXTENSION_NAME, VK_KHR_8BIT_STORAGE_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceASTCDecodeFeaturesEXT>, VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceBufferDeviceAddressFeatures>, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>, VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceBufferDeviceAddressFeaturesKHR>, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceCoherentMemoryFeaturesAMD>, DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME, 0 },
 	{ createFeatureStructWrapper<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>, VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceConditionalRenderingFeaturesEXT>, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION },
@@ -126,13 +279,13 @@
 	{ createFeatureStructWrapper<VkPhysicalDeviceCoverageReductionModeFeaturesNV>, VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME, VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME, VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceDepthClipEnableFeaturesEXT>, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceDescriptorIndexingFeatures>, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceExclusiveScissorFeaturesNV>, VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME, VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME, VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceHostQueryResetFeaturesEXT>, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_EXT_HOST_QUERY_RESET_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceImagelessFramebufferFeaturesKHR>, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceHostQueryResetFeatures>, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_EXT_HOST_QUERY_RESET_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceImagelessFramebufferFeatures>, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceLineRasterizationFeaturesEXT>, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION },
@@ -144,26 +297,56 @@
 	{ createFeatureStructWrapper<VkPhysicalDeviceProtectedMemoryFeatures>, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0 },
 	{ createFeatureStructWrapper<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME, VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceSamplerYcbcrConversionFeatures>, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT>, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR>, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceShaderAtomicInt64FeaturesKHR>, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceScalarBlockLayoutFeatures>, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceShaderAtomicInt64Features>, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShaderClockFeaturesKHR>, VK_KHR_SHADER_CLOCK_EXTENSION_NAME, VK_KHR_SHADER_CLOCK_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShaderDrawParametersFeatures>, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceShaderFloat16Int8FeaturesKHR>, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceShaderFloat16Int8Features>, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShaderImageFootprintFeaturesNV>, VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME, VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME, VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR>, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>, VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME, VK_NV_SHADER_SM_BUILTINS_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceShadingRateImageFeaturesNV>, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME, VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>, VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR>, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceTimelineSemaphoreFeatures>, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceTransformFeedbackFeaturesEXT>, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR>, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceVariablePointersFeatures>, VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION },
-	{ createFeatureStructWrapper<VkPhysicalDeviceVulkanMemoryModelFeaturesKHR>, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION },
+	{ createFeatureStructWrapper<VkPhysicalDeviceVulkanMemoryModelFeatures>, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION },
 	{ createFeatureStructWrapper<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>, VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME, VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION },
 };
+
+bool isPartOfBlobFeatures (VkStructureType sType)
+{
+	const std::vector<VkStructureType> sTypeVect =	{
+		// Vulkan11
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
+		// Vulkan12
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+	};
+	return de::contains(sTypeVect.begin(), sTypeVect.end(), sType);
+}
+
 } // vk
 
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl
index 323b75b..f91ce80 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl
@@ -1,54 +1,56 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  */
-const vk::VkPhysicalDevice16BitStorageFeatures&							get16BitStorageFeatures						(void) const;
-const vk::VkPhysicalDevice8BitStorageFeaturesKHR&						get8BitStorageFeatures						(void) const;
-const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			getBlendOperationAdvancedFeatures			(void) const;
-const vk::VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&				getBufferDeviceAddressFeaturesEXT			(void) const;
-const vk::VkPhysicalDeviceBufferDeviceAddressFeaturesKHR&				getBufferDeviceAddressFeatures				(void) const;
-const vk::VkPhysicalDeviceCoherentMemoryFeaturesAMD&					getCoherentMemoryFeaturesAMD				(void) const;
-const vk::VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&			getComputeShaderDerivativesFeatures			(void) const;
-const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT&				getConditionalRenderingFeatures				(void) const;
-const vk::VkPhysicalDeviceCooperativeMatrixFeaturesNV&					getCooperativeMatrixFeatures				(void) const;
-const vk::VkPhysicalDeviceCornerSampledImageFeaturesNV&					getCornerSampledImageFeatures				(void) const;
-const vk::VkPhysicalDeviceCoverageReductionModeFeaturesNV&				getCoverageReductionModeFeatures			(void) const;
-const vk::VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&	getDedicatedAllocationImageAliasingFeatures	(void) const;
-const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT&					getDepthClipEnableFeatures					(void) const;
-const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT&				getDescriptorIndexingFeatures				(void) const;
-const vk::VkPhysicalDeviceExclusiveScissorFeaturesNV&					getExclusiveScissorFeatures					(void) const;
-const vk::VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				getFragmentDensityMapFeatures				(void) const;
-const vk::VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&			getFragmentShaderBarycentricFeatures		(void) const;
-const vk::VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			getFragmentShaderInterlockFeatures			(void) const;
-const vk::VkPhysicalDeviceHostQueryResetFeaturesEXT&					getHostQueryResetFeatures					(void) const;
-const vk::VkPhysicalDeviceImagelessFramebufferFeaturesKHR&				getImagelessFramebufferFeatures				(void) const;
-const vk::VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					getIndexTypeUint8Features					(void) const;
-const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				getInlineUniformBlockFeatures				(void) const;
-const vk::VkPhysicalDeviceLineRasterizationFeaturesEXT&					getLineRasterizationFeatures				(void) const;
-const vk::VkPhysicalDeviceMemoryPriorityFeaturesEXT&					getMemoryPriorityFeatures					(void) const;
-const vk::VkPhysicalDeviceMeshShaderFeaturesNV&							getMeshShaderFeatures						(void) const;
-const vk::VkPhysicalDeviceMultiviewFeatures&							getMultiviewFeatures						(void) const;
-const vk::VkPhysicalDevicePerformanceQueryFeaturesKHR&					getPerformanceQueryFeatures					(void) const;
-const vk::VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR&		getPipelineExecutablePropertiesFeatures		(void) const;
-const vk::VkPhysicalDeviceProtectedMemoryFeatures&						getProtectedMemoryFeatures					(void) const;
-const vk::VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&			getRepresentativeFragmentTestFeatures		(void) const;
-const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&				getSamplerYcbcrConversionFeatures			(void) const;
-const vk::VkPhysicalDeviceScalarBlockLayoutFeaturesEXT&					getScalarBlockLayoutFeatures				(void) const;
-const vk::VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR&		getSeparateDepthStencilLayoutsFeatures		(void) const;
-const vk::VkPhysicalDeviceShaderAtomicInt64FeaturesKHR&					getShaderAtomicInt64Features				(void) const;
-const vk::VkPhysicalDeviceShaderClockFeaturesKHR&						getShaderClockFeatures						(void) const;
-const vk::VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	getShaderDemoteToHelperInvocationFeatures	(void) const;
-const vk::VkPhysicalDeviceShaderDrawParametersFeatures&					getShaderDrawParametersFeatures				(void) const;
-const vk::VkPhysicalDeviceShaderFloat16Int8FeaturesKHR&					getShaderFloat16Int8Features				(void) const;
-const vk::VkPhysicalDeviceShaderImageFootprintFeaturesNV&				getShaderImageFootprintFeatures				(void) const;
-const vk::VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&			getShaderIntegerFunctions2FeaturesINTEL		(void) const;
-const vk::VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR&		getShaderSubgroupExtendedTypesFeatures		(void) const;
-const vk::VkPhysicalDeviceShadingRateImageFeaturesNV&					getShadingRateImageFeatures					(void) const;
-const vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				getSubgroupSizeControlFeatures				(void) const;
-const vk::VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				getTexelBufferAlignmentFeatures				(void) const;
-const vk::VkPhysicalDeviceTimelineSemaphoreFeaturesKHR&					getTimelineSemaphoreFeatures				(void) const;
-const vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT&					getTransformFeedbackFeatures				(void) const;
-const vk::VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR&		getUniformBufferStandardLayoutFeatures		(void) const;
-const vk::VkPhysicalDeviceVariablePointersFeatures&						getVariablePointersFeatures					(void) const;
-const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			getVertexAttributeDivisorFeatures			(void) const;
-const vk::VkPhysicalDeviceVulkanMemoryModelFeaturesKHR&					getVulkanMemoryModelFeatures				(void) const;
-const vk::VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					getYcbcrImageArraysFeatures					(void) const;
+const vk::VkPhysicalDevice16BitStorageFeatures&							get16BitStorageFeatures							(void) const;
+const vk::VkPhysicalDevice8BitStorageFeatures&							get8BitStorageFeatures							(void) const;
+const vk::VkPhysicalDeviceASTCDecodeFeaturesEXT&						getASTCDecodeFeaturesEXT						(void) const;
+const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			getBlendOperationAdvancedFeaturesEXT			(void) const;
+const vk::VkPhysicalDeviceBufferDeviceAddressFeatures&					getBufferDeviceAddressFeatures					(void) const;
+const vk::VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&				getBufferDeviceAddressFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceCoherentMemoryFeaturesAMD&					getCoherentMemoryFeaturesAMD					(void) const;
+const vk::VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&			getComputeShaderDerivativesFeatures				(void) const;
+const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT&				getConditionalRenderingFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceCooperativeMatrixFeaturesNV&					getCooperativeMatrixFeatures					(void) const;
+const vk::VkPhysicalDeviceCornerSampledImageFeaturesNV&					getCornerSampledImageFeatures					(void) const;
+const vk::VkPhysicalDeviceCoverageReductionModeFeaturesNV&				getCoverageReductionModeFeatures				(void) const;
+const vk::VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&	getDedicatedAllocationImageAliasingFeatures		(void) const;
+const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT&					getDepthClipEnableFeaturesEXT					(void) const;
+const vk::VkPhysicalDeviceDescriptorIndexingFeatures&					getDescriptorIndexingFeatures					(void) const;
+const vk::VkPhysicalDeviceExclusiveScissorFeaturesNV&					getExclusiveScissorFeatures						(void) const;
+const vk::VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				getFragmentDensityMapFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&			getFragmentShaderBarycentricFeatures			(void) const;
+const vk::VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			getFragmentShaderInterlockFeaturesEXT			(void) const;
+const vk::VkPhysicalDeviceHostQueryResetFeatures&						getHostQueryResetFeatures						(void) const;
+const vk::VkPhysicalDeviceImagelessFramebufferFeatures&					getImagelessFramebufferFeatures					(void) const;
+const vk::VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					getIndexTypeUint8FeaturesEXT					(void) const;
+const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				getInlineUniformBlockFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceLineRasterizationFeaturesEXT&					getLineRasterizationFeaturesEXT					(void) const;
+const vk::VkPhysicalDeviceMemoryPriorityFeaturesEXT&					getMemoryPriorityFeaturesEXT					(void) const;
+const vk::VkPhysicalDeviceMeshShaderFeaturesNV&							getMeshShaderFeatures							(void) const;
+const vk::VkPhysicalDeviceMultiviewFeatures&							getMultiviewFeatures							(void) const;
+const vk::VkPhysicalDevicePerformanceQueryFeaturesKHR&					getPerformanceQueryFeatures						(void) const;
+const vk::VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR&		getPipelineExecutablePropertiesFeatures			(void) const;
+const vk::VkPhysicalDeviceProtectedMemoryFeatures&						getProtectedMemoryFeatures						(void) const;
+const vk::VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&			getRepresentativeFragmentTestFeatures			(void) const;
+const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&				getSamplerYcbcrConversionFeatures				(void) const;
+const vk::VkPhysicalDeviceScalarBlockLayoutFeatures&					getScalarBlockLayoutFeatures					(void) const;
+const vk::VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures&			getSeparateDepthStencilLayoutsFeatures			(void) const;
+const vk::VkPhysicalDeviceShaderAtomicInt64Features&					getShaderAtomicInt64Features					(void) const;
+const vk::VkPhysicalDeviceShaderClockFeaturesKHR&						getShaderClockFeatures							(void) const;
+const vk::VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	getShaderDemoteToHelperInvocationFeaturesEXT	(void) const;
+const vk::VkPhysicalDeviceShaderDrawParametersFeatures&					getShaderDrawParametersFeatures					(void) const;
+const vk::VkPhysicalDeviceShaderFloat16Int8Features&					getShaderFloat16Int8Features					(void) const;
+const vk::VkPhysicalDeviceShaderImageFootprintFeaturesNV&				getShaderImageFootprintFeatures					(void) const;
+const vk::VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&			getShaderIntegerFunctions2FeaturesINTEL			(void) const;
+const vk::VkPhysicalDeviceShaderSMBuiltinsFeaturesNV&					getShaderSMBuiltinsFeatures						(void) const;
+const vk::VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures&			getShaderSubgroupExtendedTypesFeatures			(void) const;
+const vk::VkPhysicalDeviceShadingRateImageFeaturesNV&					getShadingRateImageFeatures						(void) const;
+const vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				getSubgroupSizeControlFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				getTexelBufferAlignmentFeaturesEXT				(void) const;
+const vk::VkPhysicalDeviceTimelineSemaphoreFeatures&					getTimelineSemaphoreFeatures					(void) const;
+const vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT&					getTransformFeedbackFeaturesEXT					(void) const;
+const vk::VkPhysicalDeviceUniformBufferStandardLayoutFeatures&			getUniformBufferStandardLayoutFeatures			(void) const;
+const vk::VkPhysicalDeviceVariablePointersFeatures&						getVariablePointersFeatures						(void) const;
+const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			getVertexAttributeDivisorFeaturesEXT			(void) const;
+const vk::VkPhysicalDeviceVulkanMemoryModelFeatures&					getVulkanMemoryModelFeatures					(void) const;
+const vk::VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					getYcbcrImageArraysFeaturesEXT					(void) const;
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl
index 776c9ac..9ff3919 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl
@@ -2,29 +2,30 @@
  * be lost! Modify the generating script instead.
  */
 const vk::VkPhysicalDevice16BitStorageFeatures&							Context::get16BitStorageFeatures						(void) const { return m_device->get16BitStorageFeatures();						}
-const vk::VkPhysicalDevice8BitStorageFeaturesKHR&						Context::get8BitStorageFeatures							(void) const { return m_device->get8BitStorageFeatures();						}
-const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			Context::getBlendOperationAdvancedFeatures				(void) const { return m_device->getBlendOperationAdvancedFeatures();			}
+const vk::VkPhysicalDevice8BitStorageFeatures&							Context::get8BitStorageFeatures							(void) const { return m_device->get8BitStorageFeatures();						}
+const vk::VkPhysicalDeviceASTCDecodeFeaturesEXT&						Context::getASTCDecodeFeaturesEXT						(void) const { return m_device->getASTCDecodeFeaturesEXT();						}
+const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			Context::getBlendOperationAdvancedFeaturesEXT			(void) const { return m_device->getBlendOperationAdvancedFeaturesEXT();			}
+const vk::VkPhysicalDeviceBufferDeviceAddressFeatures&					Context::getBufferDeviceAddressFeatures					(void) const { return m_device->getBufferDeviceAddressFeatures();				}
 const vk::VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&				Context::getBufferDeviceAddressFeaturesEXT				(void) const { return m_device->getBufferDeviceAddressFeaturesEXT();			}
-const vk::VkPhysicalDeviceBufferDeviceAddressFeaturesKHR&				Context::getBufferDeviceAddressFeatures					(void) const { return m_device->getBufferDeviceAddressFeatures();				}
 const vk::VkPhysicalDeviceCoherentMemoryFeaturesAMD&					Context::getCoherentMemoryFeaturesAMD					(void) const { return m_device->getCoherentMemoryFeaturesAMD();					}
 const vk::VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&			Context::getComputeShaderDerivativesFeatures			(void) const { return m_device->getComputeShaderDerivativesFeatures();			}
-const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT&				Context::getConditionalRenderingFeatures				(void) const { return m_device->getConditionalRenderingFeatures();				}
+const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT&				Context::getConditionalRenderingFeaturesEXT				(void) const { return m_device->getConditionalRenderingFeaturesEXT();			}
 const vk::VkPhysicalDeviceCooperativeMatrixFeaturesNV&					Context::getCooperativeMatrixFeatures					(void) const { return m_device->getCooperativeMatrixFeatures();					}
 const vk::VkPhysicalDeviceCornerSampledImageFeaturesNV&					Context::getCornerSampledImageFeatures					(void) const { return m_device->getCornerSampledImageFeatures();				}
 const vk::VkPhysicalDeviceCoverageReductionModeFeaturesNV&				Context::getCoverageReductionModeFeatures				(void) const { return m_device->getCoverageReductionModeFeatures();				}
 const vk::VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&	Context::getDedicatedAllocationImageAliasingFeatures	(void) const { return m_device->getDedicatedAllocationImageAliasingFeatures();	}
-const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT&					Context::getDepthClipEnableFeatures						(void) const { return m_device->getDepthClipEnableFeatures();					}
-const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT&				Context::getDescriptorIndexingFeatures					(void) const { return m_device->getDescriptorIndexingFeatures();				}
+const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT&					Context::getDepthClipEnableFeaturesEXT					(void) const { return m_device->getDepthClipEnableFeaturesEXT();				}
+const vk::VkPhysicalDeviceDescriptorIndexingFeatures&					Context::getDescriptorIndexingFeatures					(void) const { return m_device->getDescriptorIndexingFeatures();				}
 const vk::VkPhysicalDeviceExclusiveScissorFeaturesNV&					Context::getExclusiveScissorFeatures					(void) const { return m_device->getExclusiveScissorFeatures();					}
-const vk::VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				Context::getFragmentDensityMapFeatures					(void) const { return m_device->getFragmentDensityMapFeatures();				}
+const vk::VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				Context::getFragmentDensityMapFeaturesEXT				(void) const { return m_device->getFragmentDensityMapFeaturesEXT();				}
 const vk::VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&			Context::getFragmentShaderBarycentricFeatures			(void) const { return m_device->getFragmentShaderBarycentricFeatures();			}
-const vk::VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			Context::getFragmentShaderInterlockFeatures				(void) const { return m_device->getFragmentShaderInterlockFeatures();			}
-const vk::VkPhysicalDeviceHostQueryResetFeaturesEXT&					Context::getHostQueryResetFeatures						(void) const { return m_device->getHostQueryResetFeatures();					}
-const vk::VkPhysicalDeviceImagelessFramebufferFeaturesKHR&				Context::getImagelessFramebufferFeatures				(void) const { return m_device->getImagelessFramebufferFeatures();				}
-const vk::VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					Context::getIndexTypeUint8Features						(void) const { return m_device->getIndexTypeUint8Features();					}
-const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				Context::getInlineUniformBlockFeatures					(void) const { return m_device->getInlineUniformBlockFeatures();				}
-const vk::VkPhysicalDeviceLineRasterizationFeaturesEXT&					Context::getLineRasterizationFeatures					(void) const { return m_device->getLineRasterizationFeatures();					}
-const vk::VkPhysicalDeviceMemoryPriorityFeaturesEXT&					Context::getMemoryPriorityFeatures						(void) const { return m_device->getMemoryPriorityFeatures();					}
+const vk::VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			Context::getFragmentShaderInterlockFeaturesEXT			(void) const { return m_device->getFragmentShaderInterlockFeaturesEXT();		}
+const vk::VkPhysicalDeviceHostQueryResetFeatures&						Context::getHostQueryResetFeatures						(void) const { return m_device->getHostQueryResetFeatures();					}
+const vk::VkPhysicalDeviceImagelessFramebufferFeatures&					Context::getImagelessFramebufferFeatures				(void) const { return m_device->getImagelessFramebufferFeatures();				}
+const vk::VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					Context::getIndexTypeUint8FeaturesEXT					(void) const { return m_device->getIndexTypeUint8FeaturesEXT();					}
+const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				Context::getInlineUniformBlockFeaturesEXT				(void) const { return m_device->getInlineUniformBlockFeaturesEXT();				}
+const vk::VkPhysicalDeviceLineRasterizationFeaturesEXT&					Context::getLineRasterizationFeaturesEXT				(void) const { return m_device->getLineRasterizationFeaturesEXT();				}
+const vk::VkPhysicalDeviceMemoryPriorityFeaturesEXT&					Context::getMemoryPriorityFeaturesEXT					(void) const { return m_device->getMemoryPriorityFeaturesEXT();					}
 const vk::VkPhysicalDeviceMeshShaderFeaturesNV&							Context::getMeshShaderFeatures							(void) const { return m_device->getMeshShaderFeatures();						}
 const vk::VkPhysicalDeviceMultiviewFeatures&							Context::getMultiviewFeatures							(void) const { return m_device->getMultiviewFeatures();							}
 const vk::VkPhysicalDevicePerformanceQueryFeaturesKHR&					Context::getPerformanceQueryFeatures					(void) const { return m_device->getPerformanceQueryFeatures();					}
@@ -32,23 +33,24 @@
 const vk::VkPhysicalDeviceProtectedMemoryFeatures&						Context::getProtectedMemoryFeatures						(void) const { return m_device->getProtectedMemoryFeatures();					}
 const vk::VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&			Context::getRepresentativeFragmentTestFeatures			(void) const { return m_device->getRepresentativeFragmentTestFeatures();		}
 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&				Context::getSamplerYcbcrConversionFeatures				(void) const { return m_device->getSamplerYcbcrConversionFeatures();			}
-const vk::VkPhysicalDeviceScalarBlockLayoutFeaturesEXT&					Context::getScalarBlockLayoutFeatures					(void) const { return m_device->getScalarBlockLayoutFeatures();					}
-const vk::VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR&		Context::getSeparateDepthStencilLayoutsFeatures			(void) const { return m_device->getSeparateDepthStencilLayoutsFeatures();		}
-const vk::VkPhysicalDeviceShaderAtomicInt64FeaturesKHR&					Context::getShaderAtomicInt64Features					(void) const { return m_device->getShaderAtomicInt64Features();					}
+const vk::VkPhysicalDeviceScalarBlockLayoutFeatures&					Context::getScalarBlockLayoutFeatures					(void) const { return m_device->getScalarBlockLayoutFeatures();					}
+const vk::VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures&			Context::getSeparateDepthStencilLayoutsFeatures			(void) const { return m_device->getSeparateDepthStencilLayoutsFeatures();		}
+const vk::VkPhysicalDeviceShaderAtomicInt64Features&					Context::getShaderAtomicInt64Features					(void) const { return m_device->getShaderAtomicInt64Features();					}
 const vk::VkPhysicalDeviceShaderClockFeaturesKHR&						Context::getShaderClockFeatures							(void) const { return m_device->getShaderClockFeatures();						}
-const vk::VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	Context::getShaderDemoteToHelperInvocationFeatures		(void) const { return m_device->getShaderDemoteToHelperInvocationFeatures();	}
+const vk::VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	Context::getShaderDemoteToHelperInvocationFeaturesEXT	(void) const { return m_device->getShaderDemoteToHelperInvocationFeaturesEXT();	}
 const vk::VkPhysicalDeviceShaderDrawParametersFeatures&					Context::getShaderDrawParametersFeatures				(void) const { return m_device->getShaderDrawParametersFeatures();				}
-const vk::VkPhysicalDeviceShaderFloat16Int8FeaturesKHR&					Context::getShaderFloat16Int8Features					(void) const { return m_device->getShaderFloat16Int8Features();					}
+const vk::VkPhysicalDeviceShaderFloat16Int8Features&					Context::getShaderFloat16Int8Features					(void) const { return m_device->getShaderFloat16Int8Features();					}
 const vk::VkPhysicalDeviceShaderImageFootprintFeaturesNV&				Context::getShaderImageFootprintFeatures				(void) const { return m_device->getShaderImageFootprintFeatures();				}
 const vk::VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&			Context::getShaderIntegerFunctions2FeaturesINTEL		(void) const { return m_device->getShaderIntegerFunctions2FeaturesINTEL();		}
-const vk::VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR&		Context::getShaderSubgroupExtendedTypesFeatures			(void) const { return m_device->getShaderSubgroupExtendedTypesFeatures();		}
+const vk::VkPhysicalDeviceShaderSMBuiltinsFeaturesNV&					Context::getShaderSMBuiltinsFeatures					(void) const { return m_device->getShaderSMBuiltinsFeatures();					}
+const vk::VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures&			Context::getShaderSubgroupExtendedTypesFeatures			(void) const { return m_device->getShaderSubgroupExtendedTypesFeatures();		}
 const vk::VkPhysicalDeviceShadingRateImageFeaturesNV&					Context::getShadingRateImageFeatures					(void) const { return m_device->getShadingRateImageFeatures();					}
-const vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				Context::getSubgroupSizeControlFeatures					(void) const { return m_device->getSubgroupSizeControlFeatures();				}
-const vk::VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				Context::getTexelBufferAlignmentFeatures				(void) const { return m_device->getTexelBufferAlignmentFeatures();				}
-const vk::VkPhysicalDeviceTimelineSemaphoreFeaturesKHR&					Context::getTimelineSemaphoreFeatures					(void) const { return m_device->getTimelineSemaphoreFeatures();					}
-const vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT&					Context::getTransformFeedbackFeatures					(void) const { return m_device->getTransformFeedbackFeatures();					}
-const vk::VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR&		Context::getUniformBufferStandardLayoutFeatures			(void) const { return m_device->getUniformBufferStandardLayoutFeatures();		}
+const vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				Context::getSubgroupSizeControlFeaturesEXT				(void) const { return m_device->getSubgroupSizeControlFeaturesEXT();			}
+const vk::VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				Context::getTexelBufferAlignmentFeaturesEXT				(void) const { return m_device->getTexelBufferAlignmentFeaturesEXT();			}
+const vk::VkPhysicalDeviceTimelineSemaphoreFeatures&					Context::getTimelineSemaphoreFeatures					(void) const { return m_device->getTimelineSemaphoreFeatures();					}
+const vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT&					Context::getTransformFeedbackFeaturesEXT				(void) const { return m_device->getTransformFeedbackFeaturesEXT();				}
+const vk::VkPhysicalDeviceUniformBufferStandardLayoutFeatures&			Context::getUniformBufferStandardLayoutFeatures			(void) const { return m_device->getUniformBufferStandardLayoutFeatures();		}
 const vk::VkPhysicalDeviceVariablePointersFeatures&						Context::getVariablePointersFeatures					(void) const { return m_device->getVariablePointersFeatures();					}
-const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			Context::getVertexAttributeDivisorFeatures				(void) const { return m_device->getVertexAttributeDivisorFeatures();			}
-const vk::VkPhysicalDeviceVulkanMemoryModelFeaturesKHR&					Context::getVulkanMemoryModelFeatures					(void) const { return m_device->getVulkanMemoryModelFeatures();					}
-const vk::VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					Context::getYcbcrImageArraysFeatures					(void) const { return m_device->getYcbcrImageArraysFeatures();					}
+const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			Context::getVertexAttributeDivisorFeaturesEXT			(void) const { return m_device->getVertexAttributeDivisorFeaturesEXT();			}
+const vk::VkPhysicalDeviceVulkanMemoryModelFeatures&					Context::getVulkanMemoryModelFeatures					(void) const { return m_device->getVulkanMemoryModelFeatures();					}
+const vk::VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					Context::getYcbcrImageArraysFeaturesEXT					(void) const { return m_device->getYcbcrImageArraysFeaturesEXT();				}
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl
index 5e38dcb..a374c52 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl
@@ -1,54 +1,56 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  */
-const VkPhysicalDevice16BitStorageFeatures&							get16BitStorageFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevice16BitStorageFeatures>();							}
-const VkPhysicalDevice8BitStorageFeaturesKHR&						get8BitStorageFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevice8BitStorageFeaturesKHR>();						}
-const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			getBlendOperationAdvancedFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>();				}
-const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&				getBufferDeviceAddressFeaturesEXT			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>();				}
-const VkPhysicalDeviceBufferDeviceAddressFeaturesKHR&				getBufferDeviceAddressFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBufferDeviceAddressFeaturesKHR>();				}
-const VkPhysicalDeviceCoherentMemoryFeaturesAMD&					getCoherentMemoryFeaturesAMD				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCoherentMemoryFeaturesAMD>();						}
-const VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&			getComputeShaderDerivativesFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>();			}
-const VkPhysicalDeviceConditionalRenderingFeaturesEXT&				getConditionalRenderingFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceConditionalRenderingFeaturesEXT>();				}
-const VkPhysicalDeviceCooperativeMatrixFeaturesNV&					getCooperativeMatrixFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCooperativeMatrixFeaturesNV>();					}
-const VkPhysicalDeviceCornerSampledImageFeaturesNV&					getCornerSampledImageFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCornerSampledImageFeaturesNV>();					}
-const VkPhysicalDeviceCoverageReductionModeFeaturesNV&				getCoverageReductionModeFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCoverageReductionModeFeaturesNV>();				}
-const VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&	getDedicatedAllocationImageAliasingFeatures	(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>();	}
-const VkPhysicalDeviceDepthClipEnableFeaturesEXT&					getDepthClipEnableFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDepthClipEnableFeaturesEXT>();					}
-const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&				getDescriptorIndexingFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();					}
-const VkPhysicalDeviceExclusiveScissorFeaturesNV&					getExclusiveScissorFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceExclusiveScissorFeaturesNV>();					}
-const VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				getFragmentDensityMapFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>();					}
-const VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&			getFragmentShaderBarycentricFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>();			}
-const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			getFragmentShaderInterlockFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>();			}
-const VkPhysicalDeviceHostQueryResetFeaturesEXT&					getHostQueryResetFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceHostQueryResetFeaturesEXT>();						}
-const VkPhysicalDeviceImagelessFramebufferFeaturesKHR&				getImagelessFramebufferFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceImagelessFramebufferFeaturesKHR>();				}
-const VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					getIndexTypeUint8Features					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>();						}
-const VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				getInlineUniformBlockFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>();					}
-const VkPhysicalDeviceLineRasterizationFeaturesEXT&					getLineRasterizationFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceLineRasterizationFeaturesEXT>();					}
-const VkPhysicalDeviceMemoryPriorityFeaturesEXT&					getMemoryPriorityFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMemoryPriorityFeaturesEXT>();						}
-const VkPhysicalDeviceMeshShaderFeaturesNV&							getMeshShaderFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMeshShaderFeaturesNV>();							}
-const VkPhysicalDeviceMultiviewFeatures&							getMultiviewFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMultiviewFeatures>();								}
-const VkPhysicalDevicePerformanceQueryFeaturesKHR&					getPerformanceQueryFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevicePerformanceQueryFeaturesKHR>();					}
-const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR&		getPipelineExecutablePropertiesFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>();		}
-const VkPhysicalDeviceProtectedMemoryFeatures&						getProtectedMemoryFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceProtectedMemoryFeatures>();						}
-const VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&			getRepresentativeFragmentTestFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>();			}
-const VkPhysicalDeviceSamplerYcbcrConversionFeatures&				getSamplerYcbcrConversionFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSamplerYcbcrConversionFeatures>();				}
-const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT&					getScalarBlockLayoutFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT>();					}
-const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR&		getSeparateDepthStencilLayoutsFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR>();		}
-const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR&					getShaderAtomicInt64Features				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderAtomicInt64FeaturesKHR>();					}
-const VkPhysicalDeviceShaderClockFeaturesKHR&						getShaderClockFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderClockFeaturesKHR>();						}
-const VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	getShaderDemoteToHelperInvocationFeatures	(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>();		}
-const VkPhysicalDeviceShaderDrawParametersFeatures&					getShaderDrawParametersFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderDrawParametersFeatures>();					}
-const VkPhysicalDeviceShaderFloat16Int8FeaturesKHR&					getShaderFloat16Int8Features				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderFloat16Int8FeaturesKHR>();					}
-const VkPhysicalDeviceShaderImageFootprintFeaturesNV&				getShaderImageFootprintFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderImageFootprintFeaturesNV>();				}
-const VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&			getShaderIntegerFunctions2FeaturesINTEL		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>();			}
-const VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR&		getShaderSubgroupExtendedTypesFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR>();		}
-const VkPhysicalDeviceShadingRateImageFeaturesNV&					getShadingRateImageFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShadingRateImageFeaturesNV>();					}
-const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				getSubgroupSizeControlFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>();				}
-const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				getTexelBufferAlignmentFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>();				}
-const VkPhysicalDeviceTimelineSemaphoreFeaturesKHR&					getTimelineSemaphoreFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR>();					}
-const VkPhysicalDeviceTransformFeedbackFeaturesEXT&					getTransformFeedbackFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();					}
-const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR&		getUniformBufferStandardLayoutFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR>();		}
-const VkPhysicalDeviceVariablePointersFeatures&						getVariablePointersFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVariablePointersFeatures>();						}
-const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			getVertexAttributeDivisorFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>();				}
-const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR&					getVulkanMemoryModelFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVulkanMemoryModelFeaturesKHR>();					}
-const VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					getYcbcrImageArraysFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>();					}
+const VkPhysicalDevice16BitStorageFeatures&							get16BitStorageFeatures							(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevice16BitStorageFeatures>();							}
+const VkPhysicalDevice8BitStorageFeatures&							get8BitStorageFeatures							(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevice8BitStorageFeatures>();							}
+const VkPhysicalDeviceASTCDecodeFeaturesEXT&						getASTCDecodeFeaturesEXT						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceASTCDecodeFeaturesEXT>();							}
+const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT&			getBlendOperationAdvancedFeaturesEXT			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>();				}
+const VkPhysicalDeviceBufferDeviceAddressFeatures&					getBufferDeviceAddressFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBufferDeviceAddressFeatures>();					}
+const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT&				getBufferDeviceAddressFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>();				}
+const VkPhysicalDeviceCoherentMemoryFeaturesAMD&					getCoherentMemoryFeaturesAMD					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCoherentMemoryFeaturesAMD>();						}
+const VkPhysicalDeviceComputeShaderDerivativesFeaturesNV&			getComputeShaderDerivativesFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>();			}
+const VkPhysicalDeviceConditionalRenderingFeaturesEXT&				getConditionalRenderingFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceConditionalRenderingFeaturesEXT>();				}
+const VkPhysicalDeviceCooperativeMatrixFeaturesNV&					getCooperativeMatrixFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCooperativeMatrixFeaturesNV>();					}
+const VkPhysicalDeviceCornerSampledImageFeaturesNV&					getCornerSampledImageFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCornerSampledImageFeaturesNV>();					}
+const VkPhysicalDeviceCoverageReductionModeFeaturesNV&				getCoverageReductionModeFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceCoverageReductionModeFeaturesNV>();				}
+const VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV&	getDedicatedAllocationImageAliasingFeatures		(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>();	}
+const VkPhysicalDeviceDepthClipEnableFeaturesEXT&					getDepthClipEnableFeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDepthClipEnableFeaturesEXT>();					}
+const VkPhysicalDeviceDescriptorIndexingFeatures&					getDescriptorIndexingFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceDescriptorIndexingFeatures>();					}
+const VkPhysicalDeviceExclusiveScissorFeaturesNV&					getExclusiveScissorFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceExclusiveScissorFeaturesNV>();					}
+const VkPhysicalDeviceFragmentDensityMapFeaturesEXT&				getFragmentDensityMapFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>();					}
+const VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV&			getFragmentShaderBarycentricFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>();			}
+const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&			getFragmentShaderInterlockFeaturesEXT			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>();			}
+const VkPhysicalDeviceHostQueryResetFeatures&						getHostQueryResetFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceHostQueryResetFeatures>();						}
+const VkPhysicalDeviceImagelessFramebufferFeatures&					getImagelessFramebufferFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceImagelessFramebufferFeatures>();					}
+const VkPhysicalDeviceIndexTypeUint8FeaturesEXT&					getIndexTypeUint8FeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>();						}
+const VkPhysicalDeviceInlineUniformBlockFeaturesEXT&				getInlineUniformBlockFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>();					}
+const VkPhysicalDeviceLineRasterizationFeaturesEXT&					getLineRasterizationFeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceLineRasterizationFeaturesEXT>();					}
+const VkPhysicalDeviceMemoryPriorityFeaturesEXT&					getMemoryPriorityFeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMemoryPriorityFeaturesEXT>();						}
+const VkPhysicalDeviceMeshShaderFeaturesNV&							getMeshShaderFeatures							(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMeshShaderFeaturesNV>();							}
+const VkPhysicalDeviceMultiviewFeatures&							getMultiviewFeatures							(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceMultiviewFeatures>();								}
+const VkPhysicalDevicePerformanceQueryFeaturesKHR&					getPerformanceQueryFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevicePerformanceQueryFeaturesKHR>();					}
+const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR&		getPipelineExecutablePropertiesFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>();		}
+const VkPhysicalDeviceProtectedMemoryFeatures&						getProtectedMemoryFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceProtectedMemoryFeatures>();						}
+const VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV&			getRepresentativeFragmentTestFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>();			}
+const VkPhysicalDeviceSamplerYcbcrConversionFeatures&				getSamplerYcbcrConversionFeatures				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSamplerYcbcrConversionFeatures>();				}
+const VkPhysicalDeviceScalarBlockLayoutFeatures&					getScalarBlockLayoutFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceScalarBlockLayoutFeatures>();						}
+const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures&			getSeparateDepthStencilLayoutsFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>();			}
+const VkPhysicalDeviceShaderAtomicInt64Features&					getShaderAtomicInt64Features					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderAtomicInt64Features>();						}
+const VkPhysicalDeviceShaderClockFeaturesKHR&						getShaderClockFeatures							(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderClockFeaturesKHR>();						}
+const VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&	getShaderDemoteToHelperInvocationFeaturesEXT	(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>();		}
+const VkPhysicalDeviceShaderDrawParametersFeatures&					getShaderDrawParametersFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderDrawParametersFeatures>();					}
+const VkPhysicalDeviceShaderFloat16Int8Features&					getShaderFloat16Int8Features					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderFloat16Int8Features>();						}
+const VkPhysicalDeviceShaderImageFootprintFeaturesNV&				getShaderImageFootprintFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderImageFootprintFeaturesNV>();				}
+const VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL&			getShaderIntegerFunctions2FeaturesINTEL			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>();			}
+const VkPhysicalDeviceShaderSMBuiltinsFeaturesNV&					getShaderSMBuiltinsFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>();					}
+const VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures&			getShaderSubgroupExtendedTypesFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>();			}
+const VkPhysicalDeviceShadingRateImageFeaturesNV&					getShadingRateImageFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceShadingRateImageFeaturesNV>();					}
+const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT&				getSubgroupSizeControlFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>();				}
+const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT&				getTexelBufferAlignmentFeaturesEXT				(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>();				}
+const VkPhysicalDeviceTimelineSemaphoreFeatures&					getTimelineSemaphoreFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTimelineSemaphoreFeatures>();						}
+const VkPhysicalDeviceTransformFeedbackFeaturesEXT&					getTransformFeedbackFeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();					}
+const VkPhysicalDeviceUniformBufferStandardLayoutFeatures&			getUniformBufferStandardLayoutFeatures			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>();			}
+const VkPhysicalDeviceVariablePointersFeatures&						getVariablePointersFeatures						(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVariablePointersFeatures>();						}
+const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&			getVertexAttributeDivisorFeaturesEXT			(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>();				}
+const VkPhysicalDeviceVulkanMemoryModelFeatures&					getVulkanMemoryModelFeatures					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceVulkanMemoryModelFeatures>();						}
+const VkPhysicalDeviceYcbcrImageArraysFeaturesEXT&					getYcbcrImageArraysFeaturesEXT					(void) const { return m_deviceFeatures.getFeatureType<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>();					}
diff --git a/external/vulkancts/framework/vulkan/vkDeviceFunctionPointers.inl b/external/vulkancts/framework/vulkan/vkDeviceFunctionPointers.inl
index 32e3126..c3acddd 100644
--- a/external/vulkancts/framework/vulkan/vkDeviceFunctionPointers.inl
+++ b/external/vulkancts/framework/vulkan/vkDeviceFunctionPointers.inl
@@ -138,6 +138,19 @@
 DestroyDescriptorUpdateTemplateFunc					destroyDescriptorUpdateTemplate;
 UpdateDescriptorSetWithTemplateFunc					updateDescriptorSetWithTemplate;
 GetDescriptorSetLayoutSupportFunc					getDescriptorSetLayoutSupport;
+CmdDrawIndirectCountFunc							cmdDrawIndirectCount;
+CmdDrawIndexedIndirectCountFunc						cmdDrawIndexedIndirectCount;
+CreateRenderPass2Func								createRenderPass2;
+CmdBeginRenderPass2Func								cmdBeginRenderPass2;
+CmdNextSubpass2Func									cmdNextSubpass2;
+CmdEndRenderPass2Func								cmdEndRenderPass2;
+ResetQueryPoolFunc									resetQueryPool;
+GetSemaphoreCounterValueFunc						getSemaphoreCounterValue;
+WaitSemaphoresFunc									waitSemaphores;
+SignalSemaphoreFunc									signalSemaphore;
+GetBufferDeviceAddressFunc							getBufferDeviceAddress;
+GetBufferOpaqueCaptureAddressFunc					getBufferOpaqueCaptureAddress;
+GetDeviceMemoryOpaqueCaptureAddressFunc				getDeviceMemoryOpaqueCaptureAddress;
 CreateSwapchainKHRFunc								createSwapchainKHR;
 DestroySwapchainKHRFunc								destroySwapchainKHR;
 GetSwapchainImagesKHRFunc							getSwapchainImagesKHR;
@@ -153,23 +166,11 @@
 GetSemaphoreFdKHRFunc								getSemaphoreFdKHR;
 CmdPushDescriptorSetKHRFunc							cmdPushDescriptorSetKHR;
 CmdPushDescriptorSetWithTemplateKHRFunc				cmdPushDescriptorSetWithTemplateKHR;
-CreateRenderPass2KHRFunc							createRenderPass2KHR;
-CmdBeginRenderPass2KHRFunc							cmdBeginRenderPass2KHR;
-CmdNextSubpass2KHRFunc								cmdNextSubpass2KHR;
-CmdEndRenderPass2KHRFunc							cmdEndRenderPass2KHR;
 GetSwapchainStatusKHRFunc							getSwapchainStatusKHR;
 ImportFenceFdKHRFunc								importFenceFdKHR;
 GetFenceFdKHRFunc									getFenceFdKHR;
 AcquireProfilingLockKHRFunc							acquireProfilingLockKHR;
 ReleaseProfilingLockKHRFunc							releaseProfilingLockKHR;
-CmdDrawIndirectCountKHRFunc							cmdDrawIndirectCountKHR;
-CmdDrawIndexedIndirectCountKHRFunc					cmdDrawIndexedIndirectCountKHR;
-GetSemaphoreCounterValueKHRFunc						getSemaphoreCounterValueKHR;
-WaitSemaphoresKHRFunc								waitSemaphoresKHR;
-SignalSemaphoreKHRFunc								signalSemaphoreKHR;
-GetBufferDeviceAddressKHRFunc						getBufferDeviceAddressKHR;
-GetBufferOpaqueCaptureAddressKHRFunc				getBufferOpaqueCaptureAddressKHR;
-GetDeviceMemoryOpaqueCaptureAddressKHRFunc			getDeviceMemoryOpaqueCaptureAddressKHR;
 GetPipelineExecutablePropertiesKHRFunc				getPipelineExecutablePropertiesKHR;
 GetPipelineExecutableStatisticsKHRFunc				getPipelineExecutableStatisticsKHR;
 GetPipelineExecutableInternalRepresentationsKHRFunc	getPipelineExecutableInternalRepresentationsKHR;
@@ -257,7 +258,6 @@
 SetLocalDimmingAMDFunc								setLocalDimmingAMD;
 GetBufferDeviceAddressEXTFunc						getBufferDeviceAddressEXT;
 CmdSetLineStippleEXTFunc							cmdSetLineStippleEXT;
-ResetQueryPoolEXTFunc								resetQueryPoolEXT;
 GetAndroidHardwareBufferPropertiesANDROIDFunc		getAndroidHardwareBufferPropertiesANDROID;
 GetMemoryAndroidHardwareBufferANDROIDFunc			getMemoryAndroidHardwareBufferANDROID;
 GetMemoryWin32HandleKHRFunc							getMemoryWin32HandleKHR;
diff --git a/external/vulkancts/framework/vulkan/vkDeviceProperties.cpp b/external/vulkancts/framework/vulkan/vkDeviceProperties.cpp
new file mode 100644
index 0000000..bf90c30
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDeviceProperties.cpp
@@ -0,0 +1,112 @@
+/*-------------------------------------------------------------------------
+* Vulkan CTS
+* ----------
+*
+* Copyright (c) 2019 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.
+*/
+
+#include "deSTLUtil.hpp"
+#include "deString.h"
+#include "vkQueryUtil.hpp"
+#include "vkDeviceProperties.inl"
+#include "vkDeviceProperties.hpp"
+
+namespace vk
+{
+
+DeviceProperties::DeviceProperties	(const InstanceInterface&			vki,
+									 const deUint32						apiVersion,
+									 const VkPhysicalDevice				physicalDevice,
+									 const std::vector<std::string>&	instanceExtensions,
+									 const std::vector<std::string>&	deviceExtensions)
+{
+	m_coreProperties2 = initVulkanStructure();
+
+	if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
+	{
+		const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+		void**										nextPtr						= &m_coreProperties2.pNext;
+
+		for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(propertyStructCreatorMap); ++i)
+		{
+			const char* propertyName = propertyStructCreatorMap[i].name;
+
+			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), propertyName))
+			{
+				PropertyStruct* p = createPropertyStructWrapper(propertyName);
+
+				if (p)
+				{
+					*nextPtr = p->getPropertyTypeRaw();
+					nextPtr = p->getPropertyTypeNext();
+					m_properties.push_back(p);
+				}
+			}
+		}
+
+		vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
+	}
+	else
+		m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
+}
+
+bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
+{
+	const size_t typesSize	= m_properties.size();
+
+	for (size_t typeIdx = 0; typeIdx < typesSize; ++typeIdx)
+	{
+		if (deStringEqual(m_properties[typeIdx]->getPropertyDesc().name, property.c_str()))
+		{
+			return true;
+		}
+	}
+
+	if (throwIfNotExists)
+	{
+		std::string msg("Property " + property + " is not supported");
+
+		TCU_THROW(NotSupportedError, msg);
+	}
+
+	return false;
+}
+
+bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
+{
+	return findStructureInChain(&m_coreProperties2, sType) != DE_NULL;
+}
+
+DeviceProperties::~DeviceProperties (void)
+{
+	for (size_t i = 0; i < m_properties.size(); ++i)
+		delete m_properties[i];
+
+	m_properties.clear();
+}
+
+PropertyStruct* DeviceProperties::createPropertyStructWrapper (const std::string& s)
+{
+	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(propertyStructCreatorMap); ++i)
+	{
+		if (deStringEqual(propertyStructCreatorMap[i].name, s.c_str()))
+			return (*propertyStructCreatorMap[i].creator)();
+	}
+
+	return DE_NULL;
+}
+
+} // vk
+
diff --git a/external/vulkancts/framework/vulkan/vkDeviceProperties.hpp b/external/vulkancts/framework/vulkan/vkDeviceProperties.hpp
new file mode 100644
index 0000000..8254587
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDeviceProperties.hpp
@@ -0,0 +1,178 @@
+#ifndef _VKDEVICEPROPERTIES_HPP
+#define _VKDEVICEPROPERTIES_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2019 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 Vulkan DeviceProperties class utility.
+ *//*--------------------------------------------------------------------*/
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "deMemory.h"
+#include "vkDefs.hpp"
+
+namespace vk
+{
+
+struct PropertyDesc
+{
+						PropertyDesc (VkStructureType sType_, const char* name_, deUint32 specVersion_, deUint32 typeId_)
+							: name			(name_)
+							, sType			(sType_)
+							, specVersion	(specVersion_)
+							, typeId		(typeId_)
+						{}
+
+	const char*			name;
+	VkStructureType		sType;
+	const deUint32		specVersion;
+	const deUint32		typeId;
+};
+
+struct PropertyStruct
+{
+	virtual deUint32		getPropertyTypeId		(void) const = 0;
+	virtual PropertyDesc	getPropertyDesc			(void) const = 0;
+	virtual void**			getPropertyTypeNext		(void) = 0;
+	virtual void*			getPropertyTypeRaw		(void) = 0;
+	virtual					~PropertyStruct			(void) {}
+};
+
+
+struct PropertyStructMapItem
+{
+	PropertyStruct*	(*creator)(void);
+	const char*		name;
+	deUint32		specVersion;
+};
+
+template<class PropertyType> struct PropertyStructWrapper;
+template<class PropertyType> PropertyDesc makePropertyDesc (void);
+
+template<class PropertyType>
+PropertyStruct* createPropertyStructWrapper (void)
+{
+	return new PropertyStructWrapper<PropertyType>(makePropertyDesc<PropertyType>());
+}
+
+class DeviceProperties
+{
+public:
+											DeviceProperties				(const InstanceInterface&			vki,
+																			 const deUint32						apiVersion,
+																			 const VkPhysicalDevice				physicalDevice,
+																			 const std::vector<std::string>&	instanceExtensions,
+																			 const std::vector<std::string>&	deviceExtensions);
+
+											~DeviceProperties				(void);
+
+	template<class PropertyType>
+	bool									getPropertyType					(PropertyType&						propertyType) const
+	{
+		typedef PropertyStructWrapper<PropertyType>	*PropertyWrapperPtr;
+
+		const VkStructureType	sType		= makePropertyDesc<PropertyType>().sType;
+		const size_t			propCount	= m_properties.size();
+
+		for (size_t propIdx = 0; propIdx < propCount; ++propIdx)
+		{
+			if (sType == m_properties[propIdx]->getPropertyDesc().sType)
+			{
+				propertyType = static_cast<PropertyWrapperPtr>(m_properties[propIdx])->getPropertyTypeRef();
+				return true;
+			}
+		}
+		return false;
+	}
+
+	template<class PropertyType>
+	const PropertyType&						getPropertyType					(void) const
+	{
+		typedef PropertyStructWrapper<PropertyType>	*PropertyWrapperPtr;
+
+		const PropertyDesc		propDesc	= makePropertyDesc<PropertyType>();
+		const VkStructureType	sType		= propDesc.sType;
+		const size_t			propCount	= m_properties.size();
+
+		for (size_t propIdx = 0; propIdx < propCount; ++propIdx)
+		{
+			if (sType == m_properties[propIdx]->getPropertyDesc().sType)
+				return static_cast<PropertyWrapperPtr>(m_properties[propIdx])->getPropertyTypeRef();
+		}
+
+		const deUint32			propertyId = propDesc.typeId;
+
+		for (size_t propIdx = 0; propIdx < propCount; ++propIdx)
+		{
+			if (propertyId == m_properties[propIdx]->getPropertyTypeId())
+				return static_cast<PropertyWrapperPtr>(m_properties[propIdx])->getPropertyTypeRef();
+		}
+
+		PropertyStruct* p = vk::createPropertyStructWrapper<PropertyType>();
+		m_properties.push_back(p);
+
+		return static_cast<PropertyWrapperPtr>(p)->getPropertyTypeRef();
+	}
+
+	const VkPhysicalDeviceProperties2&		getCoreProperties2				(void) const { return m_coreProperties2; }
+
+	bool									contains						(const std::string& property, bool throwIfNotExists = false) const;
+
+	bool									isDevicePropertyInitialized		(VkStructureType sType) const;
+
+private:
+	static PropertyStruct*					createPropertyStructWrapper		(const std::string& s);
+
+	VkPhysicalDeviceProperties2				m_coreProperties2;
+	mutable std::vector<PropertyStruct*>	m_properties;
+};
+
+template<class PropertyType>
+struct PropertyStructWrapper : PropertyStruct
+{
+	const PropertyDesc	m_propertyDesc;
+	PropertyType		m_propertyType;
+
+						PropertyStructWrapper	(void)
+							: m_propertyDesc	(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, DE_NULL, ~0u, 0u)
+						{
+							deMemset(&m_propertyType, 0, sizeof(m_propertyType));
+						}
+
+						PropertyStructWrapper	(const PropertyDesc& propertyDesc)
+							: m_propertyDesc	(propertyDesc)
+						{
+							deMemset(&m_propertyType, 0, sizeof(m_propertyType));
+							m_propertyType.sType = propertyDesc.sType;
+						}
+
+	deUint32			getPropertyTypeId		(void) const	{ return m_propertyDesc.typeId;	}
+	PropertyDesc		getPropertyDesc			(void) const	{ return m_propertyDesc;		}
+	void**				getPropertyTypeNext		(void)			{ return &m_propertyType.pNext;	}
+	void*				getPropertyTypeRaw		(void)			{ return &m_propertyType;		}
+	PropertyType&		getPropertyTypeRef		(void)			{ return m_propertyType;		}
+};
+
+} // vk
+
+#endif // _VKDEVICEPROPERTIES_HPP
diff --git a/external/vulkancts/framework/vulkan/vkDeviceProperties.inl b/external/vulkancts/framework/vulkan/vkDeviceProperties.inl
new file mode 100644
index 0000000..98ab7d5
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDeviceProperties.inl
@@ -0,0 +1,118 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ */
+#include "vkDeviceProperties.hpp"
+
+namespace vk
+{
+#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced"
+#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization"
+#define VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_NV_cooperative_matrix"
+#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve"
+#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles"
+#define DECL_DRIVER_EXTENSION_NAME "not_existent_property"
+#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host"
+#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls"
+#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map"
+#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block"
+#define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization"
+#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
+#define DECL_2_MEMORY_EXTENSION_NAME "not_existent_property"
+#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget"
+#define VK_NV_MESH_SHADER_EXTENSION_NAME  "VK_NV_mesh_shader"
+#define VK_KHR_MULTIVIEW_EXTENSION_NAME   "VK_KHR_multiview"
+#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes"
+#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query"
+#define DECL_POINT_CLIPPING_EXTENSION_NAME "not_existent_property"
+#define DECL_PROTECTED_MEMORY_EXTENSION_NAME "not_existent_property"
+#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor"
+#define VK_NV_RAY_TRACING_EXTENSION_NAME  "VK_NV_ray_tracing"
+#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax"
+#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations"
+#define DECL_AMD_SHADER_CORE_EXTENSION_NAME "not_existent_property"
+#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
+#define DECL_SUBGROUP_EXTENSION_NAME "not_existent_property"
+#define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control"
+#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment"
+#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore"
+#define DECL_EXT_TOOL_EXTENSION_NAME "not_existent_property"
+#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback"
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+
+
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION, 34); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceConservativeRasterizationPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION, 33); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceCooperativeMatrixPropertiesNV>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV, VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME, VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION, 32); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceDepthStencilResolveProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION, 31); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceDescriptorIndexingProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION, 30); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceDiscardRectanglePropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION, 29); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceDriverProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, DECL_DRIVER_EXTENSION_NAME, 0, 28); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceExternalMemoryHostPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT, VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION, 27); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceFloatControlsProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION, 26); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceFragmentDensityMapPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION, 25); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceInlineUniformBlockPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION, 24); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceLineRasterizationPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION, 23); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMaintenance3Properties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_MAINTENANCE3_SPEC_VERSION, 22); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMemoryProperties2>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, DECL_2_MEMORY_EXTENSION_NAME, 0, 21); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMemoryBudgetPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, VK_EXT_MEMORY_BUDGET_SPEC_VERSION, 20); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMeshShaderPropertiesNV>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV, VK_NV_MESH_SHADER_EXTENSION_NAME, VK_NV_MESH_SHADER_SPEC_VERSION, 19); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMultiviewProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION, 18); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION, 17); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDevicePerformanceQueryPropertiesKHR>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION, 16); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDevicePointClippingProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, DECL_POINT_CLIPPING_EXTENSION_NAME, 0, 15); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceProtectedMemoryProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 14); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDevicePushDescriptorPropertiesKHR>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION, 13); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceRayTracingPropertiesNV>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV, VK_NV_RAY_TRACING_EXTENSION_NAME, VK_NV_RAY_TRACING_SPEC_VERSION, 12); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceSamplerFilterMinmaxProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION, 11); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceSampleLocationsPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION, 10); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceShaderCorePropertiesAMD>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD, DECL_AMD_SHADER_CORE_EXTENSION_NAME, 0, 9); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceShadingRateImagePropertiesNV>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME, VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION, 8); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceSubgroupProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES, DECL_SUBGROUP_EXTENSION_NAME, 0, 7); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceSubgroupSizeControlPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION, 6); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT, VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION, 5); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceTimelineSemaphoreProperties>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION, 4); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceToolPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT, DECL_EXT_TOOL_EXTENSION_NAME, 0, 3); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceTransformFeedbackPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION, 2); }
+template<> PropertyDesc makePropertyDesc<VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT>(void) { return PropertyDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION, 1); }
+
+
+static const PropertyStructMapItem propertyStructCreatorMap[] =
+{
+	{ createPropertyStructWrapper<VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT>, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceConservativeRasterizationPropertiesEXT>, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceCooperativeMatrixPropertiesNV>, VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME, VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceDepthStencilResolveProperties>, VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceDescriptorIndexingProperties>, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceDiscardRectanglePropertiesEXT>, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceDriverProperties>, DECL_DRIVER_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceExternalMemoryHostPropertiesEXT>, VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceFloatControlsProperties>, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceFragmentDensityMapPropertiesEXT>, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceInlineUniformBlockPropertiesEXT>, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceLineRasterizationPropertiesEXT>, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMaintenance3Properties>, VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_MAINTENANCE3_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMemoryProperties2>, DECL_2_MEMORY_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMemoryBudgetPropertiesEXT>, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, VK_EXT_MEMORY_BUDGET_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMeshShaderPropertiesNV>, VK_NV_MESH_SHADER_EXTENSION_NAME, VK_NV_MESH_SHADER_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMultiviewProperties>, VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX>, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDevicePerformanceQueryPropertiesKHR>, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDevicePointClippingProperties>, DECL_POINT_CLIPPING_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDevicePushDescriptorPropertiesKHR>, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceRayTracingPropertiesNV>, VK_NV_RAY_TRACING_EXTENSION_NAME, VK_NV_RAY_TRACING_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceSamplerFilterMinmaxProperties>, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceSampleLocationsPropertiesEXT>, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceShaderCorePropertiesAMD>, DECL_AMD_SHADER_CORE_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceShadingRateImagePropertiesNV>, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME, VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>, DECL_SUBGROUP_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceSubgroupSizeControlPropertiesEXT>, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT>, VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceTimelineSemaphoreProperties>, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceToolPropertiesEXT>, DECL_EXT_TOOL_EXTENSION_NAME, 0 },
+	{ createPropertyStructWrapper<VkPhysicalDeviceTransformFeedbackPropertiesEXT>, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION },
+	{ createPropertyStructWrapper<VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT>, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION },
+};
+} // vk
+
diff --git a/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDecl.inl b/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDecl.inl
new file mode 100644
index 0000000..237dca0
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDecl.inl
@@ -0,0 +1,37 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ */
+const vk::VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT&		getBlendOperationAdvancedPropertiesEXT		(void) const;
+const vk::VkPhysicalDeviceConservativeRasterizationPropertiesEXT&	getConservativeRasterizationPropertiesEXT	(void) const;
+const vk::VkPhysicalDeviceCooperativeMatrixPropertiesNV&			getCooperativeMatrixProperties				(void) const;
+const vk::VkPhysicalDeviceDepthStencilResolveProperties&			getDepthStencilResolveProperties			(void) const;
+const vk::VkPhysicalDeviceDescriptorIndexingProperties&				getDescriptorIndexingProperties				(void) const;
+const vk::VkPhysicalDeviceDiscardRectanglePropertiesEXT&			getDiscardRectanglePropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceDriverProperties&							getDriverProperties							(void) const;
+const vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT&			getExternalMemoryHostPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceFloatControlsProperties&					getFloatControlsProperties					(void) const;
+const vk::VkPhysicalDeviceFragmentDensityMapPropertiesEXT&			getFragmentDensityMapPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceInlineUniformBlockPropertiesEXT&			getInlineUniformBlockPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceLineRasterizationPropertiesEXT&			getLineRasterizationPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceMaintenance3Properties&					getMaintenance3Properties					(void) const;
+const vk::VkPhysicalDeviceMemoryProperties2&						getMemoryProperties2						(void) const;
+const vk::VkPhysicalDeviceMemoryBudgetPropertiesEXT&				getMemoryBudgetPropertiesEXT				(void) const;
+const vk::VkPhysicalDeviceMeshShaderPropertiesNV&					getMeshShaderProperties						(void) const;
+const vk::VkPhysicalDeviceMultiviewProperties&						getMultiviewProperties						(void) const;
+const vk::VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX&	getMultiviewPerViewAttributesPropertiesX	(void) const;
+const vk::VkPhysicalDevicePerformanceQueryPropertiesKHR&			getPerformanceQueryProperties				(void) const;
+const vk::VkPhysicalDevicePointClippingProperties&					getPointClippingProperties					(void) const;
+const vk::VkPhysicalDeviceProtectedMemoryProperties&				getProtectedMemoryProperties				(void) const;
+const vk::VkPhysicalDevicePushDescriptorPropertiesKHR&				getPushDescriptorProperties					(void) const;
+const vk::VkPhysicalDeviceRayTracingPropertiesNV&					getRayTracingProperties						(void) const;
+const vk::VkPhysicalDeviceSamplerFilterMinmaxProperties&			getSamplerFilterMinmaxProperties			(void) const;
+const vk::VkPhysicalDeviceSampleLocationsPropertiesEXT&				getSampleLocationsPropertiesEXT				(void) const;
+const vk::VkPhysicalDeviceShaderCorePropertiesAMD&					getShaderCorePropertiesAMD					(void) const;
+const vk::VkPhysicalDeviceShadingRateImagePropertiesNV&				getShadingRateImageProperties				(void) const;
+const vk::VkPhysicalDeviceSubgroupProperties&						getSubgroupProperties						(void) const;
+const vk::VkPhysicalDeviceSubgroupSizeControlPropertiesEXT&			getSubgroupSizeControlPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT&		getTexelBufferAlignmentPropertiesEXT		(void) const;
+const vk::VkPhysicalDeviceTimelineSemaphoreProperties&				getTimelineSemaphoreProperties				(void) const;
+const vk::VkPhysicalDeviceToolPropertiesEXT&						getToolPropertiesEXT						(void) const;
+const vk::VkPhysicalDeviceTransformFeedbackPropertiesEXT&			getTransformFeedbackPropertiesEXT			(void) const;
+const vk::VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT&		getVertexAttributeDivisorPropertiesEXT		(void) const;
diff --git a/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDefs.inl b/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDefs.inl
new file mode 100644
index 0000000..0f048b8
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDevicePropertiesForContextDefs.inl
@@ -0,0 +1,37 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ */
+const vk::VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT&		Context::getBlendOperationAdvancedPropertiesEXT		(void) const { return m_device->getBlendOperationAdvancedPropertiesEXT();		}
+const vk::VkPhysicalDeviceConservativeRasterizationPropertiesEXT&	Context::getConservativeRasterizationPropertiesEXT	(void) const { return m_device->getConservativeRasterizationPropertiesEXT();	}
+const vk::VkPhysicalDeviceCooperativeMatrixPropertiesNV&			Context::getCooperativeMatrixProperties				(void) const { return m_device->getCooperativeMatrixProperties();				}
+const vk::VkPhysicalDeviceDepthStencilResolveProperties&			Context::getDepthStencilResolveProperties			(void) const { return m_device->getDepthStencilResolveProperties();				}
+const vk::VkPhysicalDeviceDescriptorIndexingProperties&				Context::getDescriptorIndexingProperties			(void) const { return m_device->getDescriptorIndexingProperties();				}
+const vk::VkPhysicalDeviceDiscardRectanglePropertiesEXT&			Context::getDiscardRectanglePropertiesEXT			(void) const { return m_device->getDiscardRectanglePropertiesEXT();				}
+const vk::VkPhysicalDeviceDriverProperties&							Context::getDriverProperties						(void) const { return m_device->getDriverProperties();							}
+const vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT&			Context::getExternalMemoryHostPropertiesEXT			(void) const { return m_device->getExternalMemoryHostPropertiesEXT();			}
+const vk::VkPhysicalDeviceFloatControlsProperties&					Context::getFloatControlsProperties					(void) const { return m_device->getFloatControlsProperties();					}
+const vk::VkPhysicalDeviceFragmentDensityMapPropertiesEXT&			Context::getFragmentDensityMapPropertiesEXT			(void) const { return m_device->getFragmentDensityMapPropertiesEXT();			}
+const vk::VkPhysicalDeviceInlineUniformBlockPropertiesEXT&			Context::getInlineUniformBlockPropertiesEXT			(void) const { return m_device->getInlineUniformBlockPropertiesEXT();			}
+const vk::VkPhysicalDeviceLineRasterizationPropertiesEXT&			Context::getLineRasterizationPropertiesEXT			(void) const { return m_device->getLineRasterizationPropertiesEXT();			}
+const vk::VkPhysicalDeviceMaintenance3Properties&					Context::getMaintenance3Properties					(void) const { return m_device->getMaintenance3Properties();					}
+const vk::VkPhysicalDeviceMemoryProperties2&						Context::getMemoryProperties2						(void) const { return m_device->getMemoryProperties2();							}
+const vk::VkPhysicalDeviceMemoryBudgetPropertiesEXT&				Context::getMemoryBudgetPropertiesEXT				(void) const { return m_device->getMemoryBudgetPropertiesEXT();					}
+const vk::VkPhysicalDeviceMeshShaderPropertiesNV&					Context::getMeshShaderProperties					(void) const { return m_device->getMeshShaderProperties();						}
+const vk::VkPhysicalDeviceMultiviewProperties&						Context::getMultiviewProperties						(void) const { return m_device->getMultiviewProperties();						}
+const vk::VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX&	Context::getMultiviewPerViewAttributesPropertiesX	(void) const { return m_device->getMultiviewPerViewAttributesPropertiesX();		}
+const vk::VkPhysicalDevicePerformanceQueryPropertiesKHR&			Context::getPerformanceQueryProperties				(void) const { return m_device->getPerformanceQueryProperties();				}
+const vk::VkPhysicalDevicePointClippingProperties&					Context::getPointClippingProperties					(void) const { return m_device->getPointClippingProperties();					}
+const vk::VkPhysicalDeviceProtectedMemoryProperties&				Context::getProtectedMemoryProperties				(void) const { return m_device->getProtectedMemoryProperties();					}
+const vk::VkPhysicalDevicePushDescriptorPropertiesKHR&				Context::getPushDescriptorProperties				(void) const { return m_device->getPushDescriptorProperties();					}
+const vk::VkPhysicalDeviceRayTracingPropertiesNV&					Context::getRayTracingProperties					(void) const { return m_device->getRayTracingProperties();						}
+const vk::VkPhysicalDeviceSamplerFilterMinmaxProperties&			Context::getSamplerFilterMinmaxProperties			(void) const { return m_device->getSamplerFilterMinmaxProperties();				}
+const vk::VkPhysicalDeviceSampleLocationsPropertiesEXT&				Context::getSampleLocationsPropertiesEXT			(void) const { return m_device->getSampleLocationsPropertiesEXT();				}
+const vk::VkPhysicalDeviceShaderCorePropertiesAMD&					Context::getShaderCorePropertiesAMD					(void) const { return m_device->getShaderCorePropertiesAMD();					}
+const vk::VkPhysicalDeviceShadingRateImagePropertiesNV&				Context::getShadingRateImageProperties				(void) const { return m_device->getShadingRateImageProperties();				}
+const vk::VkPhysicalDeviceSubgroupProperties&						Context::getSubgroupProperties						(void) const { return m_device->getSubgroupProperties();						}
+const vk::VkPhysicalDeviceSubgroupSizeControlPropertiesEXT&			Context::getSubgroupSizeControlPropertiesEXT		(void) const { return m_device->getSubgroupSizeControlPropertiesEXT();			}
+const vk::VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT&		Context::getTexelBufferAlignmentPropertiesEXT		(void) const { return m_device->getTexelBufferAlignmentPropertiesEXT();			}
+const vk::VkPhysicalDeviceTimelineSemaphoreProperties&				Context::getTimelineSemaphoreProperties				(void) const { return m_device->getTimelineSemaphoreProperties();				}
+const vk::VkPhysicalDeviceToolPropertiesEXT&						Context::getToolPropertiesEXT						(void) const { return m_device->getToolPropertiesEXT();							}
+const vk::VkPhysicalDeviceTransformFeedbackPropertiesEXT&			Context::getTransformFeedbackPropertiesEXT			(void) const { return m_device->getTransformFeedbackPropertiesEXT();			}
+const vk::VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT&		Context::getVertexAttributeDivisorPropertiesEXT		(void) const { return m_device->getVertexAttributeDivisorPropertiesEXT();		}
diff --git a/external/vulkancts/framework/vulkan/vkDevicePropertiesForDefaultDeviceDefs.inl b/external/vulkancts/framework/vulkan/vkDevicePropertiesForDefaultDeviceDefs.inl
new file mode 100644
index 0000000..21c8a39
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkDevicePropertiesForDefaultDeviceDefs.inl
@@ -0,0 +1,37 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ */
+const VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT&		getBlendOperationAdvancedPropertiesEXT		(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT>();		}
+const VkPhysicalDeviceConservativeRasterizationPropertiesEXT&	getConservativeRasterizationPropertiesEXT	(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceConservativeRasterizationPropertiesEXT>();		}
+const VkPhysicalDeviceCooperativeMatrixPropertiesNV&			getCooperativeMatrixProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceCooperativeMatrixPropertiesNV>();				}
+const VkPhysicalDeviceDepthStencilResolveProperties&			getDepthStencilResolveProperties			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceDepthStencilResolveProperties>();				}
+const VkPhysicalDeviceDescriptorIndexingProperties&				getDescriptorIndexingProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceDescriptorIndexingProperties>();				}
+const VkPhysicalDeviceDiscardRectanglePropertiesEXT&			getDiscardRectanglePropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceDiscardRectanglePropertiesEXT>();				}
+const VkPhysicalDeviceDriverProperties&							getDriverProperties							(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceDriverProperties>();							}
+const VkPhysicalDeviceExternalMemoryHostPropertiesEXT&			getExternalMemoryHostPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceExternalMemoryHostPropertiesEXT>();			}
+const VkPhysicalDeviceFloatControlsProperties&					getFloatControlsProperties					(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceFloatControlsProperties>();					}
+const VkPhysicalDeviceFragmentDensityMapPropertiesEXT&			getFragmentDensityMapPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceFragmentDensityMapPropertiesEXT>();			}
+const VkPhysicalDeviceInlineUniformBlockPropertiesEXT&			getInlineUniformBlockPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceInlineUniformBlockPropertiesEXT>();			}
+const VkPhysicalDeviceLineRasterizationPropertiesEXT&			getLineRasterizationPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceLineRasterizationPropertiesEXT>();				}
+const VkPhysicalDeviceMaintenance3Properties&					getMaintenance3Properties					(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMaintenance3Properties>();						}
+const VkPhysicalDeviceMemoryProperties2&						getMemoryProperties2						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMemoryProperties2>();							}
+const VkPhysicalDeviceMemoryBudgetPropertiesEXT&				getMemoryBudgetPropertiesEXT				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMemoryBudgetPropertiesEXT>();					}
+const VkPhysicalDeviceMeshShaderPropertiesNV&					getMeshShaderProperties						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMeshShaderPropertiesNV>();						}
+const VkPhysicalDeviceMultiviewProperties&						getMultiviewProperties						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMultiviewProperties>();						}
+const VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX&	getMultiviewPerViewAttributesPropertiesX	(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX>();	}
+const VkPhysicalDevicePerformanceQueryPropertiesKHR&			getPerformanceQueryProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDevicePerformanceQueryPropertiesKHR>();				}
+const VkPhysicalDevicePointClippingProperties&					getPointClippingProperties					(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDevicePointClippingProperties>();					}
+const VkPhysicalDeviceProtectedMemoryProperties&				getProtectedMemoryProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceProtectedMemoryProperties>();					}
+const VkPhysicalDevicePushDescriptorPropertiesKHR&				getPushDescriptorProperties					(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDevicePushDescriptorPropertiesKHR>();				}
+const VkPhysicalDeviceRayTracingPropertiesNV&					getRayTracingProperties						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceRayTracingPropertiesNV>();						}
+const VkPhysicalDeviceSamplerFilterMinmaxProperties&			getSamplerFilterMinmaxProperties			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceSamplerFilterMinmaxProperties>();				}
+const VkPhysicalDeviceSampleLocationsPropertiesEXT&				getSampleLocationsPropertiesEXT				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceSampleLocationsPropertiesEXT>();				}
+const VkPhysicalDeviceShaderCorePropertiesAMD&					getShaderCorePropertiesAMD					(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceShaderCorePropertiesAMD>();					}
+const VkPhysicalDeviceShadingRateImagePropertiesNV&				getShadingRateImageProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceShadingRateImagePropertiesNV>();				}
+const VkPhysicalDeviceSubgroupProperties&						getSubgroupProperties						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceSubgroupProperties>();							}
+const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT&			getSubgroupSizeControlPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceSubgroupSizeControlPropertiesEXT>();			}
+const VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT&		getTexelBufferAlignmentPropertiesEXT		(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT>();			}
+const VkPhysicalDeviceTimelineSemaphoreProperties&				getTimelineSemaphoreProperties				(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceTimelineSemaphoreProperties>();				}
+const VkPhysicalDeviceToolPropertiesEXT&						getToolPropertiesEXT						(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceToolPropertiesEXT>();							}
+const VkPhysicalDeviceTransformFeedbackPropertiesEXT&			getTransformFeedbackPropertiesEXT			(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();				}
+const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT&		getVertexAttributeDivisorPropertiesEXT		(void) const { return m_devicePropertiesFull.getPropertyType<VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT>();		}
diff --git a/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl b/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl
index d8f2d9a..8b2b2da 100644
--- a/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl
+++ b/external/vulkancts/framework/vulkan/vkExtensionFunctions.inl
@@ -105,6 +105,10 @@
 	{
 		functions.push_back("vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
 	}
+	else if (extName == "VK_EXT_tooling_info")
+	{
+		functions.push_back("vkGetPhysicalDeviceToolPropertiesEXT");
+	}
 	else if (extName == "VK_NV_cooperative_matrix")
 	{
 		functions.push_back("vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
@@ -516,6 +520,7 @@
 	"VK_EXT_direct_mode_display",
 	"VK_EXT_display_surface_counter",
 	"VK_EXT_calibrated_timestamps",
+	"VK_EXT_tooling_info",
 	"VK_NV_cooperative_matrix",
 	"VK_NV_coverage_reduction_mode",
 	"VK_EXT_headless_surface",
diff --git a/external/vulkancts/framework/vulkan/vkFunctionPointerTypes.inl b/external/vulkancts/framework/vulkan/vkFunctionPointerTypes.inl
index 29cd294..ab0894b 100644
--- a/external/vulkancts/framework/vulkan/vkFunctionPointerTypes.inl
+++ b/external/vulkancts/framework/vulkan/vkFunctionPointerTypes.inl
@@ -166,6 +166,19 @@
 typedef VKAPI_ATTR void					(VKAPI_CALL* GetPhysicalDeviceExternalFencePropertiesFunc)							(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties);
 typedef VKAPI_ATTR void					(VKAPI_CALL* GetPhysicalDeviceExternalSemaphorePropertiesFunc)						(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
 typedef VKAPI_ATTR void					(VKAPI_CALL* GetDescriptorSetLayoutSupportFunc)										(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdDrawIndirectCountFunc)												(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdDrawIndexedIndirectCountFunc)										(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* CreateRenderPass2Func)													(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdBeginRenderPass2Func)												(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdNextSubpass2Func)													(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdEndRenderPass2Func)													(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef VKAPI_ATTR void					(VKAPI_CALL* ResetQueryPoolFunc)													(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetSemaphoreCounterValueFunc)											(VkDevice device, VkSemaphore semaphore, deUint64* pValue);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* WaitSemaphoresFunc)													(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* SignalSemaphoreFunc)													(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+typedef VKAPI_ATTR VkDeviceAddress		(VKAPI_CALL* GetBufferDeviceAddressFunc)											(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetBufferOpaqueCaptureAddressFunc)										(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetDeviceMemoryOpaqueCaptureAddressFunc)								(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 typedef VKAPI_ATTR void					(VKAPI_CALL* DestroySurfaceKHRFunc)													(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPhysicalDeviceSurfaceSupportKHRFunc)								(VkPhysicalDevice physicalDevice, deUint32 queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPhysicalDeviceSurfaceCapabilitiesKHRFunc)							(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
@@ -211,10 +224,10 @@
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* CreateDescriptorUpdateTemplateKHRFunc)									(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
 typedef VKAPI_ATTR void					(VKAPI_CALL* DestroyDescriptorUpdateTemplateKHRFunc)								(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator);
 typedef VKAPI_ATTR void					(VKAPI_CALL* UpdateDescriptorSetWithTemplateKHRFunc)								(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData);
-typedef VKAPI_ATTR VkResult				(VKAPI_CALL* CreateRenderPass2KHRFunc)												(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
-typedef VKAPI_ATTR void					(VKAPI_CALL* CmdBeginRenderPass2KHRFunc)											(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo);
-typedef VKAPI_ATTR void					(VKAPI_CALL* CmdNextSubpass2KHRFunc)												(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo);
-typedef VKAPI_ATTR void					(VKAPI_CALL* CmdEndRenderPass2KHRFunc)												(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* CreateRenderPass2KHRFunc)												(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdBeginRenderPass2KHRFunc)											(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdNextSubpass2KHRFunc)												(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef VKAPI_ATTR void					(VKAPI_CALL* CmdEndRenderPass2KHRFunc)												(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetSwapchainStatusKHRFunc)												(VkDevice device, VkSwapchainKHR swapchain);
 typedef VKAPI_ATTR void					(VKAPI_CALL* GetPhysicalDeviceExternalFencePropertiesKHRFunc)						(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* ImportFenceFdKHRFunc)													(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
@@ -240,11 +253,11 @@
 typedef VKAPI_ATTR void					(VKAPI_CALL* CmdDrawIndirectCountKHRFunc)											(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
 typedef VKAPI_ATTR void					(VKAPI_CALL* CmdDrawIndexedIndirectCountKHRFunc)									(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetSemaphoreCounterValueKHRFunc)										(VkDevice device, VkSemaphore semaphore, deUint64* pValue);
-typedef VKAPI_ATTR VkResult				(VKAPI_CALL* WaitSemaphoresKHRFunc)													(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout);
-typedef VKAPI_ATTR VkResult				(VKAPI_CALL* SignalSemaphoreKHRFunc)												(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo);
-typedef VKAPI_ATTR VkDeviceAddress		(VKAPI_CALL* GetBufferDeviceAddressKHRFunc)											(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetBufferOpaqueCaptureAddressKHRFunc)									(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetDeviceMemoryOpaqueCaptureAddressKHRFunc)							(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* WaitSemaphoresKHRFunc)													(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* SignalSemaphoreKHRFunc)												(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+typedef VKAPI_ATTR VkDeviceAddress		(VKAPI_CALL* GetBufferDeviceAddressKHRFunc)											(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetBufferOpaqueCaptureAddressKHRFunc)									(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef VKAPI_ATTR uint64_t				(VKAPI_CALL* GetDeviceMemoryOpaqueCaptureAddressKHRFunc)							(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPipelineExecutablePropertiesKHRFunc)								(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, deUint32* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPipelineExecutableStatisticsKHRFunc)								(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPipelineExecutableInternalRepresentationsKHRFunc)					(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations);
@@ -342,7 +355,8 @@
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* QueueSetPerformanceConfigurationINTELFunc)								(VkQueue queue, VkPerformanceConfigurationINTEL configuration);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPerformanceParameterINTELFunc)										(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue);
 typedef VKAPI_ATTR void					(VKAPI_CALL* SetLocalDimmingAMDFunc)												(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable);
-typedef VKAPI_ATTR VkDeviceAddress		(VKAPI_CALL* GetBufferDeviceAddressEXTFunc)											(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
+typedef VKAPI_ATTR VkDeviceAddress		(VKAPI_CALL* GetBufferDeviceAddressEXTFunc)											(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPhysicalDeviceToolPropertiesEXTFunc)								(VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPhysicalDeviceCooperativeMatrixPropertiesNVFunc)					(VkPhysicalDevice physicalDevice, deUint32* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNVFunc)	(VkPhysicalDevice physicalDevice, deUint32* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations);
 typedef VKAPI_ATTR VkResult				(VKAPI_CALL* CreateHeadlessSurfaceEXTFunc)											(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
diff --git a/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl b/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl
index d85e138..deb36cf 100644
--- a/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl
@@ -561,6 +561,256 @@
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
 }
 
+template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan11Features> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan11Properties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan12Features> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan12Properties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkImageFormatListCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkAttachmentDescription2> (void)
+{
+	return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
+}
+
+template<> VkStructureType getStructureType<VkAttachmentReference2> (void)
+{
+	return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
+}
+
+template<> VkStructureType getStructureType<VkSubpassDescription2> (void)
+{
+	return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
+}
+
+template<> VkStructureType getStructureType<VkSubpassDependency2> (void)
+{
+	return VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
+}
+
+template<> VkStructureType getStructureType<VkRenderPassCreateInfo2> (void)
+{
+	return VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
+}
+
+template<> VkStructureType getStructureType<VkSubpassBeginInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
+}
+
+template<> VkStructureType getStructureType<VkSubpassEndInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDevice8BitStorageFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceDriverProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceShaderAtomicInt64Features> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceShaderFloat16Int8Features> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceFloatControlsProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkDescriptorSetLayoutBindingFlagsCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountAllocateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountLayoutSupport> (void)
+{
+	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT;
+}
+
+template<> VkStructureType getStructureType<VkSubpassDescriptionDepthStencilResolve> (void)
+{
+	return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceDepthStencilResolveProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceScalarBlockLayoutFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkImageStencilUsageCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkSamplerReductionModeCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceSamplerFilterMinmaxProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceVulkanMemoryModelFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceImagelessFramebufferFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkFramebufferAttachmentImageInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkFramebufferAttachmentsCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkRenderPassAttachmentBeginInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkAttachmentReferenceStencilLayout> (void)
+{
+	return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT;
+}
+
+template<> VkStructureType getStructureType<VkAttachmentDescriptionStencilLayout> (void)
+{
+	return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceHostQueryResetFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreProperties> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;
+}
+
+template<> VkStructureType getStructureType<VkSemaphoreTypeCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkTimelineSemaphoreSubmitInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
+}
+
+template<> VkStructureType getStructureType<VkSemaphoreWaitInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
+}
+
+template<> VkStructureType getStructureType<VkSemaphoreSignalInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
+}
+
+template<> VkStructureType getStructureType<VkPhysicalDeviceBufferDeviceAddressFeatures> (void)
+{
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
+}
+
+template<> VkStructureType getStructureType<VkBufferDeviceAddressInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
+}
+
+template<> VkStructureType getStructureType<VkBufferOpaqueCaptureAddressCreateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkMemoryOpaqueCaptureAddressAllocateInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO;
+}
+
+template<> VkStructureType getStructureType<VkDeviceMemoryOpaqueCaptureAddressInfo> (void)
+{
+	return VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO;
+}
+
 template<> VkStructureType getStructureType<VkSwapchainCreateInfoKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@@ -646,71 +896,11 @@
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceShaderFloat16Int8FeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
-}
-
 template<> VkStructureType getStructureType<VkPresentRegionsKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceImagelessFramebufferFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkFramebufferAttachmentImageInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkFramebufferAttachmentsCreateInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkRenderPassAttachmentBeginInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkAttachmentDescription2KHR> (void)
-{
-	return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
-}
-
-template<> VkStructureType getStructureType<VkAttachmentReference2KHR> (void)
-{
-	return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSubpassDescription2KHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSubpassDependency2KHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
-}
-
-template<> VkStructureType getStructureType<VkRenderPassCreateInfo2KHR> (void)
-{
-	return VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSubpassBeginInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSubpassEndInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR;
-}
-
 template<> VkStructureType getStructureType<VkSharedPresentSurfaceCapabilitiesKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
@@ -801,136 +991,16 @@
 	return VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
 }
 
-template<> VkStructureType getStructureType<VkImageFormatListCreateInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDevice8BitStorageFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceShaderAtomicInt64FeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
-}
-
 template<> VkStructureType getStructureType<VkPhysicalDeviceShaderClockFeaturesKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceDriverPropertiesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceFloatControlsPropertiesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSubpassDescriptionDepthStencilResolveKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceDepthStencilResolvePropertiesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphorePropertiesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSemaphoreTypeCreateInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkTimelineSemaphoreSubmitInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSemaphoreWaitInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkSemaphoreSignalInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceVulkanMemoryModelFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
-}
-
 template<> VkStructureType getStructureType<VkSurfaceProtectedCapabilitiesKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkAttachmentReferenceStencilLayoutKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR;
-}
-
-template<> VkStructureType getStructureType<VkAttachmentDescriptionStencilLayoutKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceBufferDeviceAddressFeaturesKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
-}
-
-template<> VkStructureType getStructureType<VkBufferDeviceAddressInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkBufferOpaqueCaptureAddressCreateInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkMemoryOpaqueCaptureAddressAllocateInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR;
-}
-
-template<> VkStructureType getStructureType<VkDeviceMemoryOpaqueCaptureAddressInfoKHR> (void)
-{
-	return VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR;
-}
-
 template<> VkStructureType getStructureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR> (void)
 {
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
@@ -1211,16 +1281,6 @@
 	return VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
 }
 
-template<> VkStructureType getStructureType<VkSamplerReductionModeCreateInfoEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT;
-}
-
 template<> VkStructureType getStructureType<VkPhysicalDeviceInlineUniformBlockFeaturesEXT> (void)
 {
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
@@ -1336,31 +1396,6 @@
 	return VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT;
 }
 
-template<> VkStructureType getStructureType<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingFeaturesEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
-}
-
-template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingPropertiesEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
-}
-
-template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountAllocateInfoEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT;
-}
-
-template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountLayoutSupportEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT;
-}
-
 template<> VkStructureType getStructureType<VkPipelineViewportShadingRateImageStateCreateInfoNV> (void)
 {
 	return VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV;
@@ -1626,11 +1661,6 @@
 	return VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
-}
-
 template<> VkStructureType getStructureType<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT> (void)
 {
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT;
@@ -1686,9 +1716,9 @@
 	return VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT;
 }
 
-template<> VkStructureType getStructureType<VkImageStencilUsageCreateInfoEXT> (void)
+template<> VkStructureType getStructureType<VkPhysicalDeviceToolPropertiesEXT> (void)
 {
-	return VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT;
+	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT;
 }
 
 template<> VkStructureType getStructureType<VkValidationFeaturesEXT> (void)
@@ -1756,11 +1786,6 @@
 	return VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
 }
 
-template<> VkStructureType getStructureType<VkPhysicalDeviceHostQueryResetFeaturesEXT> (void)
-{
-	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
-}
-
 template<> VkStructureType getStructureType<VkPhysicalDeviceIndexTypeUint8FeaturesEXT> (void)
 {
 	return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT;
diff --git a/external/vulkancts/framework/vulkan/vkImageUtil.cpp b/external/vulkancts/framework/vulkan/vkImageUtil.cpp
index 4de1cdd..38f2a5c 100644
--- a/external/vulkancts/framework/vulkan/vkImageUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkImageUtil.cpp
@@ -307,11 +307,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	4,		2,		1	},
-				{	0,		0,		0	},
-				{	0,		0,		0	},
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	4,		1,		1,		VK_FORMAT_G8B8G8R8_422_UNORM_KHR	},
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED	},
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED	},
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -325,11 +326,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	4,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	4,		1,		1,		VK_FORMAT_B8G8R8G8_422_UNORM_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -343,11 +345,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{  1, 1, 1 },
-				{  1, 2, 2 },
-				{  1, 2, 2 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	1,		2,		2,		VK_FORMAT_R8_UNORM },
+				{	1,		2,		2,		VK_FORMAT_R8_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -361,11 +364,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{  1, 1, 1 },
-				{  2, 2, 2 },
-				{  0, 0, 0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	2,		2,		2,		VK_FORMAT_R8G8_UNORM },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -379,11 +383,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{  1, 1, 1 },
-				{  1, 2, 1 },
-				{  1, 2, 1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	1,		2,		1,		VK_FORMAT_R8_UNORM },
+				{	1,		2,		1,		VK_FORMAT_R8_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -397,11 +402,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{  1, 1, 1 },
-				{  2, 2, 1 },
-				{  0, 0, 0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	2,		2,		1,		VK_FORMAT_R8G8_UNORM },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -415,11 +421,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{  1, 1, 1 },
-				{  1, 1, 1 },
-				{  1, 1, 1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -433,11 +440,12 @@
 		{
 			1, // planes
 			chanR,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -451,11 +459,12 @@
 		{
 			1, // planes
 			chanR|chanG,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	4,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	4,		1,		1,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -469,11 +478,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB|chanA,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -487,11 +497,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -505,11 +516,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -523,11 +535,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		2 },
-				{	2,		2,		2 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		2,		2,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		2,		2,		VK_FORMAT_R10X6_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -541,11 +554,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		2 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	4,		2,		2,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -559,11 +573,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		1 },
-				{	2,		2,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		2,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		2,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -577,11 +592,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		1 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	4,		2,		1,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -595,11 +611,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		1,		1 },
-				{	2,		1,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
+				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -613,11 +630,12 @@
 		{
 			1, // planes
 			chanR,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -631,11 +649,12 @@
 		{
 			1, // planes
 			chanR|chanG,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	4,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	4,		1,		1,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -649,11 +668,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB|chanA,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		1,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -667,11 +687,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -685,11 +706,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -703,11 +725,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		2 },
-				{	2,		2,		2 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		2,		2,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		2,		2,		VK_FORMAT_R12X4_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -721,11 +744,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		2 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	4,		2,		2,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -739,11 +763,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		1 },
-				{	2,		2,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		2,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		2,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -757,11 +782,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		1 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	4,		2,		1,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -775,11 +801,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		1,		1 },
-				{	2,		1,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
+				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -793,11 +820,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_G16B16G16R16_422_UNORM_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -811,11 +839,12 @@
 		{
 			1, // planes
 			chanR|chanG|chanB,
+			2,1,
 			{
-			//		Size	WDiv	HDiv
-				{	8,		2,		1 },
-				{	0,		0,		0 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	8,		1,		1,		VK_FORMAT_B16G16R16G16_422_UNORM_KHR },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -829,11 +858,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		2 },
-				{	2,		2,		2 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	2,		2,		2,		VK_FORMAT_R16_UNORM },
+				{	2,		2,		2,		VK_FORMAT_R16_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -847,11 +877,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		2 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	4,		2,		2,		VK_FORMAT_R16G16_UNORM },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -865,11 +896,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		2,		1 },
-				{	2,		2,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	2,		2,		1,		VK_FORMAT_R16_UNORM },
+				{	2,		2,		1,		VK_FORMAT_R16_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -883,11 +915,12 @@
 		{
 			2, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	4,		2,		1 },
-				{	0,		0,		0 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	4,		2,		1,		VK_FORMAT_R16G16_UNORM },
+				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -901,11 +934,12 @@
 		{
 			3, // planes
 			chanR|chanG|chanB,
+			1,1,
 			{
-			//		Size	WDiv	HDiv
-				{	2,		1,		1 },
-				{	2,		1,		1 },
-				{	2,		1,		1 },
+			//		Size	WDiv	HDiv	planeCompatibleFormat
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
 			},
 			{
 			//		Plane	Type	Offs	Size	Stride
@@ -926,7 +960,9 @@
 
 PlanarFormatDescription getCorePlanarFormatDescription (VkFormat format)
 {
+	const deUint8			snorm	= (deUint8)tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
 	const deUint8			unorm	= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
+	const deUint8			sint	= (deUint8)tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
 	const deUint8			uint	= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
 	const deUint8			sfloat	= (deUint8)tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
 
@@ -949,11 +985,12 @@
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	1,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_R8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -966,17 +1003,43 @@
 			return desc;
 		}
 
+		case VK_FORMAT_R8_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_R8_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		8,		1 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+
 		case VK_FORMAT_R8G8_UNORM:
 		{
 			const PlanarFormatDescription	desc	=
 			{
 				1, // planes
 				chanR|chanG,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R8G8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -989,17 +1052,42 @@
 			return desc;
 		}
 
+		case VK_FORMAT_R8G8_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R8G8_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		8,		2 },	// R
+					{	0,		snorm,	8,		8,		2 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
 		case VK_FORMAT_R16_UNORM:
 		{
 			const PlanarFormatDescription	desc	=
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R16_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1012,17 +1100,42 @@
 			return desc;
 		}
 
+		case VK_FORMAT_R16_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R16_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		16,		2 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
 		case VK_FORMAT_R16G16_UNORM:
 		{
 			const PlanarFormatDescription	desc	=
 			{
 				1, // planes
 				chanR|chanG,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R16G16_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1035,17 +1148,42 @@
 			return desc;
 		}
 
+		case VK_FORMAT_R16G16_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R16G16_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		16,		4 },	// R
+					{	0,		snorm,	16,		16,		4 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
 		{
 			const PlanarFormatDescription	desc	=
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_B10G11R11_UFLOAT_PACK32 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1064,11 +1202,12 @@
 			{
 				1, // planes
 				chanR|chanG,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	1,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_R4G4_UNORM_PACK8 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1087,11 +1226,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R4G4B4A4_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1110,11 +1250,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_B4G4R4A4_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1133,11 +1274,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R5G6B5_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1156,11 +1298,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_B5G6R5_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1179,11 +1322,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R5G5B5A1_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1202,11 +1346,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_B5G5R5A1_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1225,11 +1370,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_A1R5G5B5_UNORM_PACK16 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1248,11 +1394,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	3,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	3,		1,		1,		VK_FORMAT_R8G8B8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1271,11 +1418,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	3,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	3,		1,		1,		VK_FORMAT_B8G8R8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1295,11 +1443,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1318,11 +1467,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_B8G8R8A8_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1341,11 +1491,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1364,11 +1515,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1387,11 +1539,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	6,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	6,		1,		1,		VK_FORMAT_R16G16B16_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1410,11 +1563,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	8,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1427,21 +1581,265 @@
 			return desc;
 		}
 
+		case VK_FORMAT_R8_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_R8_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		8,		1 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R16_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		16,		2 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R32_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R32_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		32,		4 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R8G8_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R8G8_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		8,		2 },	// R
+					{	0,		sint,	8,		8,		2 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16G16_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R16G16_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		16,		4 },	// R
+					{	0,		sint,	16,		16,		4 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R32G32_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R32G32_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		32,		8 },	// R
+					{	0,		sint,	32,		32,		8 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R8G8B8A8_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		8,		4 },	// R
+					{	0,		sint,	8,		8,		4 },	// G
+					{	0,		sint,	16,		8,		4 },	// B
+					{	0,		sint,	24,		8,		4 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16G16B16A16_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		16,		8 },	// R
+					{	0,		sint,	16,		16,		8 },	// G
+					{	0,		sint,	32,		16,		8 },	// B
+					{	0,		sint,	48,		16,		8 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R32G32B32A32_SINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_SINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		sint,	0,		32,		16 },	// R
+					{	0,		sint,	32,		32,		16 },	// G
+					{	0,		sint,	64,		32,		16 },	// B
+					{	0,		sint,	96,		32,		16 }	// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R8_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_R8_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		8,		1 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
 		case VK_FORMAT_R16_UINT:
 		{
 			const PlanarFormatDescription	desc	=
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R16_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
-					{	0,		uint,	0,		2,		2 },	// R
+					{	0,		uint,	0,		16,		2 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
 				}
 			};
 			return desc;
@@ -1453,20 +1851,215 @@
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R32_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
-					{	0,		uint,	0,		4,		4 },	// R
+					{	0,		uint,	0,		32,		4 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
 				}
 			};
 			return desc;
 		}
 
+		case VK_FORMAT_R8G8_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_R8G8_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		8,		2 },	// R
+					{	0,		uint,	8,		8,		2 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16G16_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R16G16_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		16,		4 },	// R
+					{	0,		uint,	16,		16,		4 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R32G32_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R32G32_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		32,		8 },	// R
+					{	0,		uint,	32,		32,		8 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R8G8B8A8_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		8,		4 },	// R
+					{	0,		uint,	8,		8,		4 },	// G
+					{	0,		uint,	16,		8,		4 },	// B
+					{	0,		uint,	24,		8,		4 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16G16B16A16_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		16,		8 },	// R
+					{	0,		uint,	16,		16,		8 },	// G
+					{	0,		uint,	32,		16,		8 },	// B
+					{	0,		uint,	48,		16,		8 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R32G32B32A32_UINT:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		uint,	0,		32,		16 },	// R
+					{	0,		uint,	32,		32,		16 },	// G
+					{	0,		uint,	64,		32,		16 },	// B
+					{	0,		uint,	96,		32,		16 }	// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R8G8B8A8_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		8,		4 },	// R
+					{	0,		snorm,	8,		8,		4 },	// G
+					{	0,		snorm,	16,		8,		4 },	// B
+					{	0,		snorm,	24,		8,		4 }		// A
+				}
+			};
+			return desc;
+		}
+
+		case VK_FORMAT_R16G16B16A16_SNORM:
+		{
+			const PlanarFormatDescription	desc	=
+			{
+				1, // planes
+				chanR | chanG | chanB | chanA,
+				1,1,
+				{
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_SNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+				},
+				{
+				//		Plane	Type	Offs	Size	Stride
+					{	0,		snorm,	0,		16,		8 },	// R
+					{	0,		snorm,	16,		16,		8 },	// G
+					{	0,		snorm,	32,		16,		8 },	// B
+					{	0,		snorm,	48,		16,		8 }		// A
+				}
+			};
+			return desc;
+		}
 		case VK_FORMAT_R32_SFLOAT:
 		case VK_FORMAT_D32_SFLOAT:
 		{
@@ -1474,15 +2067,19 @@
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	4,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	4,		1,		1,		VK_FORMAT_R32_SFLOAT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
 					{	0,		sfloat,	0,		32,		4 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
 				}
 			};
 			return desc;
@@ -1494,15 +2091,19 @@
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	2,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	2,		1,		1,		VK_FORMAT_D16_UNORM },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
 					{	0,		unorm,	0,		16,		2 },	// R
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
 				}
 			};
 			return desc;
@@ -1514,61 +2115,19 @@
 			{
 				1, // planes
 				chanR,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	1,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	1,		1,		1,		VK_FORMAT_S8_UINT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED},
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
 					{	0,		uint,	0,		8,		1 },	// R
-				}
-			};
-			return desc;
-		}
-
-		case VK_FORMAT_R16G16B16A16_UINT:
-		{
-			const PlanarFormatDescription	desc	=
-			{
-				1, // planes
-				chanR|chanG|chanB|chanA,
-				{
-				//		Size	WDiv	HDiv
-					{	8,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
-				},
-				{
-				//		Plane	Type	Offs	Size	Stride
-					{	0,		uint,	0,		16,		8 },	// R
-					{	0,		uint,	16,		16,		8 },	// G
-					{	0,		uint,	32,		16,		8 },	// B
-					{	0,		uint,	48,		16,		8 },	// A
-				}
-			};
-			return desc;
-		}
-
-		case VK_FORMAT_R32G32B32A32_UINT:
-		{
-			const PlanarFormatDescription	desc	=
-			{
-				1, // planes
-				chanR|chanG|chanB|chanA,
-				{
-				//		Size	WDiv	HDiv
-					{	16,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
-				},
-				{
-				//		Plane	Type	Offs	Size	Stride
-					{	0,		uint,	0,		32,		16 },	// R
-					{	0,		uint,	32,		32,		16 },	// G
-					{	0,		uint,	64,		32,		16 },	// B
-					{	0,		uint,	96,		32,		16 },	// A
+					{	0,		0,		0,		0,		0 },	// G
+					{	0,		0,		0,		0,		0 },	// B
+					{	0,		0,		0,		0,		0 }		// A
 				}
 			};
 			return desc;
@@ -1580,11 +2139,12 @@
 			{
 				1, // planes
 				chanR|chanG|chanB|chanA,
+				1,1,
 				{
-				//		Size	WDiv	HDiv
-					{	16,		1,		1 },
-					{	0,		0,		0 },
-					{	0,		0,		0 },
+				//		Size	WDiv	HDiv	planeCompatibleFormat
+					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_SFLOAT },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
+					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
 				},
 				{
 				//		Plane	Type	Offs	Size	Stride
@@ -1597,6 +2157,7 @@
 			return desc;
 		}
 
+
 		default:
 			TCU_THROW(InternalError, "Not implemented");
 	}
@@ -1660,6 +2221,109 @@
 	}
 }
 
+deUint32 getMipmapCount(VkFormat format, const vk::PlanarFormatDescription& formatDescription, const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
+{
+	if (isYCbCrFormat(format))
+		return 1;
+	tcu::UVec3 imageAlignment	= getImageSizeAlignment(formatDescription);
+	deUint32 mipmapEdge			= std::max(std::max(extent.width, extent.height), extent.depth);
+	if (imageAlignment.x() > 1)
+		mipmapEdge = std::min(mipmapEdge, extent.width / imageAlignment.x());
+	if (imageAlignment.y() > 1)
+		mipmapEdge = std::min(mipmapEdge, extent.height / imageAlignment.y());
+	if (imageAlignment.z() > 1)
+		mipmapEdge = std::min(mipmapEdge, extent.depth / imageAlignment.z());
+	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(mipmapEdge))) + 1u, imageFormatProperties.maxMipLevels);
+}
+
+deUint32 getPlaneSizeInBytes (const PlanarFormatDescription&	formatInfo,
+							  const VkExtent3D&					baseExtents,
+							  const deUint32					planeNdx,
+							  const deUint32					mipmapLevel,
+							  const deUint32					mipmapMemoryAlignment)
+{
+	VkExtent3D imageExtent	= getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel);
+	imageExtent.width		/= formatInfo.blockWidth;
+	imageExtent.height		/= formatInfo.blockHeight;
+	return deAlign32( formatInfo.planes[planeNdx].elementSizeBytes * imageExtent.width * imageExtent.height * imageExtent.depth, mipmapMemoryAlignment);
+}
+
+deUint32 getPlaneSizeInBytes (const PlanarFormatDescription&	formatInfo,
+							  const tcu::UVec2&					baseExtents,
+							  const deUint32					planeNdx,
+							  const deUint32					mipmapLevel,
+							  const deUint32					mipmapMemoryAlignment)
+{
+	tcu::UVec2 mipExtents = getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel) / tcu::UVec2(formatInfo.blockWidth, formatInfo.blockHeight);
+	return deAlign32( formatInfo.planes[planeNdx].elementSizeBytes * mipExtents.x() * mipExtents.y(), mipmapMemoryAlignment);
+}
+
+VkExtent3D getPlaneExtent(const PlanarFormatDescription&	formatInfo,
+						  const VkExtent3D&					baseExtents,
+						  const deUint32					planeNdx,
+						  const deUint32					mipmapLevel)
+{
+	deUint32	widthDivisor	= formatInfo.planes[planeNdx].widthDivisor;
+	deUint32	heightDivisor	= formatInfo.planes[planeNdx].heightDivisor;
+	deUint32	depthDivisor	= 1u;
+	VkExtent3D	mip0Extents		{ baseExtents.width / widthDivisor, baseExtents.height / heightDivisor, baseExtents.depth / depthDivisor };
+
+	return mipLevelExtents(mip0Extents, mipmapLevel);
+}
+
+tcu::UVec2 getPlaneExtent(const PlanarFormatDescription&	formatInfo,
+						  const tcu::UVec2&					baseExtents,
+						  const deUint32					planeNdx,
+						  const deUint32					mipmapLevel)
+{
+	deUint32 widthDivisor			= formatInfo.planes[planeNdx].widthDivisor;
+	deUint32 heightDivisor			= formatInfo.planes[planeNdx].heightDivisor;
+	tcu::UVec2 mip0Extents			{ baseExtents.x() / widthDivisor, baseExtents.y() / heightDivisor };
+
+	return tcu::UVec2
+	{
+		std::max(mip0Extents.x() >> mipmapLevel, 1u),
+		std::max(mip0Extents.y() >> mipmapLevel, 1u)
+	};
+}
+
+tcu::UVec3 getImageSizeAlignment(VkFormat format)
+{
+	return getImageSizeAlignment(getPlanarFormatDescription(format));
+}
+
+tcu::UVec3 getImageSizeAlignment(const PlanarFormatDescription&	formatInfo)
+{
+	tcu::UVec3 imgAlignment{ formatInfo.blockWidth, formatInfo.blockHeight, 1 };
+	for (deUint32 planeNdx = 0; planeNdx < formatInfo.numPlanes; ++planeNdx)
+	{
+		imgAlignment.x() = std::max(imgAlignment.x(), static_cast<deUint32>(formatInfo.planes[planeNdx].widthDivisor));
+		imgAlignment.y() = std::max(imgAlignment.y(), static_cast<deUint32>(formatInfo.planes[planeNdx].heightDivisor));
+	}
+	return imgAlignment;
+}
+
+tcu::UVec2 getBlockExtent(VkFormat format)
+{
+	return getBlockExtent(getPlanarFormatDescription(format));
+}
+
+tcu::UVec2 getBlockExtent(const PlanarFormatDescription& formatInfo)
+{
+	return tcu::UVec2{ formatInfo.blockWidth, formatInfo.blockHeight };
+}
+
+VkFormat getPlaneCompatibleFormat(VkFormat format, deUint32 planeNdx)
+{
+	return getPlaneCompatibleFormat(getPlanarFormatDescription(format), planeNdx);
+}
+
+VkFormat getPlaneCompatibleFormat(const PlanarFormatDescription& formatInfo, deUint32 planeNdx)
+{
+	DE_ASSERT(planeNdx < formatInfo.numPlanes);
+	return formatInfo.planes[planeNdx].planeCompatibleFormat;
+}
+
 VkImageAspectFlagBits getPlaneAspect (deUint32 planeNdx)
 {
 	DE_ASSERT(de::inBounds(planeNdx, 0u, 3u));
@@ -2428,30 +3092,29 @@
 	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits % 8;
 	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
 
-	DE_ASSERT(size.x() % formatInfo.planes[planeNdx].widthDivisor == 0);
-	DE_ASSERT(size.y() % formatInfo.planes[planeNdx].heightDivisor == 0);
+	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
+	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
 
-	deUint32		accessWidth			= size.x() / formatInfo.planes[planeNdx].widthDivisor;
-	const deUint32	accessHeight		= size.y() / formatInfo.planes[planeNdx].heightDivisor;
+	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
 	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
-
 	const deUint32	rowPitch			= planeRowPitches[planeNdx];
 
-	if (pixelStrideBytes != elementSizeBytes)
-	{
-		DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
-		accessWidth *= elementSizeBytes/pixelStrideBytes;
-	}
+	DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
+
+	tcu::IVec3		texDivider(
+		std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes, 1u),
+		std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes / elementSizeBytes, 1u),
+		1);
 
 	return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
 														 valueOffsetBits,
 														 formatInfo.channels[channelNdx].sizeBits),
-								  tcu::IVec3((int)accessWidth, (int)accessHeight, 1),
-								  tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, 0),
-								  (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
+														 tcu::IVec3((int)size.x(), (int)size.y(), 1),
+														 tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight*rowPitch)),
+														 texDivider,
+														 (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
 }
 
-
 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
 											  const tcu::UVec2&					size,
 											  const deUint32*					planeRowPitches,
@@ -2461,6 +3124,51 @@
 	return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void* const*>(planePtrs), channelNdx);
 }
 
+tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
+										 const tcu::UVec3&				size,
+										 const deUint32*				planeRowPitches,
+										 void* const*					planePtrs,
+										 deUint32						channelNdx)
+{
+	DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
+
+	const deUint32	planeNdx			= formatInfo.channels[channelNdx].planeNdx;
+	const deUint32	planeOffsetBytes	= formatInfo.channels[channelNdx].offsetBits / 8;
+	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits % 8;
+	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
+
+	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
+	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
+
+	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
+	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
+	const deUint32	rowPitch			= planeRowPitches[planeNdx];
+
+	DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
+
+	tcu::IVec3		texDivider(
+		std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes, 1u),
+		std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes / elementSizeBytes, 1u),
+		1);
+
+	return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
+														 valueOffsetBits,
+														 formatInfo.channels[channelNdx].sizeBits),
+														 tcu::IVec3((int)size.x(), (int)size.y(), (int)size.z()),
+														 tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight*rowPitch)),
+														 texDivider,
+														 (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
+}
+
+tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
+											  const tcu::UVec3&					size,
+											  const deUint32*					planeRowPitches,
+											  const void* const*				planePtrs,
+											  deUint32							channelNdx)
+{
+	return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void* const*>(planePtrs), channelNdx);
+}
+
 void imageUtilSelfTest (void)
 {
 	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; formatNdx++)
@@ -2832,9 +3540,9 @@
 		{
 			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT:
 			{
-				const VkSamplerReductionModeCreateInfoEXT reductionModeCreateInfo = *reinterpret_cast<const VkSamplerReductionModeCreateInfoEXT*>(pNext);
+				const VkSamplerReductionModeCreateInfo reductionModeCreateInfo = *reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext);
 				reductionMode = mapVkSamplerReductionMode(reductionModeCreateInfo.reductionMode);
-				pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfoEXT*>(pNext)->pNext;
+				pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext)->pNext;
 				break;
 			}
 			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
@@ -2931,13 +3639,13 @@
 	return tcu::Sampler::WRAPMODE_LAST;
 }
 
-tcu::Sampler::ReductionMode mapVkSamplerReductionMode (VkSamplerReductionModeEXT reductionMode)
+tcu::Sampler::ReductionMode mapVkSamplerReductionMode (VkSamplerReductionMode reductionMode)
 {
 	switch (reductionMode)
 	{
-		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT:	return tcu::Sampler::WEIGHTED_AVERAGE;
-		case VK_SAMPLER_REDUCTION_MODE_MIN_EXT:					return tcu::Sampler::MIN;
-		case VK_SAMPLER_REDUCTION_MODE_MAX_EXT:					return tcu::Sampler::MAX;
+		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE:	return tcu::Sampler::WEIGHTED_AVERAGE;
+		case VK_SAMPLER_REDUCTION_MODE_MIN:					return tcu::Sampler::MIN;
+		case VK_SAMPLER_REDUCTION_MODE_MAX:					return tcu::Sampler::MAX;
 		default:
 			break;
 	}
diff --git a/external/vulkancts/framework/vulkan/vkImageUtil.hpp b/external/vulkancts/framework/vulkan/vkImageUtil.hpp
index 8b1222d..509c7c3 100644
--- a/external/vulkancts/framework/vulkan/vkImageUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkImageUtil.hpp
@@ -56,7 +56,7 @@
 tcu::Sampler				mapVkSampler				(const VkSamplerCreateInfo& samplerCreateInfo);
 tcu::Sampler::CompareMode	mapVkSamplerCompareOp		(VkCompareOp compareOp);
 tcu::Sampler::WrapMode		mapVkSamplerAddressMode		(VkSamplerAddressMode addressMode);
-tcu::Sampler::ReductionMode mapVkSamplerReductionMode	(VkSamplerReductionModeEXT reductionMode);
+tcu::Sampler::ReductionMode mapVkSamplerReductionMode	(VkSamplerReductionMode reductionMode);
 tcu::Sampler::FilterMode	mapVkMinTexFilter			(VkFilter filter, VkSamplerMipmapMode mipMode);
 tcu::Sampler::FilterMode	mapVkMagTexFilter			(VkFilter filter);
 
@@ -77,6 +77,8 @@
 deUint32					getBlockWidth				(const VkFormat compressedFormat);
 deUint32					getBlockHeight				(const VkFormat compressedFormat);
 
+const deUint32 BUFFER_IMAGE_COPY_OFFSET_GRANULARITY = 4u;
+
 // \todo [2017-05-18 pyry] Consider moving this to tcu
 struct PlanarFormatDescription
 {
@@ -99,6 +101,7 @@
 		deUint8		elementSizeBytes;
 		deUint8		widthDivisor;
 		deUint8		heightDivisor;
+		VkFormat	planeCompatibleFormat;
 	};
 
 	struct Channel
@@ -112,6 +115,8 @@
 
 	deUint8		numPlanes;
 	deUint8		presentChannels;
+	deUint8		blockWidth;
+	deUint8		blockHeight;
 	Plane		planes[MAX_PLANES];
 	Channel		channels[MAX_CHANNELS];
 
@@ -122,15 +127,46 @@
 	}
 };
 
-bool							isYCbCrFormat					(VkFormat format);
-PlanarFormatDescription			getPlanarFormatDescription		(VkFormat format);
-const PlanarFormatDescription&	getYCbCrPlanarFormatDescription	(VkFormat format);
-int								getPlaneCount					(VkFormat format);
-VkImageAspectFlagBits			getPlaneAspect					(deUint32 planeNdx);
-deUint32						getAspectPlaneNdx				(VkImageAspectFlagBits planeAspect);
-bool							isChromaSubsampled				(VkFormat format);
-bool							isYCbCr422Format				(VkFormat format);
-bool							isYCbCr420Format				(VkFormat format);
+bool							isYCbCrFormat					(VkFormat						format);
+PlanarFormatDescription			getPlanarFormatDescription		(VkFormat						format);
+int								getPlaneCount					(VkFormat						format);
+deUint32						getMipmapCount					(VkFormat						format,
+																 const vk::PlanarFormatDescription&	formatDescription,
+																 const vk::VkImageFormatProperties& imageFormatProperties,
+																 const vk::VkExtent3D&				extent);
+
+deUint32						getPlaneSizeInBytes				(const PlanarFormatDescription&	formatInfo,
+																 const VkExtent3D&				baseExtents,
+																 const deUint32					planeNdx,
+																 const deUint32					mipmapLevel,
+																 const deUint32					mipmapMemoryAlignment);
+deUint32						getPlaneSizeInBytes				(const PlanarFormatDescription&	formatInfo,
+																 const tcu::UVec2&				baseExtents,
+																 const deUint32					planeNdx,
+																 const deUint32					mipmapLevel,
+																 const deUint32					mipmapMemoryAlignment);
+VkExtent3D						getPlaneExtent					(const PlanarFormatDescription&	formatInfo,
+																 const VkExtent3D&				baseExtents,
+																 const deUint32					planeNdx,
+																 const deUint32					mipmapLevel);
+tcu::UVec2						getPlaneExtent					(const PlanarFormatDescription&	formatInfo,
+																 const tcu::UVec2&				baseExtents,
+																 const deUint32					planeNdx,
+																 const deUint32					mipmapLevel);
+tcu::UVec3						getImageSizeAlignment			(VkFormat						format);
+tcu::UVec3						getImageSizeAlignment			(const PlanarFormatDescription&	formatInfo);
+tcu::UVec2						getBlockExtent					(VkFormat						format);
+tcu::UVec2						getBlockExtent					(const PlanarFormatDescription&	formatInfo);
+VkFormat						getPlaneCompatibleFormat		(VkFormat						format,
+																 deUint32						planeNdx);
+VkFormat						getPlaneCompatibleFormat		(const PlanarFormatDescription&	formatInfo,
+																 deUint32						planeNdx);
+
+VkImageAspectFlagBits			getPlaneAspect					(deUint32						planeNdx);
+deUint32						getAspectPlaneNdx				(VkImageAspectFlagBits			planeAspect);
+bool							isChromaSubsampled				(VkFormat						format);
+bool							isYCbCr422Format				(VkFormat						format);
+bool							isYCbCr420Format				(VkFormat						format);
 
 tcu::PixelBufferAccess			getChannelAccess				(const PlanarFormatDescription&	formatInfo,
 																 const tcu::UVec2&				size,
@@ -142,6 +178,16 @@
 																 const deUint32*				planeRowPitches,
 																 const void* const*				planePtrs,
 																 deUint32						channelNdx);
+tcu::PixelBufferAccess			getChannelAccess				(const PlanarFormatDescription&	formatInfo,
+																 const tcu::UVec3&				size,
+																 const deUint32*				planeRowPitches,
+																 void* const*					planePtrs,
+																 deUint32						channelNdx);
+tcu::ConstPixelBufferAccess		getChannelAccess				(const PlanarFormatDescription&	formatInfo,
+																 const tcu::UVec3&				size,
+																 const deUint32*				planeRowPitches,
+																 const void* const*				planePtrs,
+																 deUint32						channelNdx);
 VkImageAspectFlags				getImageAspectFlags				(const tcu::TextureFormat		textureFormat);
 VkExtent3D						mipLevelExtents					(const VkExtent3D&				baseExtents,
 																 const deUint32					mipLevel);
diff --git a/external/vulkancts/framework/vulkan/vkInitDeviceFunctionPointers.inl b/external/vulkancts/framework/vulkan/vkInitDeviceFunctionPointers.inl
index ea0b549..cf1c172 100644
--- a/external/vulkancts/framework/vulkan/vkInitDeviceFunctionPointers.inl
+++ b/external/vulkancts/framework/vulkan/vkInitDeviceFunctionPointers.inl
@@ -168,6 +168,45 @@
 m_vk.getDescriptorSetLayoutSupport						= (GetDescriptorSetLayoutSupportFunc)					GET_PROC_ADDR("vkGetDescriptorSetLayoutSupport");
 if (!m_vk.getDescriptorSetLayoutSupport)
 	m_vk.getDescriptorSetLayoutSupport					= (GetDescriptorSetLayoutSupportFunc)					GET_PROC_ADDR("vkGetDescriptorSetLayoutSupportKHR");
+m_vk.cmdDrawIndirectCount								= (CmdDrawIndirectCountFunc)							GET_PROC_ADDR("vkCmdDrawIndirectCount");
+if (!m_vk.cmdDrawIndirectCount)
+	m_vk.cmdDrawIndirectCount							= (CmdDrawIndirectCountFunc)							GET_PROC_ADDR("vkCmdDrawIndirectCountKHR");
+m_vk.cmdDrawIndexedIndirectCount						= (CmdDrawIndexedIndirectCountFunc)						GET_PROC_ADDR("vkCmdDrawIndexedIndirectCount");
+if (!m_vk.cmdDrawIndexedIndirectCount)
+	m_vk.cmdDrawIndexedIndirectCount					= (CmdDrawIndexedIndirectCountFunc)						GET_PROC_ADDR("vkCmdDrawIndexedIndirectCountKHR");
+m_vk.createRenderPass2									= (CreateRenderPass2Func)								GET_PROC_ADDR("vkCreateRenderPass2");
+if (!m_vk.createRenderPass2)
+	m_vk.createRenderPass2								= (CreateRenderPass2Func)								GET_PROC_ADDR("vkCreateRenderPass2KHR");
+m_vk.cmdBeginRenderPass2								= (CmdBeginRenderPass2Func)								GET_PROC_ADDR("vkCmdBeginRenderPass2");
+if (!m_vk.cmdBeginRenderPass2)
+	m_vk.cmdBeginRenderPass2							= (CmdBeginRenderPass2Func)								GET_PROC_ADDR("vkCmdBeginRenderPass2KHR");
+m_vk.cmdNextSubpass2									= (CmdNextSubpass2Func)									GET_PROC_ADDR("vkCmdNextSubpass2");
+if (!m_vk.cmdNextSubpass2)
+	m_vk.cmdNextSubpass2								= (CmdNextSubpass2Func)									GET_PROC_ADDR("vkCmdNextSubpass2KHR");
+m_vk.cmdEndRenderPass2									= (CmdEndRenderPass2Func)								GET_PROC_ADDR("vkCmdEndRenderPass2");
+if (!m_vk.cmdEndRenderPass2)
+	m_vk.cmdEndRenderPass2								= (CmdEndRenderPass2Func)								GET_PROC_ADDR("vkCmdEndRenderPass2KHR");
+m_vk.resetQueryPool										= (ResetQueryPoolFunc)									GET_PROC_ADDR("vkResetQueryPool");
+if (!m_vk.resetQueryPool)
+	m_vk.resetQueryPool									= (ResetQueryPoolFunc)									GET_PROC_ADDR("vkResetQueryPoolEXT");
+m_vk.getSemaphoreCounterValue							= (GetSemaphoreCounterValueFunc)						GET_PROC_ADDR("vkGetSemaphoreCounterValue");
+if (!m_vk.getSemaphoreCounterValue)
+	m_vk.getSemaphoreCounterValue						= (GetSemaphoreCounterValueFunc)						GET_PROC_ADDR("vkGetSemaphoreCounterValueKHR");
+m_vk.waitSemaphores										= (WaitSemaphoresFunc)									GET_PROC_ADDR("vkWaitSemaphores");
+if (!m_vk.waitSemaphores)
+	m_vk.waitSemaphores									= (WaitSemaphoresFunc)									GET_PROC_ADDR("vkWaitSemaphoresKHR");
+m_vk.signalSemaphore									= (SignalSemaphoreFunc)									GET_PROC_ADDR("vkSignalSemaphore");
+if (!m_vk.signalSemaphore)
+	m_vk.signalSemaphore								= (SignalSemaphoreFunc)									GET_PROC_ADDR("vkSignalSemaphoreKHR");
+m_vk.getBufferDeviceAddress								= (GetBufferDeviceAddressFunc)							GET_PROC_ADDR("vkGetBufferDeviceAddress");
+if (!m_vk.getBufferDeviceAddress)
+	m_vk.getBufferDeviceAddress							= (GetBufferDeviceAddressFunc)							GET_PROC_ADDR("vkGetBufferDeviceAddressKHR");
+m_vk.getBufferOpaqueCaptureAddress						= (GetBufferOpaqueCaptureAddressFunc)					GET_PROC_ADDR("vkGetBufferOpaqueCaptureAddress");
+if (!m_vk.getBufferOpaqueCaptureAddress)
+	m_vk.getBufferOpaqueCaptureAddress					= (GetBufferOpaqueCaptureAddressFunc)					GET_PROC_ADDR("vkGetBufferOpaqueCaptureAddressKHR");
+m_vk.getDeviceMemoryOpaqueCaptureAddress				= (GetDeviceMemoryOpaqueCaptureAddressFunc)				GET_PROC_ADDR("vkGetDeviceMemoryOpaqueCaptureAddress");
+if (!m_vk.getDeviceMemoryOpaqueCaptureAddress)
+	m_vk.getDeviceMemoryOpaqueCaptureAddress			= (GetDeviceMemoryOpaqueCaptureAddressFunc)				GET_PROC_ADDR("vkGetDeviceMemoryOpaqueCaptureAddressKHR");
 m_vk.createSwapchainKHR									= (CreateSwapchainKHRFunc)								GET_PROC_ADDR("vkCreateSwapchainKHR");
 m_vk.destroySwapchainKHR								= (DestroySwapchainKHRFunc)								GET_PROC_ADDR("vkDestroySwapchainKHR");
 m_vk.getSwapchainImagesKHR								= (GetSwapchainImagesKHRFunc)							GET_PROC_ADDR("vkGetSwapchainImagesKHR");
@@ -183,23 +222,11 @@
 m_vk.getSemaphoreFdKHR									= (GetSemaphoreFdKHRFunc)								GET_PROC_ADDR("vkGetSemaphoreFdKHR");
 m_vk.cmdPushDescriptorSetKHR							= (CmdPushDescriptorSetKHRFunc)							GET_PROC_ADDR("vkCmdPushDescriptorSetKHR");
 m_vk.cmdPushDescriptorSetWithTemplateKHR				= (CmdPushDescriptorSetWithTemplateKHRFunc)				GET_PROC_ADDR("vkCmdPushDescriptorSetWithTemplateKHR");
-m_vk.createRenderPass2KHR								= (CreateRenderPass2KHRFunc)							GET_PROC_ADDR("vkCreateRenderPass2KHR");
-m_vk.cmdBeginRenderPass2KHR								= (CmdBeginRenderPass2KHRFunc)							GET_PROC_ADDR("vkCmdBeginRenderPass2KHR");
-m_vk.cmdNextSubpass2KHR									= (CmdNextSubpass2KHRFunc)								GET_PROC_ADDR("vkCmdNextSubpass2KHR");
-m_vk.cmdEndRenderPass2KHR								= (CmdEndRenderPass2KHRFunc)							GET_PROC_ADDR("vkCmdEndRenderPass2KHR");
 m_vk.getSwapchainStatusKHR								= (GetSwapchainStatusKHRFunc)							GET_PROC_ADDR("vkGetSwapchainStatusKHR");
 m_vk.importFenceFdKHR									= (ImportFenceFdKHRFunc)								GET_PROC_ADDR("vkImportFenceFdKHR");
 m_vk.getFenceFdKHR										= (GetFenceFdKHRFunc)									GET_PROC_ADDR("vkGetFenceFdKHR");
 m_vk.acquireProfilingLockKHR							= (AcquireProfilingLockKHRFunc)							GET_PROC_ADDR("vkAcquireProfilingLockKHR");
 m_vk.releaseProfilingLockKHR							= (ReleaseProfilingLockKHRFunc)							GET_PROC_ADDR("vkReleaseProfilingLockKHR");
-m_vk.cmdDrawIndirectCountKHR							= (CmdDrawIndirectCountKHRFunc)							GET_PROC_ADDR("vkCmdDrawIndirectCountKHR");
-m_vk.cmdDrawIndexedIndirectCountKHR						= (CmdDrawIndexedIndirectCountKHRFunc)					GET_PROC_ADDR("vkCmdDrawIndexedIndirectCountKHR");
-m_vk.getSemaphoreCounterValueKHR						= (GetSemaphoreCounterValueKHRFunc)						GET_PROC_ADDR("vkGetSemaphoreCounterValueKHR");
-m_vk.waitSemaphoresKHR									= (WaitSemaphoresKHRFunc)								GET_PROC_ADDR("vkWaitSemaphoresKHR");
-m_vk.signalSemaphoreKHR									= (SignalSemaphoreKHRFunc)								GET_PROC_ADDR("vkSignalSemaphoreKHR");
-m_vk.getBufferDeviceAddressKHR							= (GetBufferDeviceAddressKHRFunc)						GET_PROC_ADDR("vkGetBufferDeviceAddressKHR");
-m_vk.getBufferOpaqueCaptureAddressKHR					= (GetBufferOpaqueCaptureAddressKHRFunc)				GET_PROC_ADDR("vkGetBufferOpaqueCaptureAddressKHR");
-m_vk.getDeviceMemoryOpaqueCaptureAddressKHR				= (GetDeviceMemoryOpaqueCaptureAddressKHRFunc)			GET_PROC_ADDR("vkGetDeviceMemoryOpaqueCaptureAddressKHR");
 m_vk.getPipelineExecutablePropertiesKHR					= (GetPipelineExecutablePropertiesKHRFunc)				GET_PROC_ADDR("vkGetPipelineExecutablePropertiesKHR");
 m_vk.getPipelineExecutableStatisticsKHR					= (GetPipelineExecutableStatisticsKHRFunc)				GET_PROC_ADDR("vkGetPipelineExecutableStatisticsKHR");
 m_vk.getPipelineExecutableInternalRepresentationsKHR	= (GetPipelineExecutableInternalRepresentationsKHRFunc)	GET_PROC_ADDR("vkGetPipelineExecutableInternalRepresentationsKHR");
@@ -287,7 +314,6 @@
 m_vk.setLocalDimmingAMD									= (SetLocalDimmingAMDFunc)								GET_PROC_ADDR("vkSetLocalDimmingAMD");
 m_vk.getBufferDeviceAddressEXT							= (GetBufferDeviceAddressEXTFunc)						GET_PROC_ADDR("vkGetBufferDeviceAddressEXT");
 m_vk.cmdSetLineStippleEXT								= (CmdSetLineStippleEXTFunc)							GET_PROC_ADDR("vkCmdSetLineStippleEXT");
-m_vk.resetQueryPoolEXT									= (ResetQueryPoolEXTFunc)								GET_PROC_ADDR("vkResetQueryPoolEXT");
 m_vk.getAndroidHardwareBufferPropertiesANDROID			= (GetAndroidHardwareBufferPropertiesANDROIDFunc)		GET_PROC_ADDR("vkGetAndroidHardwareBufferPropertiesANDROID");
 m_vk.getMemoryAndroidHardwareBufferANDROID				= (GetMemoryAndroidHardwareBufferANDROIDFunc)			GET_PROC_ADDR("vkGetMemoryAndroidHardwareBufferANDROID");
 m_vk.getMemoryWin32HandleKHR							= (GetMemoryWin32HandleKHRFunc)							GET_PROC_ADDR("vkGetMemoryWin32HandleKHR");
diff --git a/external/vulkancts/framework/vulkan/vkInitInstanceFunctionPointers.inl b/external/vulkancts/framework/vulkan/vkInitInstanceFunctionPointers.inl
index 6923778..41b9e29 100644
--- a/external/vulkancts/framework/vulkan/vkInitInstanceFunctionPointers.inl
+++ b/external/vulkancts/framework/vulkan/vkInitInstanceFunctionPointers.inl
@@ -89,6 +89,7 @@
 m_vk.submitDebugUtilsMessageEXT											= (SubmitDebugUtilsMessageEXTFunc)										GET_PROC_ADDR("vkSubmitDebugUtilsMessageEXT");
 m_vk.getPhysicalDeviceMultisamplePropertiesEXT							= (GetPhysicalDeviceMultisamplePropertiesEXTFunc)						GET_PROC_ADDR("vkGetPhysicalDeviceMultisamplePropertiesEXT");
 m_vk.getPhysicalDeviceCalibrateableTimeDomainsEXT						= (GetPhysicalDeviceCalibrateableTimeDomainsEXTFunc)					GET_PROC_ADDR("vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
+m_vk.getPhysicalDeviceToolPropertiesEXT									= (GetPhysicalDeviceToolPropertiesEXTFunc)								GET_PROC_ADDR("vkGetPhysicalDeviceToolPropertiesEXT");
 m_vk.getPhysicalDeviceCooperativeMatrixPropertiesNV						= (GetPhysicalDeviceCooperativeMatrixPropertiesNVFunc)					GET_PROC_ADDR("vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
 m_vk.getPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV	= (GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNVFunc)	GET_PROC_ADDR("vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
 m_vk.createHeadlessSurfaceEXT											= (CreateHeadlessSurfaceEXTFunc)										GET_PROC_ADDR("vkCreateHeadlessSurfaceEXT");
diff --git a/external/vulkancts/framework/vulkan/vkInstanceDriverImpl.inl b/external/vulkancts/framework/vulkan/vkInstanceDriverImpl.inl
index 05b8657..1e5af6c 100644
--- a/external/vulkancts/framework/vulkan/vkInstanceDriverImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkInstanceDriverImpl.inl
@@ -332,6 +332,11 @@
 	return m_vk.getPhysicalDeviceCalibrateableTimeDomainsEXT(physicalDevice, pTimeDomainCount, pTimeDomains);
 }
 
+VkResult InstanceDriver::getPhysicalDeviceToolPropertiesEXT (VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties) const
+{
+	return m_vk.getPhysicalDeviceToolPropertiesEXT(physicalDevice, pToolCount, pToolProperties);
+}
+
 VkResult InstanceDriver::getPhysicalDeviceCooperativeMatrixPropertiesNV (VkPhysicalDevice physicalDevice, deUint32* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties) const
 {
 	return m_vk.getPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, pPropertyCount, pProperties);
diff --git a/external/vulkancts/framework/vulkan/vkInstanceFunctionPointers.inl b/external/vulkancts/framework/vulkan/vkInstanceFunctionPointers.inl
index 53bd10c..3c14f23 100644
--- a/external/vulkancts/framework/vulkan/vkInstanceFunctionPointers.inl
+++ b/external/vulkancts/framework/vulkan/vkInstanceFunctionPointers.inl
@@ -67,6 +67,7 @@
 SubmitDebugUtilsMessageEXTFunc										submitDebugUtilsMessageEXT;
 GetPhysicalDeviceMultisamplePropertiesEXTFunc						getPhysicalDeviceMultisamplePropertiesEXT;
 GetPhysicalDeviceCalibrateableTimeDomainsEXTFunc					getPhysicalDeviceCalibrateableTimeDomainsEXT;
+GetPhysicalDeviceToolPropertiesEXTFunc								getPhysicalDeviceToolPropertiesEXT;
 GetPhysicalDeviceCooperativeMatrixPropertiesNVFunc					getPhysicalDeviceCooperativeMatrixPropertiesNV;
 GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNVFunc	getPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
 CreateHeadlessSurfaceEXTFunc										createHeadlessSurfaceEXT;
diff --git a/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl b/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
index 1f84a2b..b2ac3f2 100644
--- a/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
+++ b/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
@@ -3,7 +3,7 @@
  */
 bool checkMandatoryFeatures(const vkt::Context& context)
 {
-	if ( !context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2") )
+	if (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
 		TCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");
 
 	VkPhysicalDevice					physicalDevice		= context.getPhysicalDevice();
@@ -76,6 +76,16 @@
 		nextPtr  = &physicalDeviceScalarBlockLayoutFeaturesEXT.pNext;
 	}
 
+	vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT physicalDeviceSubgroupSizeControlFeaturesEXT;
+	deMemset(&physicalDeviceSubgroupSizeControlFeaturesEXT, 0, sizeof(physicalDeviceSubgroupSizeControlFeaturesEXT));
+
+	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_subgroup_size_control")) )
+	{
+		physicalDeviceSubgroupSizeControlFeaturesEXT.sType = getStructureType<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>();
+		*nextPtr = &physicalDeviceSubgroupSizeControlFeaturesEXT;
+		nextPtr  = &physicalDeviceSubgroupSizeControlFeaturesEXT.pNext;
+	}
+
 	vk::VkPhysicalDeviceTimelineSemaphoreFeaturesKHR physicalDeviceTimelineSemaphoreFeaturesKHR;
 	deMemset(&physicalDeviceTimelineSemaphoreFeaturesKHR, 0, sizeof(physicalDeviceTimelineSemaphoreFeaturesKHR));
 
@@ -106,6 +116,26 @@
 		nextPtr  = &physicalDeviceVariablePointersFeatures.pNext;
 	}
 
+	vk::VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features;
+	deMemset(&physicalDeviceVulkan11Features, 0, sizeof(physicalDeviceVulkan11Features));
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		physicalDeviceVulkan11Features.sType = getStructureType<VkPhysicalDeviceVulkan11Features>();
+		*nextPtr = &physicalDeviceVulkan11Features;
+		nextPtr  = &physicalDeviceVulkan11Features.pNext;
+	}
+
+	vk::VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features;
+	deMemset(&physicalDeviceVulkan12Features, 0, sizeof(physicalDeviceVulkan12Features));
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		physicalDeviceVulkan12Features.sType = getStructureType<VkPhysicalDeviceVulkan12Features>();
+		*nextPtr = &physicalDeviceVulkan12Features;
+		nextPtr  = &physicalDeviceVulkan12Features.pNext;
+	}
+
 	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);
 	bool result = true;
 
@@ -144,6 +174,15 @@
 		}
 	}
 
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan11Features.multiview == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature multiview not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
 	if ( context.contextSupports(vk::ApiVersion(1, 1, 0)) )
 	{
 		if ( physicalDeviceMultiviewFeatures.multiview == VK_FALSE )
@@ -333,6 +372,69 @@
 		}
 	}
 
+	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_subgroup_size_control")) )
+	{
+		if ( physicalDeviceSubgroupSizeControlFeaturesEXT.subgroupSizeControl == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature subgroupSizeControl not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_subgroup_size_control")) )
+	{
+		if ( physicalDeviceSubgroupSizeControlFeaturesEXT.computeFullSubgroups == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature computeFullSubgroups not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.subgroupBroadcastDynamicId == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature subgroupBroadcastDynamicId not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.imagelessFramebuffer == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature imagelessFramebuffer not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.uniformBufferStandardLayout == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature uniformBufferStandardLayout not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.separateDepthStencilLayouts == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature separateDepthStencilLayouts not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.hostQueryReset == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature hostQueryReset not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
 	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_timeline_semaphore")) )
 	{
 		if ( physicalDeviceTimelineSemaphoreFeaturesKHR.timelineSemaphore == VK_FALSE )
@@ -342,6 +444,132 @@
 		}
 	}
 
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) )
+	{
+		if ( physicalDeviceVulkan12Features.timelineSemaphore == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature timelineSemaphore not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.shaderUniformTexelBufferArrayDynamicIndexing == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature shaderUniformTexelBufferArrayDynamicIndexing not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.shaderStorageTexelBufferArrayDynamicIndexing == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature shaderStorageTexelBufferArrayDynamicIndexing not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.shaderSampledImageArrayNonUniformIndexing == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature shaderSampledImageArrayNonUniformIndexing not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.shaderStorageBufferArrayNonUniformIndexing == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature shaderStorageBufferArrayNonUniformIndexing not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.shaderUniformTexelBufferArrayNonUniformIndexing == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature shaderUniformTexelBufferArrayNonUniformIndexing not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingSampledImageUpdateAfterBind == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingSampledImageUpdateAfterBind not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingStorageImageUpdateAfterBind == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingStorageImageUpdateAfterBind not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingStorageBufferUpdateAfterBind == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingStorageBufferUpdateAfterBind not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingUniformTexelBufferUpdateAfterBind == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingUniformTexelBufferUpdateAfterBind not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingStorageTexelBufferUpdateAfterBind == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingStorageTexelBufferUpdateAfterBind not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingUpdateUnusedWhilePending == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingUpdateUnusedWhilePending not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.descriptorBindingPartiallyBound == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature descriptorBindingPartiallyBound not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
+	if ( context.contextSupports(vk::ApiVersion(1, 2, 0)) && physicalDeviceVulkan12Features.descriptorIndexing )
+	{
+		if ( physicalDeviceVulkan12Features.runtimeDescriptorArray == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature runtimeDescriptorArray not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
 	return result;
 }
 
diff --git a/external/vulkancts/framework/vulkan/vkNullDriver.cpp b/external/vulkancts/framework/vulkan/vkNullDriver.cpp
index 1fbc1d6..8b6f6ee 100644
--- a/external/vulkancts/framework/vulkan/vkNullDriver.cpp
+++ b/external/vulkancts/framework/vulkan/vkNullDriver.cpp
@@ -250,7 +250,7 @@
 {
 public:
 	RenderPass (VkDevice, const VkRenderPassCreateInfo*)		{}
-	RenderPass (VkDevice, const VkRenderPassCreateInfo2KHR*)	{}
+	RenderPass (VkDevice, const VkRenderPassCreateInfo2*)		{}
 };
 
 class SwapchainKHR
@@ -1136,12 +1136,10 @@
 
 	for (deUint32 planeNdx = 0; planeNdx < desc.numPlanes; ++planeNdx)
 	{
-		const deUint32		planeW		= extent.width / desc.planes[planeNdx].widthDivisor;
-		const deUint32		planeH		= extent.height / desc.planes[planeNdx].heightDivisor;
-		const deUint32		elementSize	= desc.planes[planeNdx].elementSizeBytes;
+		const deUint32	elementSize	= desc.planes[planeNdx].elementSizeBytes;
 
 		totalSize = (VkDeviceSize)deAlign64((deInt64)totalSize, elementSize);
-		totalSize += planeW * planeH * elementSize;
+		totalSize += getPlaneSizeInBytes(desc, extent, planeNdx, 0, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 	}
 
 	return totalSize;
diff --git a/external/vulkancts/framework/vulkan/vkNullDriverImpl.inl b/external/vulkancts/framework/vulkan/vkNullDriverImpl.inl
index 803e19e..efb4765 100644
--- a/external/vulkancts/framework/vulkan/vkNullDriverImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkNullDriverImpl.inl
@@ -127,6 +127,12 @@
 	VK_NULL_RETURN((*pDescriptorUpdateTemplate = allocateNonDispHandle<DescriptorUpdateTemplate, VkDescriptorUpdateTemplate>(device, pCreateInfo, pAllocator)));
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL createRenderPass2 (VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
+{
+	DE_UNREF(pAllocator);
+	VK_NULL_RETURN((*pRenderPass = allocateNonDispHandle<RenderPass, VkRenderPass>(device, pCreateInfo, pAllocator)));
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL createSwapchainKHR (VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
 {
 	DE_UNREF(pAllocator);
@@ -139,12 +145,6 @@
 	VK_NULL_RETURN((*pSurface = allocateNonDispHandle<SurfaceKHR, VkSurfaceKHR>(instance, pCreateInfo, pAllocator)));
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL createRenderPass2KHR (VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
-{
-	DE_UNREF(pAllocator);
-	VK_NULL_RETURN((*pRenderPass = allocateNonDispHandle<RenderPass, VkRenderPass>(device, pCreateInfo, pAllocator)));
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL createDebugReportCallbackEXT (VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback)
 {
 	DE_UNREF(pAllocator);
@@ -1231,6 +1231,100 @@
 	DE_UNREF(pSupport);
 }
 
+VKAPI_ATTR void VKAPI_CALL cmdDrawIndirectCount (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride)
+{
+	DE_UNREF(commandBuffer);
+	DE_UNREF(buffer);
+	DE_UNREF(offset);
+	DE_UNREF(countBuffer);
+	DE_UNREF(countBufferOffset);
+	DE_UNREF(maxDrawCount);
+	DE_UNREF(stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL cmdDrawIndexedIndirectCount (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride)
+{
+	DE_UNREF(commandBuffer);
+	DE_UNREF(buffer);
+	DE_UNREF(offset);
+	DE_UNREF(countBuffer);
+	DE_UNREF(countBufferOffset);
+	DE_UNREF(maxDrawCount);
+	DE_UNREF(stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL cmdBeginRenderPass2 (VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo)
+{
+	DE_UNREF(commandBuffer);
+	DE_UNREF(pRenderPassBegin);
+	DE_UNREF(pSubpassBeginInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL cmdNextSubpass2 (VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo)
+{
+	DE_UNREF(commandBuffer);
+	DE_UNREF(pSubpassBeginInfo);
+	DE_UNREF(pSubpassEndInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL cmdEndRenderPass2 (VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo)
+{
+	DE_UNREF(commandBuffer);
+	DE_UNREF(pSubpassEndInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL resetQueryPool (VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount)
+{
+	DE_UNREF(device);
+	DE_UNREF(queryPool);
+	DE_UNREF(firstQuery);
+	DE_UNREF(queryCount);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL getSemaphoreCounterValue (VkDevice device, VkSemaphore semaphore, deUint64* pValue)
+{
+	DE_UNREF(device);
+	DE_UNREF(semaphore);
+	DE_UNREF(pValue);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL waitSemaphores (VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout)
+{
+	DE_UNREF(device);
+	DE_UNREF(pWaitInfo);
+	DE_UNREF(timeout);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL signalSemaphore (VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo)
+{
+	DE_UNREF(device);
+	DE_UNREF(pSignalInfo);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL getBufferDeviceAddress (VkDevice device, const VkBufferDeviceAddressInfo* pInfo)
+{
+	DE_UNREF(device);
+	DE_UNREF(pInfo);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR uint64_t VKAPI_CALL getBufferOpaqueCaptureAddress (VkDevice device, const VkBufferDeviceAddressInfo* pInfo)
+{
+	DE_UNREF(device);
+	DE_UNREF(pInfo);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR uint64_t VKAPI_CALL getDeviceMemoryOpaqueCaptureAddress (VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo)
+{
+	DE_UNREF(device);
+	DE_UNREF(pInfo);
+	return VK_SUCCESS;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceSurfaceSupportKHR (VkPhysicalDevice physicalDevice, deUint32 queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported)
 {
 	DE_UNREF(physicalDevice);
@@ -1419,26 +1513,6 @@
 	DE_UNREF(pData);
 }
 
-VKAPI_ATTR void VKAPI_CALL cmdBeginRenderPass2KHR (VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo)
-{
-	DE_UNREF(commandBuffer);
-	DE_UNREF(pRenderPassBegin);
-	DE_UNREF(pSubpassBeginInfo);
-}
-
-VKAPI_ATTR void VKAPI_CALL cmdNextSubpass2KHR (VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo)
-{
-	DE_UNREF(commandBuffer);
-	DE_UNREF(pSubpassBeginInfo);
-	DE_UNREF(pSubpassEndInfo);
-}
-
-VKAPI_ATTR void VKAPI_CALL cmdEndRenderPass2KHR (VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo)
-{
-	DE_UNREF(commandBuffer);
-	DE_UNREF(pSubpassEndInfo);
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL getSwapchainStatusKHR (VkDevice device, VkSwapchainKHR swapchain)
 {
 	DE_UNREF(device);
@@ -1540,72 +1614,6 @@
 	return VK_SUCCESS;
 }
 
-VKAPI_ATTR void VKAPI_CALL cmdDrawIndirectCountKHR (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride)
-{
-	DE_UNREF(commandBuffer);
-	DE_UNREF(buffer);
-	DE_UNREF(offset);
-	DE_UNREF(countBuffer);
-	DE_UNREF(countBufferOffset);
-	DE_UNREF(maxDrawCount);
-	DE_UNREF(stride);
-}
-
-VKAPI_ATTR void VKAPI_CALL cmdDrawIndexedIndirectCountKHR (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride)
-{
-	DE_UNREF(commandBuffer);
-	DE_UNREF(buffer);
-	DE_UNREF(offset);
-	DE_UNREF(countBuffer);
-	DE_UNREF(countBufferOffset);
-	DE_UNREF(maxDrawCount);
-	DE_UNREF(stride);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL getSemaphoreCounterValueKHR (VkDevice device, VkSemaphore semaphore, deUint64* pValue)
-{
-	DE_UNREF(device);
-	DE_UNREF(semaphore);
-	DE_UNREF(pValue);
-	return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL waitSemaphoresKHR (VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout)
-{
-	DE_UNREF(device);
-	DE_UNREF(pWaitInfo);
-	DE_UNREF(timeout);
-	return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL signalSemaphoreKHR (VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo)
-{
-	DE_UNREF(device);
-	DE_UNREF(pSignalInfo);
-	return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkDeviceAddress VKAPI_CALL getBufferDeviceAddressKHR (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo)
-{
-	DE_UNREF(device);
-	DE_UNREF(pInfo);
-	return VK_SUCCESS;
-}
-
-VKAPI_ATTR uint64_t VKAPI_CALL getBufferOpaqueCaptureAddressKHR (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo)
-{
-	DE_UNREF(device);
-	DE_UNREF(pInfo);
-	return VK_SUCCESS;
-}
-
-VKAPI_ATTR uint64_t VKAPI_CALL getDeviceMemoryOpaqueCaptureAddressKHR (VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo)
-{
-	DE_UNREF(device);
-	DE_UNREF(pInfo);
-	return VK_SUCCESS;
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL getPipelineExecutablePropertiesKHR (VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, deUint32* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties)
 {
 	DE_UNREF(device);
@@ -2292,13 +2300,21 @@
 	DE_UNREF(localDimmingEnable);
 }
 
-VKAPI_ATTR VkDeviceAddress VKAPI_CALL getBufferDeviceAddressEXT (VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo)
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL getBufferDeviceAddressEXT (VkDevice device, const VkBufferDeviceAddressInfo* pInfo)
 {
 	DE_UNREF(device);
 	DE_UNREF(pInfo);
 	return VK_SUCCESS;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceToolPropertiesEXT (VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties)
+{
+	DE_UNREF(physicalDevice);
+	DE_UNREF(pToolCount);
+	DE_UNREF(pToolProperties);
+	return VK_SUCCESS;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceCooperativeMatrixPropertiesNV (VkPhysicalDevice physicalDevice, deUint32* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties)
 {
 	DE_UNREF(physicalDevice);
@@ -2322,14 +2338,6 @@
 	DE_UNREF(lineStipplePattern);
 }
 
-VKAPI_ATTR void VKAPI_CALL resetQueryPoolEXT (VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount)
-{
-	DE_UNREF(device);
-	DE_UNREF(queryPool);
-	DE_UNREF(firstQuery);
-	DE_UNREF(queryCount);
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL getAndroidHardwareBufferPropertiesANDROID (VkDevice device, const struct pt::AndroidHardwareBufferPtr buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties)
 {
 	DE_UNREF(device);
@@ -2553,6 +2561,7 @@
 	VK_NULL_FUNC_ENTRY(vkSubmitDebugUtilsMessageEXT,										submitDebugUtilsMessageEXT),
 	VK_NULL_FUNC_ENTRY(vkGetPhysicalDeviceMultisamplePropertiesEXT,							getPhysicalDeviceMultisamplePropertiesEXT),
 	VK_NULL_FUNC_ENTRY(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT,						getPhysicalDeviceCalibrateableTimeDomainsEXT),
+	VK_NULL_FUNC_ENTRY(vkGetPhysicalDeviceToolPropertiesEXT,								getPhysicalDeviceToolPropertiesEXT),
 	VK_NULL_FUNC_ENTRY(vkGetPhysicalDeviceCooperativeMatrixPropertiesNV,					getPhysicalDeviceCooperativeMatrixPropertiesNV),
 	VK_NULL_FUNC_ENTRY(vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV,	getPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV),
 	VK_NULL_FUNC_ENTRY(vkCreateHeadlessSurfaceEXT,											createHeadlessSurfaceEXT),
@@ -2715,6 +2724,19 @@
 	VK_NULL_FUNC_ENTRY(vkDestroyDescriptorUpdateTemplate,					destroyDescriptorUpdateTemplate),
 	VK_NULL_FUNC_ENTRY(vkUpdateDescriptorSetWithTemplate,					updateDescriptorSetWithTemplate),
 	VK_NULL_FUNC_ENTRY(vkGetDescriptorSetLayoutSupport,						getDescriptorSetLayoutSupport),
+	VK_NULL_FUNC_ENTRY(vkCmdDrawIndirectCount,								cmdDrawIndirectCount),
+	VK_NULL_FUNC_ENTRY(vkCmdDrawIndexedIndirectCount,						cmdDrawIndexedIndirectCount),
+	VK_NULL_FUNC_ENTRY(vkCreateRenderPass2,									createRenderPass2),
+	VK_NULL_FUNC_ENTRY(vkCmdBeginRenderPass2,								cmdBeginRenderPass2),
+	VK_NULL_FUNC_ENTRY(vkCmdNextSubpass2,									cmdNextSubpass2),
+	VK_NULL_FUNC_ENTRY(vkCmdEndRenderPass2,									cmdEndRenderPass2),
+	VK_NULL_FUNC_ENTRY(vkResetQueryPool,									resetQueryPool),
+	VK_NULL_FUNC_ENTRY(vkGetSemaphoreCounterValue,							getSemaphoreCounterValue),
+	VK_NULL_FUNC_ENTRY(vkWaitSemaphores,									waitSemaphores),
+	VK_NULL_FUNC_ENTRY(vkSignalSemaphore,									signalSemaphore),
+	VK_NULL_FUNC_ENTRY(vkGetBufferDeviceAddress,							getBufferDeviceAddress),
+	VK_NULL_FUNC_ENTRY(vkGetBufferOpaqueCaptureAddress,						getBufferOpaqueCaptureAddress),
+	VK_NULL_FUNC_ENTRY(vkGetDeviceMemoryOpaqueCaptureAddress,				getDeviceMemoryOpaqueCaptureAddress),
 	VK_NULL_FUNC_ENTRY(vkCreateSwapchainKHR,								createSwapchainKHR),
 	VK_NULL_FUNC_ENTRY(vkDestroySwapchainKHR,								destroySwapchainKHR),
 	VK_NULL_FUNC_ENTRY(vkGetSwapchainImagesKHR,								getSwapchainImagesKHR),
@@ -2737,10 +2759,10 @@
 	VK_NULL_FUNC_ENTRY(vkCreateDescriptorUpdateTemplateKHR,					createDescriptorUpdateTemplate),
 	VK_NULL_FUNC_ENTRY(vkDestroyDescriptorUpdateTemplateKHR,				destroyDescriptorUpdateTemplate),
 	VK_NULL_FUNC_ENTRY(vkUpdateDescriptorSetWithTemplateKHR,				updateDescriptorSetWithTemplate),
-	VK_NULL_FUNC_ENTRY(vkCreateRenderPass2KHR,								createRenderPass2KHR),
-	VK_NULL_FUNC_ENTRY(vkCmdBeginRenderPass2KHR,							cmdBeginRenderPass2KHR),
-	VK_NULL_FUNC_ENTRY(vkCmdNextSubpass2KHR,								cmdNextSubpass2KHR),
-	VK_NULL_FUNC_ENTRY(vkCmdEndRenderPass2KHR,								cmdEndRenderPass2KHR),
+	VK_NULL_FUNC_ENTRY(vkCreateRenderPass2KHR,								createRenderPass2),
+	VK_NULL_FUNC_ENTRY(vkCmdBeginRenderPass2KHR,							cmdBeginRenderPass2),
+	VK_NULL_FUNC_ENTRY(vkCmdNextSubpass2KHR,								cmdNextSubpass2),
+	VK_NULL_FUNC_ENTRY(vkCmdEndRenderPass2KHR,								cmdEndRenderPass2),
 	VK_NULL_FUNC_ENTRY(vkGetSwapchainStatusKHR,								getSwapchainStatusKHR),
 	VK_NULL_FUNC_ENTRY(vkImportFenceFdKHR,									importFenceFdKHR),
 	VK_NULL_FUNC_ENTRY(vkGetFenceFdKHR,										getFenceFdKHR),
@@ -2754,14 +2776,14 @@
 	VK_NULL_FUNC_ENTRY(vkBindBufferMemory2KHR,								bindBufferMemory2),
 	VK_NULL_FUNC_ENTRY(vkBindImageMemory2KHR,								bindImageMemory2),
 	VK_NULL_FUNC_ENTRY(vkGetDescriptorSetLayoutSupportKHR,					getDescriptorSetLayoutSupport),
-	VK_NULL_FUNC_ENTRY(vkCmdDrawIndirectCountKHR,							cmdDrawIndirectCountKHR),
-	VK_NULL_FUNC_ENTRY(vkCmdDrawIndexedIndirectCountKHR,					cmdDrawIndexedIndirectCountKHR),
-	VK_NULL_FUNC_ENTRY(vkGetSemaphoreCounterValueKHR,						getSemaphoreCounterValueKHR),
-	VK_NULL_FUNC_ENTRY(vkWaitSemaphoresKHR,									waitSemaphoresKHR),
-	VK_NULL_FUNC_ENTRY(vkSignalSemaphoreKHR,								signalSemaphoreKHR),
-	VK_NULL_FUNC_ENTRY(vkGetBufferDeviceAddressKHR,							getBufferDeviceAddressKHR),
-	VK_NULL_FUNC_ENTRY(vkGetBufferOpaqueCaptureAddressKHR,					getBufferOpaqueCaptureAddressKHR),
-	VK_NULL_FUNC_ENTRY(vkGetDeviceMemoryOpaqueCaptureAddressKHR,			getDeviceMemoryOpaqueCaptureAddressKHR),
+	VK_NULL_FUNC_ENTRY(vkCmdDrawIndirectCountKHR,							cmdDrawIndirectCount),
+	VK_NULL_FUNC_ENTRY(vkCmdDrawIndexedIndirectCountKHR,					cmdDrawIndexedIndirectCount),
+	VK_NULL_FUNC_ENTRY(vkGetSemaphoreCounterValueKHR,						getSemaphoreCounterValue),
+	VK_NULL_FUNC_ENTRY(vkWaitSemaphoresKHR,									waitSemaphores),
+	VK_NULL_FUNC_ENTRY(vkSignalSemaphoreKHR,								signalSemaphore),
+	VK_NULL_FUNC_ENTRY(vkGetBufferDeviceAddressKHR,							getBufferDeviceAddress),
+	VK_NULL_FUNC_ENTRY(vkGetBufferOpaqueCaptureAddressKHR,					getBufferOpaqueCaptureAddress),
+	VK_NULL_FUNC_ENTRY(vkGetDeviceMemoryOpaqueCaptureAddressKHR,			getDeviceMemoryOpaqueCaptureAddress),
 	VK_NULL_FUNC_ENTRY(vkGetPipelineExecutablePropertiesKHR,				getPipelineExecutablePropertiesKHR),
 	VK_NULL_FUNC_ENTRY(vkGetPipelineExecutableStatisticsKHR,				getPipelineExecutableStatisticsKHR),
 	VK_NULL_FUNC_ENTRY(vkGetPipelineExecutableInternalRepresentationsKHR,	getPipelineExecutableInternalRepresentationsKHR),
@@ -2849,7 +2871,7 @@
 	VK_NULL_FUNC_ENTRY(vkSetLocalDimmingAMD,								setLocalDimmingAMD),
 	VK_NULL_FUNC_ENTRY(vkGetBufferDeviceAddressEXT,							getBufferDeviceAddressEXT),
 	VK_NULL_FUNC_ENTRY(vkCmdSetLineStippleEXT,								cmdSetLineStippleEXT),
-	VK_NULL_FUNC_ENTRY(vkResetQueryPoolEXT,									resetQueryPoolEXT),
+	VK_NULL_FUNC_ENTRY(vkResetQueryPoolEXT,									resetQueryPool),
 	VK_NULL_FUNC_ENTRY(vkGetAndroidHardwareBufferPropertiesANDROID,			getAndroidHardwareBufferPropertiesANDROID),
 	VK_NULL_FUNC_ENTRY(vkGetMemoryAndroidHardwareBufferANDROID,				getMemoryAndroidHardwareBufferANDROID),
 	VK_NULL_FUNC_ENTRY(vkGetMemoryWin32HandleKHR,							getMemoryWin32HandleKHR),
diff --git a/external/vulkancts/framework/vulkan/vkPrograms.cpp b/external/vulkancts/framework/vulkan/vkPrograms.cpp
index 242cacb..6444570 100644
--- a/external/vulkancts/framework/vulkan/vkPrograms.cpp
+++ b/external/vulkancts/framework/vulkan/vkPrograms.cpp
@@ -110,6 +110,7 @@
 		case SPIRV_VERSION_1_2:
 		case SPIRV_VERSION_1_3: targetEnv = SPV_ENV_VULKAN_1_1;	break;
 		case SPIRV_VERSION_1_4: targetEnv = SPV_ENV_VULKAN_1_1_SPIRV_1_4;	break;
+		case SPIRV_VERSION_1_5: targetEnv = SPV_ENV_VULKAN_1_2;	break;
 		default:
 			TCU_THROW(InternalError, "Unexpected SPIR-V version requested");
 	}
@@ -753,8 +754,10 @@
 	deUint32 vulkanVersionMajorMinor = VK_MAKE_VERSION(VK_VERSION_MAJOR(vulkanVersion), VK_VERSION_MINOR(vulkanVersion), 0);
 	if (vulkanVersionMajorMinor == VK_API_VERSION_1_0)
 		result = vk::SPIRV_VERSION_1_0;
-	else if (vulkanVersionMajorMinor >= VK_API_VERSION_1_1)
+	else if (vulkanVersionMajorMinor == VK_API_VERSION_1_1)
 		result = vk::SPIRV_VERSION_1_3;
+	else if (vulkanVersionMajorMinor >= VK_API_VERSION_1_2)
+		result = vk::SPIRV_VERSION_1_5;
 
 	DE_ASSERT(result < vk::SPIRV_VERSION_LAST);
 
@@ -773,7 +776,7 @@
 
 SpirvVersion extractSpirvVersion (const ProgramBinary& binary)
 {
-	DE_STATIC_ASSERT(SPIRV_VERSION_1_4 + 1 == SPIRV_VERSION_LAST);
+	DE_STATIC_ASSERT(SPIRV_VERSION_1_5 + 1 == SPIRV_VERSION_LAST);
 
 	if (binary.getFormat() != PROGRAM_FORMAT_SPIRV)
 		TCU_THROW(InternalError, "Binary is not in SPIR-V format");
@@ -786,6 +789,7 @@
 	const deUint32				spirvBinaryVersion12	= 0x00010200;
 	const deUint32				spirvBinaryVersion13	= 0x00010300;
 	const deUint32				spirvBinaryVersion14	= 0x00010400;
+	const deUint32				spirvBinaryVersion15	= 0x00010500;
 	const SpirvBinaryHeader*	header					= reinterpret_cast<const SpirvBinaryHeader*>(binary.getBinary());
 	const deUint32				spirvVersion			= isNativeSpirVBinaryEndianness()
 														? header->version
@@ -799,6 +803,7 @@
 		case spirvBinaryVersion12:	result = SPIRV_VERSION_1_2; break; //!< SPIR-V 1.2
 		case spirvBinaryVersion13:	result = SPIRV_VERSION_1_3; break; //!< SPIR-V 1.3
 		case spirvBinaryVersion14:	result = SPIRV_VERSION_1_4; break; //!< SPIR-V 1.4
+		case spirvBinaryVersion15:	result = SPIRV_VERSION_1_5; break; //!< SPIR-V 1.5
 		default:					TCU_THROW(InternalError, "Unknown SPIR-V version detected in binary");
 	}
 
@@ -807,7 +812,7 @@
 
 std::string getSpirvVersionName (const SpirvVersion spirvVersion)
 {
-	DE_STATIC_ASSERT(SPIRV_VERSION_1_4 + 1 == SPIRV_VERSION_LAST);
+	DE_STATIC_ASSERT(SPIRV_VERSION_1_5 + 1 == SPIRV_VERSION_LAST);
 	DE_ASSERT(spirvVersion < SPIRV_VERSION_LAST);
 
 	std::string result;
@@ -819,6 +824,7 @@
 		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
 		case SPIRV_VERSION_1_4: result = "1.4"; break; //!< SPIR-V 1.4
+		case SPIRV_VERSION_1_5: result = "1.5"; break; //!< SPIR-V 1.5
 		default:				result = "Unknown";
 	}
 
diff --git a/external/vulkancts/framework/vulkan/vkQueryUtil.cpp b/external/vulkancts/framework/vulkan/vkQueryUtil.cpp
index 8f7be39..de83fab 100644
--- a/external/vulkancts/framework/vulkan/vkQueryUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkQueryUtil.cpp
@@ -155,6 +155,43 @@
 	return features;
 }
 
+VkPhysicalDeviceVulkan12Features getPhysicalDeviceVulkan12Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
+{
+	VkPhysicalDeviceFeatures2			features;
+	VkPhysicalDeviceVulkan12Features	vulkan_12_features;
+
+	deMemset(&features, 0, sizeof(features));
+	features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+
+	deMemset(&vulkan_12_features, 0, sizeof(vulkan_12_features));
+	vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+
+	features.pNext = &vulkan_12_features;
+
+	vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
+	return vulkan_12_features;
+}
+
+VkPhysicalDeviceVulkan11Properties getPhysicalDeviceVulkan11Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
+{
+	VkPhysicalDeviceVulkan11Properties	vulkan11properties	= initVulkanStructure();
+	VkPhysicalDeviceProperties2			properties			= initVulkanStructure(&vulkan11properties);
+
+	vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
+
+	return vulkan11properties;
+}
+
+VkPhysicalDeviceVulkan12Properties getPhysicalDeviceVulkan12Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
+{
+	VkPhysicalDeviceVulkan12Properties	vulkan12properties	= initVulkanStructure();
+	VkPhysicalDeviceProperties2			properties			= initVulkanStructure(&vulkan12properties);
+
+	vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
+
+	return vulkan12properties;
+}
+
 VkPhysicalDeviceProperties getPhysicalDeviceProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
 {
 	VkPhysicalDeviceProperties	properties;
diff --git a/external/vulkancts/framework/vulkan/vkQueryUtil.hpp b/external/vulkancts/framework/vulkan/vkQueryUtil.hpp
index 27a22d5..2c526d8 100644
--- a/external/vulkancts/framework/vulkan/vkQueryUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkQueryUtil.hpp
@@ -47,6 +47,9 @@
 std::vector<VkQueueFamilyProperties>			getPhysicalDeviceQueueFamilyProperties			(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
 VkPhysicalDeviceFeatures						getPhysicalDeviceFeatures						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
 VkPhysicalDeviceFeatures2						getPhysicalDeviceFeatures2						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
+VkPhysicalDeviceVulkan12Features				getPhysicalDeviceVulkan12Features				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
+VkPhysicalDeviceVulkan11Properties				getPhysicalDeviceVulkan11Properties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
+VkPhysicalDeviceVulkan12Properties				getPhysicalDeviceVulkan12Properties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
 VkPhysicalDeviceProperties						getPhysicalDeviceProperties						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
 VkPhysicalDeviceMemoryProperties				getPhysicalDeviceMemoryProperties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
 VkFormatProperties								getPhysicalDeviceFormatProperties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format);
@@ -137,6 +140,97 @@
 	return reinterpret_cast<StructType*>(findStructureInChain(first, getStructureType<StructType>()));
 }
 
+struct initVulkanStructure
+{
+	initVulkanStructure	(void*	pNext = DE_NULL)	: m_next(pNext)	{};
+
+	template<class StructType>
+	operator StructType()
+	{
+		StructType result;
+
+		deMemset(&result, 0x00, sizeof(StructType));
+
+		result.sType	= getStructureType<StructType>();
+		result.pNext	= m_next;
+
+		return result;
+	}
+
+private:
+	void*	m_next;
+};
+
+template<class StructType>
+void addToChainVulkanStructure (void***	chainPNextPtr, StructType&	structType)
+{
+	DE_ASSERT(chainPNextPtr != DE_NULL);
+
+	(**chainPNextPtr) = &structType;
+
+	(*chainPNextPtr) = &structType.pNext;
+}
+
+struct initVulkanStructureConst
+{
+	initVulkanStructureConst	(const void*	pNext = DE_NULL)	: m_next(pNext)	{};
+
+	template<class StructType>
+	operator const StructType()
+	{
+		StructType result;
+
+		deMemset(&result, 0x00, sizeof(StructType));
+
+		result.sType	= getStructureType<StructType>();
+		result.pNext	= const_cast<void*>(m_next);
+
+		return result;
+	}
+
+private:
+	const void*	m_next;
+};
+
+struct getPhysicalDeviceExtensionProperties
+{
+	getPhysicalDeviceExtensionProperties (const InstanceInterface&	vki, VkPhysicalDevice physicalDevice) : m_vki(vki), m_physicalDevice(physicalDevice) {};
+
+	template<class ExtensionProperties>
+	operator ExtensionProperties ()
+	{
+		VkPhysicalDeviceProperties2	properties2;
+		ExtensionProperties			extensionProperties;
+
+		deMemset(&extensionProperties, 0x00, sizeof(ExtensionProperties));
+		extensionProperties.sType = getStructureType<ExtensionProperties>();
+
+		deMemset(&properties2, 0x00, sizeof(properties2));
+		properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+		properties2.pNext = &extensionProperties;
+
+		m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
+
+		return extensionProperties;
+	}
+
+	operator VkPhysicalDeviceProperties2 ()
+	{
+		VkPhysicalDeviceProperties2	properties2;
+
+		deMemset(&properties2, 0x00, sizeof(properties2));
+		properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+
+		m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
+
+		return properties2;
+	}
+
+private:
+	const InstanceInterface&	m_vki;
+	const VkPhysicalDevice		m_physicalDevice;
+};
+
 namespace ValidateQueryBits
 {
 
@@ -167,6 +261,30 @@
 	return true;
 }
 
+template <typename Type>
+//!< Return variable initialization validation
+bool validateStructsWithGuard (const QueryMemberTableEntry* queryMemberTableEntry, Type* vec[2], const deUint8 guardValue, const deUint32 guardSize)
+{
+	const QueryMemberTableEntry	*iterator;
+
+	for (iterator = queryMemberTableEntry; iterator->size != 0; iterator++)
+	{
+		if (deMemCmp(((deUint8*)(vec[0]))+iterator->offset, ((deUint8*)(vec[1]))+iterator->offset, iterator->size) != 0)
+			return false;
+	}
+
+	for (deUint32 vecNdx = 0; vecNdx < 2; ++vecNdx)
+	{
+		for (deUint32 ndx = 0; ndx < guardSize; ndx++)
+		{
+			if (((deUint8*)(vec[vecNdx]))[ndx + sizeof(Type)] != guardValue)
+				return false;
+		}
+	}
+
+	return true;
+}
+
 template<typename IterT>
 //! Overwrite a range of objects with an 8-bit pattern.
 inline void fillBits (IterT beg, const IterT end, const deUint8 pattern = 0xdeu)
diff --git a/external/vulkancts/framework/vulkan/vkRefUtil.cpp b/external/vulkancts/framework/vulkan/vkRefUtil.cpp
index 2a508cd..dbe70d5 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkRefUtil.cpp
@@ -95,14 +95,14 @@
 
 Move<VkSemaphore> createSemaphoreType (const DeviceInterface&		vk,
 									   VkDevice						device,
-									   VkSemaphoreTypeKHR			type,
+									   VkSemaphoreType				type,
 									   VkSemaphoreCreateFlags		flags,
 									   const deUint64				initialValue,
 									   const VkAllocationCallbacks*	pAllocator)
 {
-	const VkSemaphoreTypeCreateInfoKHR	createTypeInfo =
+	const VkSemaphoreTypeCreateInfo	createTypeInfo =
 	{
-		VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR,
+		VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
 		DE_NULL,
 
 		type,
diff --git a/external/vulkancts/framework/vulkan/vkRefUtil.hpp b/external/vulkancts/framework/vulkan/vkRefUtil.hpp
index 8b437c6..a966b20 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkRefUtil.hpp
@@ -56,7 +56,7 @@
 
 Move<VkSemaphore>		createSemaphoreType		(const DeviceInterface&			vk,
 												 VkDevice						device,
-												 VkSemaphoreTypeKHR				type,
+												 VkSemaphoreType				type,
 												 VkSemaphoreCreateFlags			flags			= (VkSemaphoreCreateFlags)0,
 												 const deUint64					initialValue	= 0,
 												 const VkAllocationCallbacks*	pAllocator		= DE_NULL);
diff --git a/external/vulkancts/framework/vulkan/vkRefUtil.inl b/external/vulkancts/framework/vulkan/vkRefUtil.inl
index 78953f5..921adc7 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtil.inl
+++ b/external/vulkancts/framework/vulkan/vkRefUtil.inl
@@ -23,10 +23,10 @@
 Move<VkCommandPool>					createCommandPool					(const DeviceInterface& vk, VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkSamplerYcbcrConversion>		createSamplerYcbcrConversion		(const DeviceInterface& vk, VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkDescriptorUpdateTemplate>	createDescriptorUpdateTemplate		(const DeviceInterface& vk, VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
+Move<VkRenderPass>					createRenderPass2					(const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkSwapchainKHR>				createSwapchainKHR					(const DeviceInterface& vk, VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkSurfaceKHR>					createDisplayPlaneSurfaceKHR		(const InstanceInterface& vk, VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkSwapchainKHR>				createSharedSwapchainsKHR			(const DeviceInterface& vk, VkDevice device, deUint32 swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator = DE_NULL);
-Move<VkRenderPass>					createRenderPass2KHR				(const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkDebugReportCallbackEXT>		createDebugReportCallbackEXT		(const InstanceInterface& vk, VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkIndirectCommandsLayoutNVX>	createIndirectCommandsLayoutNVX		(const DeviceInterface& vk, VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
 Move<VkObjectTableNVX>				createObjectTableNVX				(const DeviceInterface& vk, VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator = DE_NULL);
diff --git a/external/vulkancts/framework/vulkan/vkRefUtilImpl.inl b/external/vulkancts/framework/vulkan/vkRefUtilImpl.inl
index dd75368..6eb0c48 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtilImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkRefUtilImpl.inl
@@ -316,6 +316,13 @@
 	return Move<VkDescriptorUpdateTemplate>(check<VkDescriptorUpdateTemplate>(object), Deleter<VkDescriptorUpdateTemplate>(vk, device, pAllocator));
 }
 
+Move<VkRenderPass> createRenderPass2 (const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator)
+{
+	VkRenderPass object = 0;
+	VK_CHECK(vk.createRenderPass2(device, pCreateInfo, pAllocator, &object));
+	return Move<VkRenderPass>(check<VkRenderPass>(object), Deleter<VkRenderPass>(vk, device, pAllocator));
+}
+
 Move<VkSwapchainKHR> createSwapchainKHR (const DeviceInterface& vk, VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator)
 {
 	VkSwapchainKHR object = 0;
@@ -337,13 +344,6 @@
 	return Move<VkSwapchainKHR>(check<VkSwapchainKHR>(object), Deleter<VkSwapchainKHR>(vk, device, pAllocator));
 }
 
-Move<VkRenderPass> createRenderPass2KHR (const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator)
-{
-	VkRenderPass object = 0;
-	VK_CHECK(vk.createRenderPass2KHR(device, pCreateInfo, pAllocator, &object));
-	return Move<VkRenderPass>(check<VkRenderPass>(object), Deleter<VkRenderPass>(vk, device, pAllocator));
-}
-
 Move<VkDebugReportCallbackEXT> createDebugReportCallbackEXT (const InstanceInterface& vk, VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator)
 {
 	VkDebugReportCallbackEXT object = 0;
diff --git a/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp b/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
index 1fe287a..9916c59 100644
--- a/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
+++ b/external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp
@@ -296,6 +296,9 @@
 			case SPIRV_VERSION_1_4:
 				shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10400);
 				break;
+			case SPIRV_VERSION_1_5:
+				shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10500);
+				break;
 			default:
 				TCU_THROW(InternalError, "Unsupported SPIR-V target version");
 			}
diff --git a/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp b/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
index 4f8d2bb..bdcdc67 100644
--- a/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
+++ b/external/vulkancts/framework/vulkan/vkSpirVAsm.cpp
@@ -45,6 +45,7 @@
 	{
 		case VK_MAKE_VERSION(1, 0, 0): return SPV_ENV_VULKAN_1_0;
 		case VK_MAKE_VERSION(1, 1, 0): return allow_1_4 ? SPV_ENV_VULKAN_1_1_SPIRV_1_4 : SPV_ENV_VULKAN_1_1;
+		case VK_MAKE_VERSION(1, 2, 0): return SPV_ENV_VULKAN_1_2;
 		default:
 			break;
 	}
@@ -63,6 +64,7 @@
 		case SPIRV_VERSION_1_2: result = SPV_ENV_UNIVERSAL_1_2; break;	//!< SPIR-V 1.2
 		case SPIRV_VERSION_1_3: result = SPV_ENV_UNIVERSAL_1_3; break;	//!< SPIR-V 1.3
 		case SPIRV_VERSION_1_4: result = SPV_ENV_UNIVERSAL_1_4; break;	//!< SPIR-V 1.4
+		case SPIRV_VERSION_1_5: result = SPV_ENV_UNIVERSAL_1_5; break;	//!< SPIR-V 1.5
 		default:				TCU_THROW(InternalError, "Unknown SPIR-V version");
 	}
 
diff --git a/external/vulkancts/framework/vulkan/vkStrUtil.cpp b/external/vulkancts/framework/vulkan/vkStrUtil.cpp
index cfcae94..26f9b19 100644
--- a/external/vulkancts/framework/vulkan/vkStrUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkStrUtil.cpp
@@ -46,6 +46,47 @@
 	return CharPtr(ptr);
 }
 
+
+#if (DE_OS == DE_OS_WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+struct WStr
+{
+	LPCWSTR wstr;
+
+	WStr (LPCWSTR wstr_) : wstr(wstr_) {}
+};
+
+std::ostream& operator<< (std::ostream& str, const WStr& wstr)
+{
+	int len = WideCharToMultiByte(CP_UTF8, 0, wstr.wstr, -1, NULL, 0, 0, 0);
+	if (len < 1)
+		return str << "(null)";
+
+	std::string result;
+	result.resize(len + 1);
+	WideCharToMultiByte(CP_UTF8, 0, wstr.wstr, -1, &result[0], len, 0, 0);
+
+	return str << '"' << result << '"';
+}
+
+inline WStr getWStr (pt::Win32LPCWSTR pt_wstr)
+{
+	return WStr(static_cast<LPCWSTR>(pt_wstr.internal));
+}
+
+#else
+
+inline CharPtr getWStr (pt::Win32LPCWSTR pt_wstr)
+{
+	return CharPtr(static_cast<const char*>(pt_wstr.internal));
+}
+
+#endif
+
+
 #include "vkStrUtilImpl.inl"
 
 } // vk
diff --git a/external/vulkancts/framework/vulkan/vkStrUtil.inl b/external/vulkancts/framework/vulkan/vkStrUtil.inl
index a58551d..295a019 100644
--- a/external/vulkancts/framework/vulkan/vkStrUtil.inl
+++ b/external/vulkancts/framework/vulkan/vkStrUtil.inl
@@ -44,14 +44,15 @@
 const char*	getSamplerYcbcrRangeName								(VkSamplerYcbcrRange value);
 const char*	getChromaLocationName									(VkChromaLocation value);
 const char*	getDescriptorUpdateTemplateTypeName						(VkDescriptorUpdateTemplateType value);
+const char*	getDriverIdName											(VkDriverId value);
+const char*	getShaderFloatControlsIndependenceName					(VkShaderFloatControlsIndependence value);
+const char*	getSamplerReductionModeName								(VkSamplerReductionMode value);
+const char*	getSemaphoreTypeName									(VkSemaphoreType value);
 const char*	getColorSpaceKHRName									(VkColorSpaceKHR value);
 const char*	getPresentModeKHRName									(VkPresentModeKHR value);
 const char*	getPerformanceCounterUnitKHRName						(VkPerformanceCounterUnitKHR value);
 const char*	getPerformanceCounterScopeKHRName						(VkPerformanceCounterScopeKHR value);
 const char*	getPerformanceCounterStorageKHRName						(VkPerformanceCounterStorageKHR value);
-const char*	getDriverIdKHRName										(VkDriverIdKHR value);
-const char*	getShaderFloatControlsIndependenceKHRName				(VkShaderFloatControlsIndependenceKHR value);
-const char*	getSemaphoreTypeKHRName									(VkSemaphoreTypeKHR value);
 const char*	getPipelineExecutableStatisticFormatKHRName				(VkPipelineExecutableStatisticFormatKHR value);
 const char*	getDebugReportObjectTypeEXTName							(VkDebugReportObjectTypeEXT value);
 const char*	getRasterizationOrderAMDName							(VkRasterizationOrderAMD value);
@@ -65,7 +66,6 @@
 const char*	getViewportCoordinateSwizzleNVName						(VkViewportCoordinateSwizzleNV value);
 const char*	getDiscardRectangleModeEXTName							(VkDiscardRectangleModeEXT value);
 const char*	getConservativeRasterizationModeEXTName					(VkConservativeRasterizationModeEXT value);
-const char*	getSamplerReductionModeEXTName							(VkSamplerReductionModeEXT value);
 const char*	getBlendOverlapEXTName									(VkBlendOverlapEXT value);
 const char*	getCoverageModulationModeNVName							(VkCoverageModulationModeNV value);
 const char*	getValidationCacheHeaderVersionEXTName					(VkValidationCacheHeaderVersionEXT value);
@@ -135,14 +135,15 @@
 inline tcu::Format::Enum<VkSamplerYcbcrRange>								getSamplerYcbcrRangeStr								(VkSamplerYcbcrRange value)								{ return tcu::Format::Enum<VkSamplerYcbcrRange>(getSamplerYcbcrRangeName, value);															}
 inline tcu::Format::Enum<VkChromaLocation>									getChromaLocationStr								(VkChromaLocation value)								{ return tcu::Format::Enum<VkChromaLocation>(getChromaLocationName, value);																	}
 inline tcu::Format::Enum<VkDescriptorUpdateTemplateType>					getDescriptorUpdateTemplateTypeStr					(VkDescriptorUpdateTemplateType value)					{ return tcu::Format::Enum<VkDescriptorUpdateTemplateType>(getDescriptorUpdateTemplateTypeName, value);										}
+inline tcu::Format::Enum<VkDriverId>										getDriverIdStr										(VkDriverId value)										{ return tcu::Format::Enum<VkDriverId>(getDriverIdName, value);																				}
+inline tcu::Format::Enum<VkShaderFloatControlsIndependence>					getShaderFloatControlsIndependenceStr				(VkShaderFloatControlsIndependence value)				{ return tcu::Format::Enum<VkShaderFloatControlsIndependence>(getShaderFloatControlsIndependenceName, value);								}
+inline tcu::Format::Enum<VkSamplerReductionMode>							getSamplerReductionModeStr							(VkSamplerReductionMode value)							{ return tcu::Format::Enum<VkSamplerReductionMode>(getSamplerReductionModeName, value);														}
+inline tcu::Format::Enum<VkSemaphoreType>									getSemaphoreTypeStr									(VkSemaphoreType value)									{ return tcu::Format::Enum<VkSemaphoreType>(getSemaphoreTypeName, value);																	}
 inline tcu::Format::Enum<VkColorSpaceKHR>									getColorSpaceKHRStr									(VkColorSpaceKHR value)									{ return tcu::Format::Enum<VkColorSpaceKHR>(getColorSpaceKHRName, value);																	}
 inline tcu::Format::Enum<VkPresentModeKHR>									getPresentModeKHRStr								(VkPresentModeKHR value)								{ return tcu::Format::Enum<VkPresentModeKHR>(getPresentModeKHRName, value);																	}
 inline tcu::Format::Enum<VkPerformanceCounterUnitKHR>						getPerformanceCounterUnitKHRStr						(VkPerformanceCounterUnitKHR value)						{ return tcu::Format::Enum<VkPerformanceCounterUnitKHR>(getPerformanceCounterUnitKHRName, value);											}
 inline tcu::Format::Enum<VkPerformanceCounterScopeKHR>						getPerformanceCounterScopeKHRStr					(VkPerformanceCounterScopeKHR value)					{ return tcu::Format::Enum<VkPerformanceCounterScopeKHR>(getPerformanceCounterScopeKHRName, value);											}
 inline tcu::Format::Enum<VkPerformanceCounterStorageKHR>					getPerformanceCounterStorageKHRStr					(VkPerformanceCounterStorageKHR value)					{ return tcu::Format::Enum<VkPerformanceCounterStorageKHR>(getPerformanceCounterStorageKHRName, value);										}
-inline tcu::Format::Enum<VkDriverIdKHR>										getDriverIdKHRStr									(VkDriverIdKHR value)									{ return tcu::Format::Enum<VkDriverIdKHR>(getDriverIdKHRName, value);																		}
-inline tcu::Format::Enum<VkShaderFloatControlsIndependenceKHR>				getShaderFloatControlsIndependenceKHRStr			(VkShaderFloatControlsIndependenceKHR value)			{ return tcu::Format::Enum<VkShaderFloatControlsIndependenceKHR>(getShaderFloatControlsIndependenceKHRName, value);							}
-inline tcu::Format::Enum<VkSemaphoreTypeKHR>								getSemaphoreTypeKHRStr								(VkSemaphoreTypeKHR value)								{ return tcu::Format::Enum<VkSemaphoreTypeKHR>(getSemaphoreTypeKHRName, value);																}
 inline tcu::Format::Enum<VkPipelineExecutableStatisticFormatKHR>			getPipelineExecutableStatisticFormatKHRStr			(VkPipelineExecutableStatisticFormatKHR value)			{ return tcu::Format::Enum<VkPipelineExecutableStatisticFormatKHR>(getPipelineExecutableStatisticFormatKHRName, value);						}
 inline tcu::Format::Enum<VkDebugReportObjectTypeEXT>						getDebugReportObjectTypeEXTStr						(VkDebugReportObjectTypeEXT value)						{ return tcu::Format::Enum<VkDebugReportObjectTypeEXT>(getDebugReportObjectTypeEXTName, value);												}
 inline tcu::Format::Enum<VkRasterizationOrderAMD>							getRasterizationOrderAMDStr							(VkRasterizationOrderAMD value)							{ return tcu::Format::Enum<VkRasterizationOrderAMD>(getRasterizationOrderAMDName, value);													}
@@ -156,7 +157,6 @@
 inline tcu::Format::Enum<VkViewportCoordinateSwizzleNV>						getViewportCoordinateSwizzleNVStr					(VkViewportCoordinateSwizzleNV value)					{ return tcu::Format::Enum<VkViewportCoordinateSwizzleNV>(getViewportCoordinateSwizzleNVName, value);										}
 inline tcu::Format::Enum<VkDiscardRectangleModeEXT>							getDiscardRectangleModeEXTStr						(VkDiscardRectangleModeEXT value)						{ return tcu::Format::Enum<VkDiscardRectangleModeEXT>(getDiscardRectangleModeEXTName, value);												}
 inline tcu::Format::Enum<VkConservativeRasterizationModeEXT>				getConservativeRasterizationModeEXTStr				(VkConservativeRasterizationModeEXT value)				{ return tcu::Format::Enum<VkConservativeRasterizationModeEXT>(getConservativeRasterizationModeEXTName, value);								}
-inline tcu::Format::Enum<VkSamplerReductionModeEXT>							getSamplerReductionModeEXTStr						(VkSamplerReductionModeEXT value)						{ return tcu::Format::Enum<VkSamplerReductionModeEXT>(getSamplerReductionModeEXTName, value);												}
 inline tcu::Format::Enum<VkBlendOverlapEXT>									getBlendOverlapEXTStr								(VkBlendOverlapEXT value)								{ return tcu::Format::Enum<VkBlendOverlapEXT>(getBlendOverlapEXTName, value);																}
 inline tcu::Format::Enum<VkCoverageModulationModeNV>						getCoverageModulationModeNVStr						(VkCoverageModulationModeNV value)						{ return tcu::Format::Enum<VkCoverageModulationModeNV>(getCoverageModulationModeNVName, value);												}
 inline tcu::Format::Enum<VkValidationCacheHeaderVersionEXT>					getValidationCacheHeaderVersionEXTStr				(VkValidationCacheHeaderVersionEXT value)				{ return tcu::Format::Enum<VkValidationCacheHeaderVersionEXT>(getValidationCacheHeaderVersionEXTName, value);								}
@@ -226,14 +226,15 @@
 inline std::ostream&	operator<<	(std::ostream& s, VkSamplerYcbcrRange value)								{ return s << getSamplerYcbcrRangeStr(value);								}
 inline std::ostream&	operator<<	(std::ostream& s, VkChromaLocation value)									{ return s << getChromaLocationStr(value);									}
 inline std::ostream&	operator<<	(std::ostream& s, VkDescriptorUpdateTemplateType value)						{ return s << getDescriptorUpdateTemplateTypeStr(value);					}
+inline std::ostream&	operator<<	(std::ostream& s, VkDriverId value)											{ return s << getDriverIdStr(value);										}
+inline std::ostream&	operator<<	(std::ostream& s, VkShaderFloatControlsIndependence value)					{ return s << getShaderFloatControlsIndependenceStr(value);					}
+inline std::ostream&	operator<<	(std::ostream& s, VkSamplerReductionMode value)								{ return s << getSamplerReductionModeStr(value);							}
+inline std::ostream&	operator<<	(std::ostream& s, VkSemaphoreType value)									{ return s << getSemaphoreTypeStr(value);									}
 inline std::ostream&	operator<<	(std::ostream& s, VkColorSpaceKHR value)									{ return s << getColorSpaceKHRStr(value);									}
 inline std::ostream&	operator<<	(std::ostream& s, VkPresentModeKHR value)									{ return s << getPresentModeKHRStr(value);									}
 inline std::ostream&	operator<<	(std::ostream& s, VkPerformanceCounterUnitKHR value)						{ return s << getPerformanceCounterUnitKHRStr(value);						}
 inline std::ostream&	operator<<	(std::ostream& s, VkPerformanceCounterScopeKHR value)						{ return s << getPerformanceCounterScopeKHRStr(value);						}
 inline std::ostream&	operator<<	(std::ostream& s, VkPerformanceCounterStorageKHR value)						{ return s << getPerformanceCounterStorageKHRStr(value);					}
-inline std::ostream&	operator<<	(std::ostream& s, VkDriverIdKHR value)										{ return s << getDriverIdKHRStr(value);										}
-inline std::ostream&	operator<<	(std::ostream& s, VkShaderFloatControlsIndependenceKHR value)				{ return s << getShaderFloatControlsIndependenceKHRStr(value);				}
-inline std::ostream&	operator<<	(std::ostream& s, VkSemaphoreTypeKHR value)									{ return s << getSemaphoreTypeKHRStr(value);								}
 inline std::ostream&	operator<<	(std::ostream& s, VkPipelineExecutableStatisticFormatKHR value)				{ return s << getPipelineExecutableStatisticFormatKHRStr(value);			}
 inline std::ostream&	operator<<	(std::ostream& s, VkDebugReportObjectTypeEXT value)							{ return s << getDebugReportObjectTypeEXTStr(value);						}
 inline std::ostream&	operator<<	(std::ostream& s, VkRasterizationOrderAMD value)							{ return s << getRasterizationOrderAMDStr(value);							}
@@ -247,7 +248,6 @@
 inline std::ostream&	operator<<	(std::ostream& s, VkViewportCoordinateSwizzleNV value)						{ return s << getViewportCoordinateSwizzleNVStr(value);						}
 inline std::ostream&	operator<<	(std::ostream& s, VkDiscardRectangleModeEXT value)							{ return s << getDiscardRectangleModeEXTStr(value);							}
 inline std::ostream&	operator<<	(std::ostream& s, VkConservativeRasterizationModeEXT value)					{ return s << getConservativeRasterizationModeEXTStr(value);				}
-inline std::ostream&	operator<<	(std::ostream& s, VkSamplerReductionModeEXT value)							{ return s << getSamplerReductionModeEXTStr(value);							}
 inline std::ostream&	operator<<	(std::ostream& s, VkBlendOverlapEXT value)									{ return s << getBlendOverlapEXTStr(value);									}
 inline std::ostream&	operator<<	(std::ostream& s, VkCoverageModulationModeNV value)							{ return s << getCoverageModulationModeNVStr(value);						}
 inline std::ostream&	operator<<	(std::ostream& s, VkValidationCacheHeaderVersionEXT value)					{ return s << getValidationCacheHeaderVersionEXTStr(value);					}
@@ -324,6 +324,9 @@
 tcu::Format::Bitfield<32>	getSemaphoreImportFlagsStr									(VkSemaphoreImportFlags value);
 tcu::Format::Bitfield<32>	getExternalSemaphoreHandleTypeFlagsStr						(VkExternalSemaphoreHandleTypeFlags value);
 tcu::Format::Bitfield<32>	getExternalSemaphoreFeatureFlagsStr							(VkExternalSemaphoreFeatureFlags value);
+tcu::Format::Bitfield<32>	getResolveModeFlagsStr										(VkResolveModeFlags value);
+tcu::Format::Bitfield<32>	getDescriptorBindingFlagsStr								(VkDescriptorBindingFlags value);
+tcu::Format::Bitfield<32>	getSemaphoreWaitFlagsStr									(VkSemaphoreWaitFlags value);
 tcu::Format::Bitfield<32>	getSurfaceTransformFlagsKHRStr								(VkSurfaceTransformFlagsKHR value);
 tcu::Format::Bitfield<32>	getCompositeAlphaFlagsKHRStr								(VkCompositeAlphaFlagsKHR value);
 tcu::Format::Bitfield<32>	getSwapchainCreateFlagsKHRStr								(VkSwapchainCreateFlagsKHR value);
@@ -331,8 +334,6 @@
 tcu::Format::Bitfield<32>	getDisplayPlaneAlphaFlagsKHRStr								(VkDisplayPlaneAlphaFlagsKHR value);
 tcu::Format::Bitfield<32>	getPerformanceCounterDescriptionFlagsKHRStr					(VkPerformanceCounterDescriptionFlagsKHR value);
 tcu::Format::Bitfield<32>	getAcquireProfilingLockFlagsKHRStr							(VkAcquireProfilingLockFlagsKHR value);
-tcu::Format::Bitfield<32>	getResolveModeFlagsKHRStr									(VkResolveModeFlagsKHR value);
-tcu::Format::Bitfield<32>	getSemaphoreWaitFlagsKHRStr									(VkSemaphoreWaitFlagsKHR value);
 tcu::Format::Bitfield<32>	getDebugReportFlagsEXTStr									(VkDebugReportFlagsEXT value);
 tcu::Format::Bitfield<32>	getExternalMemoryHandleTypeFlagsNVStr						(VkExternalMemoryHandleTypeFlagsNV value);
 tcu::Format::Bitfield<32>	getExternalMemoryFeatureFlagsNVStr							(VkExternalMemoryFeatureFlagsNV value);
@@ -342,13 +343,13 @@
 tcu::Format::Bitfield<32>	getSurfaceCounterFlagsEXTStr								(VkSurfaceCounterFlagsEXT value);
 tcu::Format::Bitfield<32>	getDebugUtilsMessageSeverityFlagsEXTStr						(VkDebugUtilsMessageSeverityFlagsEXT value);
 tcu::Format::Bitfield<32>	getDebugUtilsMessageTypeFlagsEXTStr							(VkDebugUtilsMessageTypeFlagsEXT value);
-tcu::Format::Bitfield<32>	getDescriptorBindingFlagsEXTStr								(VkDescriptorBindingFlagsEXT value);
 tcu::Format::Bitfield<32>	getGeometryFlagsNVStr										(VkGeometryFlagsNV value);
 tcu::Format::Bitfield<32>	getGeometryInstanceFlagsNVStr								(VkGeometryInstanceFlagsNV value);
 tcu::Format::Bitfield<32>	getBuildAccelerationStructureFlagsNVStr						(VkBuildAccelerationStructureFlagsNV value);
 tcu::Format::Bitfield<32>	getPipelineCompilerControlFlagsAMDStr						(VkPipelineCompilerControlFlagsAMD value);
 tcu::Format::Bitfield<32>	getPipelineCreationFeedbackFlagsEXTStr						(VkPipelineCreationFeedbackFlagsEXT value);
 tcu::Format::Bitfield<32>	getShaderCorePropertiesFlagsAMDStr							(VkShaderCorePropertiesFlagsAMD value);
+tcu::Format::Bitfield<32>	getToolPurposeFlagsEXTStr									(VkToolPurposeFlagsEXT value);
 tcu::Format::Bitfield<32>	getInstanceCreateFlagsStr									(VkInstanceCreateFlags value);
 tcu::Format::Bitfield<32>	getDeviceCreateFlagsStr										(VkDeviceCreateFlags value);
 tcu::Format::Bitfield<32>	getMemoryMapFlagsStr										(VkMemoryMapFlags value);
@@ -573,6 +574,57 @@
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceMaintenance3Properties& value);
 std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetLayoutSupport& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderDrawParametersFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkan11Features& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkan11Properties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkan12Features& value);
+std::ostream&	operator<<	(std::ostream& s, const VkConformanceVersion& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkan12Properties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkImageFormatListCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkAttachmentDescription2& value);
+std::ostream&	operator<<	(std::ostream& s, const VkAttachmentReference2& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSubpassDescription2& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSubpassDependency2& value);
+std::ostream&	operator<<	(std::ostream& s, const VkRenderPassCreateInfo2& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSubpassBeginInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSubpassEndInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDevice8BitStorageFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDriverProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderAtomicInt64Features& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderFloat16Int8Features& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceFloatControlsProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetLayoutBindingFlagsCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDescriptorIndexingFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDescriptorIndexingProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetVariableDescriptorCountAllocateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetVariableDescriptorCountLayoutSupport& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSubpassDescriptionDepthStencilResolve& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDepthStencilResolveProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceScalarBlockLayoutFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkImageStencilUsageCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSamplerReductionModeCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSamplerFilterMinmaxProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkanMemoryModelFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkFramebufferAttachmentImageInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkFramebufferAttachmentsCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkRenderPassAttachmentBeginInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceUniformBufferStandardLayoutFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkAttachmentReferenceStencilLayout& value);
+std::ostream&	operator<<	(std::ostream& s, const VkAttachmentDescriptionStencilLayout& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceHostQueryResetFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreProperties& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreTypeCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkTimelineSemaphoreSubmitInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreWaitInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreSignalInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceBufferDeviceAddressFeatures& value);
+std::ostream&	operator<<	(std::ostream& s, const VkBufferDeviceAddressInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkBufferOpaqueCaptureAddressCreateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkMemoryOpaqueCaptureAddressAllocateInfo& value);
+std::ostream&	operator<<	(std::ostream& s, const VkDeviceMemoryOpaqueCaptureAddressInfo& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSurfaceCapabilitiesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSurfaceFormatKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSwapchainCreateInfoKHR& value);
@@ -597,21 +649,9 @@
 std::ostream&	operator<<	(std::ostream& s, const VkImportSemaphoreFdInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreGetFdInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDevicePushDescriptorPropertiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderFloat16Int8FeaturesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkRectLayerKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPresentRegionKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPresentRegionsKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkFramebufferAttachmentImageInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkFramebufferAttachmentsCreateInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkRenderPassAttachmentBeginInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkAttachmentDescription2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkAttachmentReference2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSubpassDescription2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSubpassDependency2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkRenderPassCreateInfo2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSubpassBeginInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSubpassEndInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSharedPresentSurfaceCapabilitiesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkImportFenceFdInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkFenceGetFdInfoKHR& value);
@@ -631,33 +671,8 @@
 std::ostream&	operator<<	(std::ostream& s, const VkDisplayModeProperties2KHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkDisplayPlaneInfo2KHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkDisplayPlaneCapabilities2KHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkImageFormatListCreateInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDevice8BitStorageFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderClockFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkConformanceVersionKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDriverPropertiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceFloatControlsPropertiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSubpassDescriptionDepthStencilResolveKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDepthStencilResolvePropertiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceTimelineSemaphorePropertiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreTypeCreateInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkTimelineSemaphoreSubmitInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreWaitInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSemaphoreSignalInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkSurfaceProtectedCapabilitiesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkAttachmentReferenceStencilLayoutKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkAttachmentDescriptionStencilLayoutKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceBufferDeviceAddressFeaturesKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkBufferDeviceAddressInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkBufferOpaqueCaptureAddressCreateInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkMemoryOpaqueCaptureAddressAllocateInfoKHR& value);
-std::ostream&	operator<<	(std::ostream& s, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPipelineInfoKHR& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPipelineExecutablePropertiesKHR& value);
@@ -732,8 +747,6 @@
 std::ostream&	operator<<	(std::ostream& s, const VkDebugUtilsLabelEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkDebugUtilsMessengerCallbackDataEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkDebugUtilsMessengerCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkSamplerReductionModeCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceInlineUniformBlockFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceInlineUniformBlockPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkWriteDescriptorSetInlineUniformBlockEXT& value);
@@ -761,11 +774,6 @@
 std::ostream&	operator<<	(std::ostream& s, const VkImageDrmFormatModifierPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkValidationCacheCreateInfoEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkShaderModuleValidationCacheCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDescriptorIndexingPropertiesEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetVariableDescriptorCountAllocateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkDescriptorSetVariableDescriptorCountLayoutSupportEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkShadingRatePaletteNV& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPipelineViewportShadingRateImageStateCreateInfoNV& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShadingRateImageFeaturesNV& value);
@@ -828,7 +836,6 @@
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceFragmentDensityMapFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceFragmentDensityMapPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkRenderPassFragmentDensityMapCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT& value);
@@ -840,7 +847,7 @@
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkBufferDeviceAddressCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkImageStencilUsageCreateInfoEXT& value);
+std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceToolPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkValidationFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkCooperativeMatrixPropertiesNV& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceCooperativeMatrixFeaturesNV& value);
@@ -854,7 +861,6 @@
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceLineRasterizationFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceLineRasterizationPropertiesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPipelineRasterizationLineStateCreateInfoEXT& value);
-std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceHostQueryResetFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceIndexTypeUint8FeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT& value);
 std::ostream&	operator<<	(std::ostream& s, const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT& value);
diff --git a/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl b/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl
index f759be5..51a536b 100644
--- a/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl
+++ b/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl
@@ -59,6 +59,7 @@
 std::ostream& operator<< (std::ostream& s, Win32SecurityAttributesPtr	v) { return s << tcu::toHex(v.internal); }
 std::ostream& operator<< (std::ostream& s, AndroidHardwareBufferPtr		v) { return s << tcu::toHex(v.internal); }
 std::ostream& operator<< (std::ostream& s, Win32MonitorHandle			v) { return s << tcu::toHex(v.internal); }
+std::ostream& operator<< (std::ostream& s, Win32LPCWSTR					v) { return s << tcu::toHex(v.internal); }
 std::ostream& operator<< (std::ostream& s, RROutput						v) { return s << tcu::toHex(v.internal); }
 std::ostream& operator<< (std::ostream& s, zx_handle_t					v) { return s << tcu::toHex(v.internal); }
 std::ostream& operator<< (std::ostream& s, GgpFrameToken				v) { return s << tcu::toHex(v.internal); }
@@ -98,8 +99,11 @@
 		case VK_ERROR_TOO_MANY_OBJECTS:								return "VK_ERROR_TOO_MANY_OBJECTS";
 		case VK_ERROR_FORMAT_NOT_SUPPORTED:							return "VK_ERROR_FORMAT_NOT_SUPPORTED";
 		case VK_ERROR_FRAGMENTED_POOL:								return "VK_ERROR_FRAGMENTED_POOL";
+		case VK_ERROR_UNKNOWN:										return "VK_ERROR_UNKNOWN";
 		case VK_ERROR_OUT_OF_POOL_MEMORY:							return "VK_ERROR_OUT_OF_POOL_MEMORY";
 		case VK_ERROR_INVALID_EXTERNAL_HANDLE:						return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
+		case VK_ERROR_FRAGMENTATION:								return "VK_ERROR_FRAGMENTATION";
+		case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS:				return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
 		case VK_ERROR_SURFACE_LOST_KHR:								return "VK_ERROR_SURFACE_LOST_KHR";
 		case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:						return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
 		case VK_SUBOPTIMAL_KHR:										return "VK_SUBOPTIMAL_KHR";
@@ -108,10 +112,8 @@
 		case VK_ERROR_VALIDATION_FAILED_EXT:						return "VK_ERROR_VALIDATION_FAILED_EXT";
 		case VK_ERROR_INVALID_SHADER_NV:							return "VK_ERROR_INVALID_SHADER_NV";
 		case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:	return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
-		case VK_ERROR_FRAGMENTATION_EXT:							return "VK_ERROR_FRAGMENTATION_EXT";
 		case VK_ERROR_NOT_PERMITTED_EXT:							return "VK_ERROR_NOT_PERMITTED_EXT";
 		case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:			return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
-		case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR:			return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR";
 		case VK_RESULT_MAX_ENUM:									return "VK_RESULT_MAX_ENUM";
 		default:													return DE_NULL;
 	}
@@ -235,6 +237,56 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES";
 		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT:									return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:								return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:							return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:								return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:							return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES";
+		case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:									return "VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2:										return "VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2";
+		case VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2:											return "VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2";
+		case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2:											return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2";
+		case VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2:											return "VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2";
+		case VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2:										return "VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2";
+		case VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO:												return "VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO";
+		case VK_STRUCTURE_TYPE_SUBPASS_END_INFO:												return "VK_STRUCTURE_TYPE_SUBPASS_END_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES:							return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES:								return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES";
+		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO:					return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES";
+		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO:			return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO";
+		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT:			return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES";
+		case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE:						return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES";
+		case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:									return "VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES";
+		case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:								return "VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES";
+		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO:								return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO:								return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO";
+		case VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO:								return "VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES";
+		case VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT:								return "VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT";
+		case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT:							return "VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES";
+		case VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO:										return "VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO:									return "VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO";
+		case VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO:												return "VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO";
+		case VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO:											return "VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES";
+		case VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO:										return "VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO";
+		case VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO:						return "VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO";
+		case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO:						return "VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO";
+		case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO:						return "VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO";
 		case VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR:										return "VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR";
 		case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR:												return "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR";
 		case VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR:							return "VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR";
@@ -294,7 +346,6 @@
 		case VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT:		return "VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT:							return "VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR:												return "VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR";
 		case VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX:									return "VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX";
 		case VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX:						return "VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX";
@@ -318,17 +369,6 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT:			return "VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_HDR_METADATA_EXT:												return "VK_STRUCTURE_TYPE_HDR_METADATA_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR";
-		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR:							return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR";
-		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR:							return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR";
-		case VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR:							return "VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR";
-		case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR:									return "VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR";
-		case VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR:										return "VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR";
-		case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR:										return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR";
-		case VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR:										return "VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR";
-		case VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR:									return "VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR";
-		case VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR:											return "VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR";
-		case VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR:											return "VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR";
 		case VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR:							return "VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR";
 		case VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR:								return "VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR";
 		case VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR:								return "VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR";
@@ -363,8 +403,6 @@
 		case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:						return "VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID";
 		case VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:					return "VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID";
 		case VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID:											return "VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT";
-		case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT:							return "VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT:					return "VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT";
@@ -374,7 +412,6 @@
 		case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT:					return "VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT:										return "VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT";
-		case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR:								return "VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT:				return "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT";
@@ -390,11 +427,6 @@
 		case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT:						return "VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT:								return "VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT:					return "VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT:				return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT";
-		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT:		return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT:		return "VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT";
 		case VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV:		return "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV";
@@ -415,12 +447,9 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT";
 		case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT:					return "VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR:		return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:								return "VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT";
 		case VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT:								return "VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD:						return "VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD";
 		case VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT:									return "VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT";
@@ -431,10 +460,6 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP:											return "VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP";
 		case VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT:						return "VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR:							return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR";
-		case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR:					return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV:							return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV";
@@ -444,12 +469,6 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV";
 		case VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV:												return "VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV";
 		case VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV:							return "VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR";
-		case VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR:									return "VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR";
-		case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR:								return "VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR";
-		case VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR:											return "VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR";
-		case VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR:										return "VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL:		return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL";
 		case VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL:									return "VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL";
 		case VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL:							return "VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL";
@@ -457,7 +476,6 @@
 		case VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL:							return "VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL";
 		case VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL:									return "VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL";
 		case VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL:					return "VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:						return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD:						return "VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD";
 		case VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD:					return "VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD";
@@ -466,7 +484,6 @@
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT:				return "VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT:	return "VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT";
@@ -477,12 +494,9 @@
 		case VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT:								return "VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR:								return "VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV:	return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR:		return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR";
-		case VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR:							return "VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR";
-		case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR:						return "VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT:							return "VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:								return "VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT";
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT:								return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT";
 		case VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT:											return "VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV";
 		case VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV:								return "VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV";
@@ -492,20 +506,13 @@
 		case VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV:						return "VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT:			return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR:		return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT:							return "VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT:					return "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT";
 		case VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT:					return "VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT";
 		case VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT:								return "VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR";
-		case VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR:									return "VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR";
-		case VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR:					return "VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR";
-		case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR:					return "VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR";
-		case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR:					return "VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT:				return "VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT:				return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT";
-		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT:					return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT";
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR:		return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR";
 		case VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR:												return "VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR";
@@ -875,14 +882,14 @@
 		case VK_IMAGE_LAYOUT_PREINITIALIZED:								return "VK_IMAGE_LAYOUT_PREINITIALIZED";
 		case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:	return "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL";
 		case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:	return "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL";
+		case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:						return "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL";
+		case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:						return "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL";
+		case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:					return "VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL";
+		case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:						return "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL";
 		case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:								return "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR";
 		case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:							return "VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR";
 		case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:						return "VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV";
 		case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:				return "VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT";
-		case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR:					return "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR";
-		case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR:					return "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR";
-		case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR:				return "VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR";
-		case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR:					return "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR";
 		case VK_IMAGE_LAYOUT_MAX_ENUM:										return "VK_IMAGE_LAYOUT_MAX_ENUM";
 		default:															return DE_NULL;
 	}
@@ -1420,6 +1427,62 @@
 	}
 }
 
+const char* getDriverIdName (VkDriverId value)
+{
+	switch (value)
+	{
+		case VK_DRIVER_ID_AMD_PROPRIETARY:				return "VK_DRIVER_ID_AMD_PROPRIETARY";
+		case VK_DRIVER_ID_AMD_OPEN_SOURCE:				return "VK_DRIVER_ID_AMD_OPEN_SOURCE";
+		case VK_DRIVER_ID_MESA_RADV:					return "VK_DRIVER_ID_MESA_RADV";
+		case VK_DRIVER_ID_NVIDIA_PROPRIETARY:			return "VK_DRIVER_ID_NVIDIA_PROPRIETARY";
+		case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:	return "VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS";
+		case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:		return "VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA";
+		case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:		return "VK_DRIVER_ID_IMAGINATION_PROPRIETARY";
+		case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:			return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY";
+		case VK_DRIVER_ID_ARM_PROPRIETARY:				return "VK_DRIVER_ID_ARM_PROPRIETARY";
+		case VK_DRIVER_ID_GOOGLE_SWIFTSHADER:			return "VK_DRIVER_ID_GOOGLE_SWIFTSHADER";
+		case VK_DRIVER_ID_GGP_PROPRIETARY:				return "VK_DRIVER_ID_GGP_PROPRIETARY";
+		case VK_DRIVER_ID_BROADCOM_PROPRIETARY:			return "VK_DRIVER_ID_BROADCOM_PROPRIETARY";
+		case VK_DRIVER_ID_MAX_ENUM:						return "VK_DRIVER_ID_MAX_ENUM";
+		default:										return DE_NULL;
+	}
+}
+
+const char* getShaderFloatControlsIndependenceName (VkShaderFloatControlsIndependence value)
+{
+	switch (value)
+	{
+		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY:	return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY";
+		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL:			return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL";
+		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE:		return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE";
+		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM:	return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM";
+		default:												return DE_NULL;
+	}
+}
+
+const char* getSamplerReductionModeName (VkSamplerReductionMode value)
+{
+	switch (value)
+	{
+		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE:	return "VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE";
+		case VK_SAMPLER_REDUCTION_MODE_MIN:					return "VK_SAMPLER_REDUCTION_MODE_MIN";
+		case VK_SAMPLER_REDUCTION_MODE_MAX:					return "VK_SAMPLER_REDUCTION_MODE_MAX";
+		case VK_SAMPLER_REDUCTION_MODE_MAX_ENUM:			return "VK_SAMPLER_REDUCTION_MODE_MAX_ENUM";
+		default:											return DE_NULL;
+	}
+}
+
+const char* getSemaphoreTypeName (VkSemaphoreType value)
+{
+	switch (value)
+	{
+		case VK_SEMAPHORE_TYPE_BINARY:		return "VK_SEMAPHORE_TYPE_BINARY";
+		case VK_SEMAPHORE_TYPE_TIMELINE:	return "VK_SEMAPHORE_TYPE_TIMELINE";
+		case VK_SEMAPHORE_TYPE_MAX_ENUM:	return "VK_SEMAPHORE_TYPE_MAX_ENUM";
+		default:							return DE_NULL;
+	}
+}
+
 const char* getColorSpaceKHRName (VkColorSpaceKHR value)
 {
 	switch (value)
@@ -1484,11 +1547,11 @@
 {
 	switch (value)
 	{
-		case VK_QUERY_SCOPE_COMMAND_BUFFER_KHR:			return "VK_QUERY_SCOPE_COMMAND_BUFFER_KHR";
-		case VK_QUERY_SCOPE_RENDER_PASS_KHR:			return "VK_QUERY_SCOPE_RENDER_PASS_KHR";
-		case VK_QUERY_SCOPE_COMMAND_KHR:				return "VK_QUERY_SCOPE_COMMAND_KHR";
-		case VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR:	return "VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR";
-		default:										return DE_NULL;
+		case VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR:	return "VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR";
+		case VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR:		return "VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR";
+		case VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR:			return "VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR";
+		case VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR:			return "VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR";
+		default:												return DE_NULL;
 	}
 }
 
@@ -1507,50 +1570,6 @@
 	}
 }
 
-const char* getDriverIdKHRName (VkDriverIdKHR value)
-{
-	switch (value)
-	{
-		case VK_DRIVER_ID_AMD_PROPRIETARY_KHR:				return "VK_DRIVER_ID_AMD_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR:				return "VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR";
-		case VK_DRIVER_ID_MESA_RADV_KHR:					return "VK_DRIVER_ID_MESA_RADV_KHR";
-		case VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR:			return "VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR:	return "VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR";
-		case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR:		return "VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR";
-		case VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR:		return "VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR:			return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_ARM_PROPRIETARY_KHR:				return "VK_DRIVER_ID_ARM_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR:			return "VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR";
-		case VK_DRIVER_ID_GGP_PROPRIETARY_KHR:				return "VK_DRIVER_ID_GGP_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR:			return "VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR";
-		case VK_DRIVER_ID_MAX_ENUM_KHR:						return "VK_DRIVER_ID_MAX_ENUM_KHR";
-		default:											return DE_NULL;
-	}
-}
-
-const char* getShaderFloatControlsIndependenceKHRName (VkShaderFloatControlsIndependenceKHR value)
-{
-	switch (value)
-	{
-		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR:	return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR";
-		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR:			return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR";
-		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR:		return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR";
-		case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR:	return "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR";
-		default:													return DE_NULL;
-	}
-}
-
-const char* getSemaphoreTypeKHRName (VkSemaphoreTypeKHR value)
-{
-	switch (value)
-	{
-		case VK_SEMAPHORE_TYPE_BINARY_KHR:		return "VK_SEMAPHORE_TYPE_BINARY_KHR";
-		case VK_SEMAPHORE_TYPE_TIMELINE_KHR:	return "VK_SEMAPHORE_TYPE_TIMELINE_KHR";
-		case VK_SEMAPHORE_TYPE_MAX_ENUM_KHR:	return "VK_SEMAPHORE_TYPE_MAX_ENUM_KHR";
-		default:								return DE_NULL;
-	}
-}
-
 const char* getPipelineExecutableStatisticFormatKHRName (VkPipelineExecutableStatisticFormatKHR value)
 {
 	switch (value)
@@ -1747,18 +1766,6 @@
 	}
 }
 
-const char* getSamplerReductionModeEXTName (VkSamplerReductionModeEXT value)
-{
-	switch (value)
-	{
-		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT:	return "VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT";
-		case VK_SAMPLER_REDUCTION_MODE_MIN_EXT:					return "VK_SAMPLER_REDUCTION_MODE_MIN_EXT";
-		case VK_SAMPLER_REDUCTION_MODE_MAX_EXT:					return "VK_SAMPLER_REDUCTION_MODE_MAX_EXT";
-		case VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT:			return "VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT";
-		default:												return DE_NULL;
-	}
-}
-
 const char* getBlendOverlapEXTName (VkBlendOverlapEXT value)
 {
 	switch (value)
@@ -2103,11 +2110,12 @@
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT,		"VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_DISJOINT_BIT,																	"VK_FORMAT_FEATURE_DISJOINT_BIT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT,														"VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"),
+		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT,													"VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG,												"VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG"),
-		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT,												"VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT,													"VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR,															"VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR,															"VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR"),
+		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT,												"VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR,													"VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR,							"VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR"),
 		tcu::Format::BitDesc(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR,			"VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR"),
@@ -2370,8 +2378,9 @@
 		tcu::Format::BitDesc(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,						"VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,						"VK_BUFFER_CREATE_SPARSE_ALIASED_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_CREATE_PROTECTED_BIT,							"VK_BUFFER_CREATE_PROTECTED_BIT"),
-		tcu::Format::BitDesc(VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,	"VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR"),
+		tcu::Format::BitDesc(VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,		"VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT,	"VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT"),
+		tcu::Format::BitDesc(VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,	"VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR"),
 		tcu::Format::BitDesc(VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM,						"VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM"),
 	};
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
@@ -2390,12 +2399,13 @@
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_INDEX_BUFFER_BIT,							"VK_BUFFER_USAGE_INDEX_BUFFER_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							"VK_BUFFER_USAGE_VERTEX_BUFFER_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,						"VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT"),
+		tcu::Format::BitDesc(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,					"VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT,			"VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT,	"VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT,				"VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_RAY_TRACING_BIT_NV,						"VK_BUFFER_USAGE_RAY_TRACING_BIT_NV"),
-		tcu::Format::BitDesc(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,				"VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT,				"VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT"),
+		tcu::Format::BitDesc(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,				"VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR"),
 		tcu::Format::BitDesc(VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM,						"VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM"),
 	};
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
@@ -2517,6 +2527,7 @@
 {
 	static const tcu::Format::BitDesc s_desc[] =
 	{
+		tcu::Format::BitDesc(VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,		"VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT"),
 		tcu::Format::BitDesc(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,			"VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR"),
 		tcu::Format::BitDesc(VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT,	"VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT"),
 		tcu::Format::BitDesc(VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM,				"VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM"),
@@ -2529,6 +2540,7 @@
 	static const tcu::Format::BitDesc s_desc[] =
 	{
 		tcu::Format::BitDesc(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		"VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,		"VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT"),
 		tcu::Format::BitDesc(VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT,	"VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT"),
 		tcu::Format::BitDesc(VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM,			"VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM"),
 	};
@@ -2539,6 +2551,7 @@
 {
 	static const tcu::Format::BitDesc s_desc[] =
 	{
+		tcu::Format::BitDesc(VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,		"VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT"),
 		tcu::Format::BitDesc(VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR,	"VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR"),
 		tcu::Format::BitDesc(VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM,	"VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM"),
 	};
@@ -2733,9 +2746,11 @@
 	static const tcu::Format::BitDesc s_desc[] =
 	{
 		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,						"VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT"),
+		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,						"VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT"),
+		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,		"VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT"),
+		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR,					"VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR"),
 		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR,					"VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR"),
 		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,	"VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR"),
-		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR,					"VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR"),
 		tcu::Format::BitDesc(VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM,						"VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM"),
 	};
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
@@ -2867,6 +2882,53 @@
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
 
+tcu::Format::Bitfield<32> getResolveModeFlagsStr (VkResolveModeFlags value)
+{
+	static const tcu::Format::BitDesc s_desc[] =
+	{
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_NONE,					"VK_RESOLVE_MODE_NONE"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,		"VK_RESOLVE_MODE_SAMPLE_ZERO_BIT"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_AVERAGE_BIT,			"VK_RESOLVE_MODE_AVERAGE_BIT"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_MIN_BIT,				"VK_RESOLVE_MODE_MIN_BIT"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_MAX_BIT,				"VK_RESOLVE_MODE_MAX_BIT"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_NONE_KHR,				"VK_RESOLVE_MODE_NONE_KHR"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,	"VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_AVERAGE_BIT_KHR,		"VK_RESOLVE_MODE_AVERAGE_BIT_KHR"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_MIN_BIT_KHR,			"VK_RESOLVE_MODE_MIN_BIT_KHR"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_MAX_BIT_KHR,			"VK_RESOLVE_MODE_MAX_BIT_KHR"),
+		tcu::Format::BitDesc(VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM,	"VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM"),
+	};
+	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
+}
+
+tcu::Format::Bitfield<32> getDescriptorBindingFlagsStr (VkDescriptorBindingFlags value)
+{
+	static const tcu::Format::BitDesc s_desc[] =
+	{
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,				"VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,		"VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,					"VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,		"VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT,			"VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT,	"VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT,				"VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT,	"VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT"),
+		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM,					"VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM"),
+	};
+	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
+}
+
+tcu::Format::Bitfield<32> getSemaphoreWaitFlagsStr (VkSemaphoreWaitFlags value)
+{
+	static const tcu::Format::BitDesc s_desc[] =
+	{
+		tcu::Format::BitDesc(VK_SEMAPHORE_WAIT_ANY_BIT,				"VK_SEMAPHORE_WAIT_ANY_BIT"),
+		tcu::Format::BitDesc(VK_SEMAPHORE_WAIT_ANY_BIT_KHR,			"VK_SEMAPHORE_WAIT_ANY_BIT_KHR"),
+		tcu::Format::BitDesc(VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM,	"VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM"),
+	};
+	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
+}
+
 tcu::Format::Bitfield<32> getSurfaceTransformFlagsKHRStr (VkSurfaceTransformFlagsKHR value)
 {
 	static const tcu::Format::BitDesc s_desc[] =
@@ -2956,30 +3018,6 @@
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
 
-tcu::Format::Bitfield<32> getResolveModeFlagsKHRStr (VkResolveModeFlagsKHR value)
-{
-	static const tcu::Format::BitDesc s_desc[] =
-	{
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_NONE_KHR,					"VK_RESOLVE_MODE_NONE_KHR"),
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,		"VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR"),
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_AVERAGE_BIT_KHR,			"VK_RESOLVE_MODE_AVERAGE_BIT_KHR"),
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_MIN_BIT_KHR,				"VK_RESOLVE_MODE_MIN_BIT_KHR"),
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_MAX_BIT_KHR,				"VK_RESOLVE_MODE_MAX_BIT_KHR"),
-		tcu::Format::BitDesc(VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR,	"VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR"),
-	};
-	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
-}
-
-tcu::Format::Bitfield<32> getSemaphoreWaitFlagsKHRStr (VkSemaphoreWaitFlagsKHR value)
-{
-	static const tcu::Format::BitDesc s_desc[] =
-	{
-		tcu::Format::BitDesc(VK_SEMAPHORE_WAIT_ANY_BIT_KHR,				"VK_SEMAPHORE_WAIT_ANY_BIT_KHR"),
-		tcu::Format::BitDesc(VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM_KHR,	"VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM_KHR"),
-	};
-	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
-}
-
 tcu::Format::Bitfield<32> getDebugReportFlagsEXTStr (VkDebugReportFlagsEXT value)
 {
 	static const tcu::Format::BitDesc s_desc[] =
@@ -3088,19 +3126,6 @@
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
 
-tcu::Format::Bitfield<32> getDescriptorBindingFlagsEXTStr (VkDescriptorBindingFlagsEXT value)
-{
-	static const tcu::Format::BitDesc s_desc[] =
-	{
-		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT,			"VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT"),
-		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT,	"VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT"),
-		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT,				"VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT"),
-		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT,	"VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT"),
-		tcu::Format::BitDesc(VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT,				"VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT"),
-	};
-	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
-}
-
 tcu::Format::Bitfield<32> getGeometryFlagsNVStr (VkGeometryFlagsNV value)
 {
 	static const tcu::Format::BitDesc s_desc[] =
@@ -3169,6 +3194,22 @@
 	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
 
+tcu::Format::Bitfield<32> getToolPurposeFlagsEXTStr (VkToolPurposeFlagsEXT value)
+{
+	static const tcu::Format::BitDesc s_desc[] =
+	{
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_VALIDATION_BIT_EXT,			"VK_TOOL_PURPOSE_VALIDATION_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_PROFILING_BIT_EXT,				"VK_TOOL_PURPOSE_PROFILING_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_TRACING_BIT_EXT,				"VK_TOOL_PURPOSE_TRACING_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT,	"VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT,	"VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT,		"VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT,			"VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT"),
+		tcu::Format::BitDesc(VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT,		"VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT"),
+	};
+	return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
+}
+
 tcu::Format::Bitfield<32> getInstanceCreateFlagsStr (VkInstanceCreateFlags value)
 {
 	return tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);
@@ -5676,6 +5717,767 @@
 	return s;
 }
 
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkan11Features& value)
+{
+	s << "VkPhysicalDeviceVulkan11Features = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
+	s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
+	s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
+	s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
+	s << "\tmultiview = " << value.multiview << '\n';
+	s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
+	s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
+	s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
+	s << "\tvariablePointers = " << value.variablePointers << '\n';
+	s << "\tprotectedMemory = " << value.protectedMemory << '\n';
+	s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
+	s << "\tshaderDrawParameters = " << value.shaderDrawParameters << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkan11Properties& value)
+{
+	s << "VkPhysicalDeviceVulkan11Properties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
+	s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
+	s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
+	s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
+	s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
+	s << "\tsubgroupSize = " << value.subgroupSize << '\n';
+	s << "\tsubgroupSupportedStages = " << getShaderStageFlagsStr(value.subgroupSupportedStages) << '\n';
+	s << "\tsubgroupSupportedOperations = " << getSubgroupFeatureFlagsStr(value.subgroupSupportedOperations) << '\n';
+	s << "\tsubgroupQuadOperationsInAllStages = " << value.subgroupQuadOperationsInAllStages << '\n';
+	s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
+	s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
+	s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
+	s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
+	s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
+	s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkan12Features& value)
+{
+	s << "VkPhysicalDeviceVulkan12Features = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tsamplerMirrorClampToEdge = " << value.samplerMirrorClampToEdge << '\n';
+	s << "\tdrawIndirectCount = " << value.drawIndirectCount << '\n';
+	s << "\tstorageBuffer8BitAccess = " << value.storageBuffer8BitAccess << '\n';
+	s << "\tuniformAndStorageBuffer8BitAccess = " << value.uniformAndStorageBuffer8BitAccess << '\n';
+	s << "\tstoragePushConstant8 = " << value.storagePushConstant8 << '\n';
+	s << "\tshaderBufferInt64Atomics = " << value.shaderBufferInt64Atomics << '\n';
+	s << "\tshaderSharedInt64Atomics = " << value.shaderSharedInt64Atomics << '\n';
+	s << "\tshaderFloat16 = " << value.shaderFloat16 << '\n';
+	s << "\tshaderInt8 = " << value.shaderInt8 << '\n';
+	s << "\tdescriptorIndexing = " << value.descriptorIndexing << '\n';
+	s << "\tshaderInputAttachmentArrayDynamicIndexing = " << value.shaderInputAttachmentArrayDynamicIndexing << '\n';
+	s << "\tshaderUniformTexelBufferArrayDynamicIndexing = " << value.shaderUniformTexelBufferArrayDynamicIndexing << '\n';
+	s << "\tshaderStorageTexelBufferArrayDynamicIndexing = " << value.shaderStorageTexelBufferArrayDynamicIndexing << '\n';
+	s << "\tshaderUniformBufferArrayNonUniformIndexing = " << value.shaderUniformBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderSampledImageArrayNonUniformIndexing = " << value.shaderSampledImageArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageBufferArrayNonUniformIndexing = " << value.shaderStorageBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageImageArrayNonUniformIndexing = " << value.shaderStorageImageArrayNonUniformIndexing << '\n';
+	s << "\tshaderInputAttachmentArrayNonUniformIndexing = " << value.shaderInputAttachmentArrayNonUniformIndexing << '\n';
+	s << "\tshaderUniformTexelBufferArrayNonUniformIndexing = " << value.shaderUniformTexelBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageTexelBufferArrayNonUniformIndexing = " << value.shaderStorageTexelBufferArrayNonUniformIndexing << '\n';
+	s << "\tdescriptorBindingUniformBufferUpdateAfterBind = " << value.descriptorBindingUniformBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingSampledImageUpdateAfterBind = " << value.descriptorBindingSampledImageUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageImageUpdateAfterBind = " << value.descriptorBindingStorageImageUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageBufferUpdateAfterBind = " << value.descriptorBindingStorageBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingUniformTexelBufferUpdateAfterBind = " << value.descriptorBindingUniformTexelBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageTexelBufferUpdateAfterBind = " << value.descriptorBindingStorageTexelBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingUpdateUnusedWhilePending = " << value.descriptorBindingUpdateUnusedWhilePending << '\n';
+	s << "\tdescriptorBindingPartiallyBound = " << value.descriptorBindingPartiallyBound << '\n';
+	s << "\tdescriptorBindingVariableDescriptorCount = " << value.descriptorBindingVariableDescriptorCount << '\n';
+	s << "\truntimeDescriptorArray = " << value.runtimeDescriptorArray << '\n';
+	s << "\tsamplerFilterMinmax = " << value.samplerFilterMinmax << '\n';
+	s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
+	s << "\timagelessFramebuffer = " << value.imagelessFramebuffer << '\n';
+	s << "\tuniformBufferStandardLayout = " << value.uniformBufferStandardLayout << '\n';
+	s << "\tshaderSubgroupExtendedTypes = " << value.shaderSubgroupExtendedTypes << '\n';
+	s << "\tseparateDepthStencilLayouts = " << value.separateDepthStencilLayouts << '\n';
+	s << "\thostQueryReset = " << value.hostQueryReset << '\n';
+	s << "\ttimelineSemaphore = " << value.timelineSemaphore << '\n';
+	s << "\tbufferDeviceAddress = " << value.bufferDeviceAddress << '\n';
+	s << "\tbufferDeviceAddressCaptureReplay = " << value.bufferDeviceAddressCaptureReplay << '\n';
+	s << "\tbufferDeviceAddressMultiDevice = " << value.bufferDeviceAddressMultiDevice << '\n';
+	s << "\tvulkanMemoryModel = " << value.vulkanMemoryModel << '\n';
+	s << "\tvulkanMemoryModelDeviceScope = " << value.vulkanMemoryModelDeviceScope << '\n';
+	s << "\tvulkanMemoryModelAvailabilityVisibilityChains = " << value.vulkanMemoryModelAvailabilityVisibilityChains << '\n';
+	s << "\tshaderOutputViewportIndex = " << value.shaderOutputViewportIndex << '\n';
+	s << "\tshaderOutputLayer = " << value.shaderOutputLayer << '\n';
+	s << "\tsubgroupBroadcastDynamicId = " << value.subgroupBroadcastDynamicId << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkConformanceVersion& value)
+{
+	s << "VkConformanceVersion = {\n";
+	s << "\tmajor = " << value.major << '\n';
+	s << "\tminor = " << value.minor << '\n';
+	s << "\tsubminor = " << value.subminor << '\n';
+	s << "\tpatch = " << value.patch << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkan12Properties& value)
+{
+	s << "VkPhysicalDeviceVulkan12Properties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdriverID = " << value.driverID << '\n';
+	s << "\tdriverName = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverName)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverName))) << '\n';
+	s << "\tdriverInfo = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverInfo)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverInfo))) << '\n';
+	s << "\tconformanceVersion = " << value.conformanceVersion << '\n';
+	s << "\tdenormBehaviorIndependence = " << value.denormBehaviorIndependence << '\n';
+	s << "\troundingModeIndependence = " << value.roundingModeIndependence << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
+	s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
+	s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
+	s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
+	s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
+	s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
+	s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
+	s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
+	s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
+	s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
+	s << "\tmaxUpdateAfterBindDescriptorsInAllPools = " << value.maxUpdateAfterBindDescriptorsInAllPools << '\n';
+	s << "\tshaderUniformBufferArrayNonUniformIndexingNative = " << value.shaderUniformBufferArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderSampledImageArrayNonUniformIndexingNative = " << value.shaderSampledImageArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderStorageBufferArrayNonUniformIndexingNative = " << value.shaderStorageBufferArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderStorageImageArrayNonUniformIndexingNative = " << value.shaderStorageImageArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderInputAttachmentArrayNonUniformIndexingNative = " << value.shaderInputAttachmentArrayNonUniformIndexingNative << '\n';
+	s << "\trobustBufferAccessUpdateAfterBind = " << value.robustBufferAccessUpdateAfterBind << '\n';
+	s << "\tquadDivergentImplicitLod = " << value.quadDivergentImplicitLod << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindSamplers = " << value.maxPerStageDescriptorUpdateAfterBindSamplers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindUniformBuffers = " << value.maxPerStageDescriptorUpdateAfterBindUniformBuffers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageBuffers = " << value.maxPerStageDescriptorUpdateAfterBindStorageBuffers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindSampledImages = " << value.maxPerStageDescriptorUpdateAfterBindSampledImages << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageImages = " << value.maxPerStageDescriptorUpdateAfterBindStorageImages << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindInputAttachments = " << value.maxPerStageDescriptorUpdateAfterBindInputAttachments << '\n';
+	s << "\tmaxPerStageUpdateAfterBindResources = " << value.maxPerStageUpdateAfterBindResources << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindSamplers = " << value.maxDescriptorSetUpdateAfterBindSamplers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffers = " << value.maxDescriptorSetUpdateAfterBindUniformBuffers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffers = " << value.maxDescriptorSetUpdateAfterBindStorageBuffers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindSampledImages = " << value.maxDescriptorSetUpdateAfterBindSampledImages << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageImages = " << value.maxDescriptorSetUpdateAfterBindStorageImages << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindInputAttachments = " << value.maxDescriptorSetUpdateAfterBindInputAttachments << '\n';
+	s << "\tsupportedDepthResolveModes = " << getResolveModeFlagsStr(value.supportedDepthResolveModes) << '\n';
+	s << "\tsupportedStencilResolveModes = " << getResolveModeFlagsStr(value.supportedStencilResolveModes) << '\n';
+	s << "\tindependentResolveNone = " << value.independentResolveNone << '\n';
+	s << "\tindependentResolve = " << value.independentResolve << '\n';
+	s << "\tfilterMinmaxSingleComponentFormats = " << value.filterMinmaxSingleComponentFormats << '\n';
+	s << "\tfilterMinmaxImageComponentMapping = " << value.filterMinmaxImageComponentMapping << '\n';
+	s << "\tmaxTimelineSemaphoreValueDifference = " << value.maxTimelineSemaphoreValueDifference << '\n';
+	s << "\tframebufferIntegerColorSampleCounts = " << getSampleCountFlagsStr(value.framebufferIntegerColorSampleCounts) << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkImageFormatListCreateInfo& value)
+{
+	s << "VkImageFormatListCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tviewFormatCount = " << value.viewFormatCount << '\n';
+	s << "\tpViewFormats = " << value.pViewFormats << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkAttachmentDescription2& value)
+{
+	s << "VkAttachmentDescription2 = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tflags = " << getAttachmentDescriptionFlagsStr(value.flags) << '\n';
+	s << "\tformat = " << value.format << '\n';
+	s << "\tsamples = " << value.samples << '\n';
+	s << "\tloadOp = " << value.loadOp << '\n';
+	s << "\tstoreOp = " << value.storeOp << '\n';
+	s << "\tstencilLoadOp = " << value.stencilLoadOp << '\n';
+	s << "\tstencilStoreOp = " << value.stencilStoreOp << '\n';
+	s << "\tinitialLayout = " << value.initialLayout << '\n';
+	s << "\tfinalLayout = " << value.finalLayout << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkAttachmentReference2& value)
+{
+	s << "VkAttachmentReference2 = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tattachment = " << value.attachment << '\n';
+	s << "\tlayout = " << value.layout << '\n';
+	s << "\taspectMask = " << getImageAspectFlagsStr(value.aspectMask) << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSubpassDescription2& value)
+{
+	s << "VkSubpassDescription2 = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tflags = " << getSubpassDescriptionFlagsStr(value.flags) << '\n';
+	s << "\tpipelineBindPoint = " << value.pipelineBindPoint << '\n';
+	s << "\tviewMask = " << value.viewMask << '\n';
+	s << "\tinputAttachmentCount = " << value.inputAttachmentCount << '\n';
+	s << "\tpInputAttachments = " << value.pInputAttachments << '\n';
+	s << "\tcolorAttachmentCount = " << value.colorAttachmentCount << '\n';
+	s << "\tpColorAttachments = " << value.pColorAttachments << '\n';
+	s << "\tpResolveAttachments = " << value.pResolveAttachments << '\n';
+	s << "\tpDepthStencilAttachment = " << value.pDepthStencilAttachment << '\n';
+	s << "\tpreserveAttachmentCount = " << value.preserveAttachmentCount << '\n';
+	s << "\tpPreserveAttachments = " << value.pPreserveAttachments << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSubpassDependency2& value)
+{
+	s << "VkSubpassDependency2 = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tsrcSubpass = " << value.srcSubpass << '\n';
+	s << "\tdstSubpass = " << value.dstSubpass << '\n';
+	s << "\tsrcStageMask = " << getPipelineStageFlagsStr(value.srcStageMask) << '\n';
+	s << "\tdstStageMask = " << getPipelineStageFlagsStr(value.dstStageMask) << '\n';
+	s << "\tsrcAccessMask = " << getAccessFlagsStr(value.srcAccessMask) << '\n';
+	s << "\tdstAccessMask = " << getAccessFlagsStr(value.dstAccessMask) << '\n';
+	s << "\tdependencyFlags = " << getDependencyFlagsStr(value.dependencyFlags) << '\n';
+	s << "\tviewOffset = " << value.viewOffset << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkRenderPassCreateInfo2& value)
+{
+	s << "VkRenderPassCreateInfo2 = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tflags = " << getRenderPassCreateFlagsStr(value.flags) << '\n';
+	s << "\tattachmentCount = " << value.attachmentCount << '\n';
+	s << "\tpAttachments = " << value.pAttachments << '\n';
+	s << "\tsubpassCount = " << value.subpassCount << '\n';
+	s << "\tpSubpasses = " << value.pSubpasses << '\n';
+	s << "\tdependencyCount = " << value.dependencyCount << '\n';
+	s << "\tpDependencies = " << value.pDependencies << '\n';
+	s << "\tcorrelatedViewMaskCount = " << value.correlatedViewMaskCount << '\n';
+	s << "\tpCorrelatedViewMasks = " << value.pCorrelatedViewMasks << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSubpassBeginInfo& value)
+{
+	s << "VkSubpassBeginInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tcontents = " << value.contents << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSubpassEndInfo& value)
+{
+	s << "VkSubpassEndInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDevice8BitStorageFeatures& value)
+{
+	s << "VkPhysicalDevice8BitStorageFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tstorageBuffer8BitAccess = " << value.storageBuffer8BitAccess << '\n';
+	s << "\tuniformAndStorageBuffer8BitAccess = " << value.uniformAndStorageBuffer8BitAccess << '\n';
+	s << "\tstoragePushConstant8 = " << value.storagePushConstant8 << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDriverProperties& value)
+{
+	s << "VkPhysicalDeviceDriverProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdriverID = " << value.driverID << '\n';
+	s << "\tdriverName = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverName)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverName))) << '\n';
+	s << "\tdriverInfo = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverInfo)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverInfo))) << '\n';
+	s << "\tconformanceVersion = " << value.conformanceVersion << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderAtomicInt64Features& value)
+{
+	s << "VkPhysicalDeviceShaderAtomicInt64Features = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tshaderBufferInt64Atomics = " << value.shaderBufferInt64Atomics << '\n';
+	s << "\tshaderSharedInt64Atomics = " << value.shaderSharedInt64Atomics << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderFloat16Int8Features& value)
+{
+	s << "VkPhysicalDeviceShaderFloat16Int8Features = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tshaderFloat16 = " << value.shaderFloat16 << '\n';
+	s << "\tshaderInt8 = " << value.shaderInt8 << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceFloatControlsProperties& value)
+{
+	s << "VkPhysicalDeviceFloatControlsProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdenormBehaviorIndependence = " << value.denormBehaviorIndependence << '\n';
+	s << "\troundingModeIndependence = " << value.roundingModeIndependence << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
+	s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
+	s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
+	s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
+	s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
+	s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
+	s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
+	s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
+	s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
+	s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
+	s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
+	s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkDescriptorSetLayoutBindingFlagsCreateInfo& value)
+{
+	s << "VkDescriptorSetLayoutBindingFlagsCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tbindingCount = " << value.bindingCount << '\n';
+	s << "\tpBindingFlags = " << value.pBindingFlags << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDescriptorIndexingFeatures& value)
+{
+	s << "VkPhysicalDeviceDescriptorIndexingFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tshaderInputAttachmentArrayDynamicIndexing = " << value.shaderInputAttachmentArrayDynamicIndexing << '\n';
+	s << "\tshaderUniformTexelBufferArrayDynamicIndexing = " << value.shaderUniformTexelBufferArrayDynamicIndexing << '\n';
+	s << "\tshaderStorageTexelBufferArrayDynamicIndexing = " << value.shaderStorageTexelBufferArrayDynamicIndexing << '\n';
+	s << "\tshaderUniformBufferArrayNonUniformIndexing = " << value.shaderUniformBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderSampledImageArrayNonUniformIndexing = " << value.shaderSampledImageArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageBufferArrayNonUniformIndexing = " << value.shaderStorageBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageImageArrayNonUniformIndexing = " << value.shaderStorageImageArrayNonUniformIndexing << '\n';
+	s << "\tshaderInputAttachmentArrayNonUniformIndexing = " << value.shaderInputAttachmentArrayNonUniformIndexing << '\n';
+	s << "\tshaderUniformTexelBufferArrayNonUniformIndexing = " << value.shaderUniformTexelBufferArrayNonUniformIndexing << '\n';
+	s << "\tshaderStorageTexelBufferArrayNonUniformIndexing = " << value.shaderStorageTexelBufferArrayNonUniformIndexing << '\n';
+	s << "\tdescriptorBindingUniformBufferUpdateAfterBind = " << value.descriptorBindingUniformBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingSampledImageUpdateAfterBind = " << value.descriptorBindingSampledImageUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageImageUpdateAfterBind = " << value.descriptorBindingStorageImageUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageBufferUpdateAfterBind = " << value.descriptorBindingStorageBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingUniformTexelBufferUpdateAfterBind = " << value.descriptorBindingUniformTexelBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingStorageTexelBufferUpdateAfterBind = " << value.descriptorBindingStorageTexelBufferUpdateAfterBind << '\n';
+	s << "\tdescriptorBindingUpdateUnusedWhilePending = " << value.descriptorBindingUpdateUnusedWhilePending << '\n';
+	s << "\tdescriptorBindingPartiallyBound = " << value.descriptorBindingPartiallyBound << '\n';
+	s << "\tdescriptorBindingVariableDescriptorCount = " << value.descriptorBindingVariableDescriptorCount << '\n';
+	s << "\truntimeDescriptorArray = " << value.runtimeDescriptorArray << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDescriptorIndexingProperties& value)
+{
+	s << "VkPhysicalDeviceDescriptorIndexingProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tmaxUpdateAfterBindDescriptorsInAllPools = " << value.maxUpdateAfterBindDescriptorsInAllPools << '\n';
+	s << "\tshaderUniformBufferArrayNonUniformIndexingNative = " << value.shaderUniformBufferArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderSampledImageArrayNonUniformIndexingNative = " << value.shaderSampledImageArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderStorageBufferArrayNonUniformIndexingNative = " << value.shaderStorageBufferArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderStorageImageArrayNonUniformIndexingNative = " << value.shaderStorageImageArrayNonUniformIndexingNative << '\n';
+	s << "\tshaderInputAttachmentArrayNonUniformIndexingNative = " << value.shaderInputAttachmentArrayNonUniformIndexingNative << '\n';
+	s << "\trobustBufferAccessUpdateAfterBind = " << value.robustBufferAccessUpdateAfterBind << '\n';
+	s << "\tquadDivergentImplicitLod = " << value.quadDivergentImplicitLod << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindSamplers = " << value.maxPerStageDescriptorUpdateAfterBindSamplers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindUniformBuffers = " << value.maxPerStageDescriptorUpdateAfterBindUniformBuffers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageBuffers = " << value.maxPerStageDescriptorUpdateAfterBindStorageBuffers << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindSampledImages = " << value.maxPerStageDescriptorUpdateAfterBindSampledImages << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageImages = " << value.maxPerStageDescriptorUpdateAfterBindStorageImages << '\n';
+	s << "\tmaxPerStageDescriptorUpdateAfterBindInputAttachments = " << value.maxPerStageDescriptorUpdateAfterBindInputAttachments << '\n';
+	s << "\tmaxPerStageUpdateAfterBindResources = " << value.maxPerStageUpdateAfterBindResources << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindSamplers = " << value.maxDescriptorSetUpdateAfterBindSamplers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffers = " << value.maxDescriptorSetUpdateAfterBindUniformBuffers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffers = " << value.maxDescriptorSetUpdateAfterBindStorageBuffers << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindSampledImages = " << value.maxDescriptorSetUpdateAfterBindSampledImages << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindStorageImages = " << value.maxDescriptorSetUpdateAfterBindStorageImages << '\n';
+	s << "\tmaxDescriptorSetUpdateAfterBindInputAttachments = " << value.maxDescriptorSetUpdateAfterBindInputAttachments << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkDescriptorSetVariableDescriptorCountAllocateInfo& value)
+{
+	s << "VkDescriptorSetVariableDescriptorCountAllocateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdescriptorSetCount = " << value.descriptorSetCount << '\n';
+	s << "\tpDescriptorCounts = " << value.pDescriptorCounts << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkDescriptorSetVariableDescriptorCountLayoutSupport& value)
+{
+	s << "VkDescriptorSetVariableDescriptorCountLayoutSupport = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tmaxVariableDescriptorCount = " << value.maxVariableDescriptorCount << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSubpassDescriptionDepthStencilResolve& value)
+{
+	s << "VkSubpassDescriptionDepthStencilResolve = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tdepthResolveMode = " << value.depthResolveMode << '\n';
+	s << "\tstencilResolveMode = " << value.stencilResolveMode << '\n';
+	s << "\tpDepthStencilResolveAttachment = " << value.pDepthStencilResolveAttachment << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDepthStencilResolveProperties& value)
+{
+	s << "VkPhysicalDeviceDepthStencilResolveProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tsupportedDepthResolveModes = " << getResolveModeFlagsStr(value.supportedDepthResolveModes) << '\n';
+	s << "\tsupportedStencilResolveModes = " << getResolveModeFlagsStr(value.supportedStencilResolveModes) << '\n';
+	s << "\tindependentResolveNone = " << value.independentResolveNone << '\n';
+	s << "\tindependentResolve = " << value.independentResolve << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceScalarBlockLayoutFeatures& value)
+{
+	s << "VkPhysicalDeviceScalarBlockLayoutFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkImageStencilUsageCreateInfo& value)
+{
+	s << "VkImageStencilUsageCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tstencilUsage = " << getImageUsageFlagsStr(value.stencilUsage) << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSamplerReductionModeCreateInfo& value)
+{
+	s << "VkSamplerReductionModeCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\treductionMode = " << value.reductionMode << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceSamplerFilterMinmaxProperties& value)
+{
+	s << "VkPhysicalDeviceSamplerFilterMinmaxProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tfilterMinmaxSingleComponentFormats = " << value.filterMinmaxSingleComponentFormats << '\n';
+	s << "\tfilterMinmaxImageComponentMapping = " << value.filterMinmaxImageComponentMapping << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkanMemoryModelFeatures& value)
+{
+	s << "VkPhysicalDeviceVulkanMemoryModelFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tvulkanMemoryModel = " << value.vulkanMemoryModel << '\n';
+	s << "\tvulkanMemoryModelDeviceScope = " << value.vulkanMemoryModelDeviceScope << '\n';
+	s << "\tvulkanMemoryModelAvailabilityVisibilityChains = " << value.vulkanMemoryModelAvailabilityVisibilityChains << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeatures& value)
+{
+	s << "VkPhysicalDeviceImagelessFramebufferFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\timagelessFramebuffer = " << value.imagelessFramebuffer << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentImageInfo& value)
+{
+	s << "VkFramebufferAttachmentImageInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tflags = " << getImageCreateFlagsStr(value.flags) << '\n';
+	s << "\tusage = " << getImageUsageFlagsStr(value.usage) << '\n';
+	s << "\twidth = " << value.width << '\n';
+	s << "\theight = " << value.height << '\n';
+	s << "\tlayerCount = " << value.layerCount << '\n';
+	s << "\tviewFormatCount = " << value.viewFormatCount << '\n';
+	s << "\tpViewFormats = " << value.pViewFormats << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentsCreateInfo& value)
+{
+	s << "VkFramebufferAttachmentsCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tattachmentImageInfoCount = " << value.attachmentImageInfoCount << '\n';
+	s << "\tpAttachmentImageInfos = " << value.pAttachmentImageInfos << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkRenderPassAttachmentBeginInfo& value)
+{
+	s << "VkRenderPassAttachmentBeginInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tattachmentCount = " << value.attachmentCount << '\n';
+	s << "\tpAttachments = " << value.pAttachments << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceUniformBufferStandardLayoutFeatures& value)
+{
+	s << "VkPhysicalDeviceUniformBufferStandardLayoutFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tuniformBufferStandardLayout = " << value.uniformBufferStandardLayout << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures& value)
+{
+	s << "VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tshaderSubgroupExtendedTypes = " << value.shaderSubgroupExtendedTypes << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures& value)
+{
+	s << "VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tseparateDepthStencilLayouts = " << value.separateDepthStencilLayouts << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkAttachmentReferenceStencilLayout& value)
+{
+	s << "VkAttachmentReferenceStencilLayout = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tstencilLayout = " << value.stencilLayout << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkAttachmentDescriptionStencilLayout& value)
+{
+	s << "VkAttachmentDescriptionStencilLayout = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tstencilInitialLayout = " << value.stencilInitialLayout << '\n';
+	s << "\tstencilFinalLayout = " << value.stencilFinalLayout << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceHostQueryResetFeatures& value)
+{
+	s << "VkPhysicalDeviceHostQueryResetFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\thostQueryReset = " << value.hostQueryReset << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreFeatures& value)
+{
+	s << "VkPhysicalDeviceTimelineSemaphoreFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\ttimelineSemaphore = " << value.timelineSemaphore << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreProperties& value)
+{
+	s << "VkPhysicalDeviceTimelineSemaphoreProperties = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tmaxTimelineSemaphoreValueDifference = " << value.maxTimelineSemaphoreValueDifference << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSemaphoreTypeCreateInfo& value)
+{
+	s << "VkSemaphoreTypeCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tsemaphoreType = " << value.semaphoreType << '\n';
+	s << "\tinitialValue = " << value.initialValue << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkTimelineSemaphoreSubmitInfo& value)
+{
+	s << "VkTimelineSemaphoreSubmitInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\twaitSemaphoreValueCount = " << value.waitSemaphoreValueCount << '\n';
+	s << "\tpWaitSemaphoreValues = " << value.pWaitSemaphoreValues << '\n';
+	s << "\tsignalSemaphoreValueCount = " << value.signalSemaphoreValueCount << '\n';
+	s << "\tpSignalSemaphoreValues = " << value.pSignalSemaphoreValues << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSemaphoreWaitInfo& value)
+{
+	s << "VkSemaphoreWaitInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tflags = " << getSemaphoreWaitFlagsStr(value.flags) << '\n';
+	s << "\tsemaphoreCount = " << value.semaphoreCount << '\n';
+	s << "\tpSemaphores = " << value.pSemaphores << '\n';
+	s << "\tpValues = " << value.pValues << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkSemaphoreSignalInfo& value)
+{
+	s << "VkSemaphoreSignalInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tsemaphore = " << value.semaphore << '\n';
+	s << "\tvalue = " << value.value << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceBufferDeviceAddressFeatures& value)
+{
+	s << "VkPhysicalDeviceBufferDeviceAddressFeatures = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tbufferDeviceAddress = " << value.bufferDeviceAddress << '\n';
+	s << "\tbufferDeviceAddressCaptureReplay = " << value.bufferDeviceAddressCaptureReplay << '\n';
+	s << "\tbufferDeviceAddressMultiDevice = " << value.bufferDeviceAddressMultiDevice << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkBufferDeviceAddressInfo& value)
+{
+	s << "VkBufferDeviceAddressInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tbuffer = " << value.buffer << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkBufferOpaqueCaptureAddressCreateInfo& value)
+{
+	s << "VkBufferOpaqueCaptureAddressCreateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\topaqueCaptureAddress = " << value.opaqueCaptureAddress << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkMemoryOpaqueCaptureAddressAllocateInfo& value)
+{
+	s << "VkMemoryOpaqueCaptureAddressAllocateInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\topaqueCaptureAddress = " << value.opaqueCaptureAddress << '\n';
+	s << '}';
+	return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkDeviceMemoryOpaqueCaptureAddressInfo& value)
+{
+	s << "VkDeviceMemoryOpaqueCaptureAddressInfo = {\n";
+	s << "\tsType = " << value.sType << '\n';
+	s << "\tpNext = " << value.pNext << '\n';
+	s << "\tmemory = " << value.memory << '\n';
+	s << '}';
+	return s;
+}
+
 std::ostream& operator<< (std::ostream& s, const VkSurfaceCapabilitiesKHR& value)
 {
 	s << "VkSurfaceCapabilitiesKHR = {\n";
@@ -5973,17 +6775,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderFloat16Int8FeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceShaderFloat16Int8FeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tshaderFloat16 = " << value.shaderFloat16 << '\n';
-	s << "\tshaderInt8 = " << value.shaderInt8 << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkRectLayerKHR& value)
 {
 	s << "VkRectLayerKHR = {\n";
@@ -6014,158 +6805,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceImagelessFramebufferFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\timagelessFramebuffer = " << value.imagelessFramebuffer << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentImageInfoKHR& value)
-{
-	s << "VkFramebufferAttachmentImageInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tflags = " << getImageCreateFlagsStr(value.flags) << '\n';
-	s << "\tusage = " << getImageUsageFlagsStr(value.usage) << '\n';
-	s << "\twidth = " << value.width << '\n';
-	s << "\theight = " << value.height << '\n';
-	s << "\tlayerCount = " << value.layerCount << '\n';
-	s << "\tviewFormatCount = " << value.viewFormatCount << '\n';
-	s << "\tpViewFormats = " << value.pViewFormats << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentsCreateInfoKHR& value)
-{
-	s << "VkFramebufferAttachmentsCreateInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tattachmentImageInfoCount = " << value.attachmentImageInfoCount << '\n';
-	s << "\tpAttachmentImageInfos = " << value.pAttachmentImageInfos << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkRenderPassAttachmentBeginInfoKHR& value)
-{
-	s << "VkRenderPassAttachmentBeginInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tattachmentCount = " << value.attachmentCount << '\n';
-	s << "\tpAttachments = " << value.pAttachments << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkAttachmentDescription2KHR& value)
-{
-	s << "VkAttachmentDescription2KHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tflags = " << getAttachmentDescriptionFlagsStr(value.flags) << '\n';
-	s << "\tformat = " << value.format << '\n';
-	s << "\tsamples = " << value.samples << '\n';
-	s << "\tloadOp = " << value.loadOp << '\n';
-	s << "\tstoreOp = " << value.storeOp << '\n';
-	s << "\tstencilLoadOp = " << value.stencilLoadOp << '\n';
-	s << "\tstencilStoreOp = " << value.stencilStoreOp << '\n';
-	s << "\tinitialLayout = " << value.initialLayout << '\n';
-	s << "\tfinalLayout = " << value.finalLayout << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkAttachmentReference2KHR& value)
-{
-	s << "VkAttachmentReference2KHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tattachment = " << value.attachment << '\n';
-	s << "\tlayout = " << value.layout << '\n';
-	s << "\taspectMask = " << getImageAspectFlagsStr(value.aspectMask) << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSubpassDescription2KHR& value)
-{
-	s << "VkSubpassDescription2KHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tflags = " << getSubpassDescriptionFlagsStr(value.flags) << '\n';
-	s << "\tpipelineBindPoint = " << value.pipelineBindPoint << '\n';
-	s << "\tviewMask = " << value.viewMask << '\n';
-	s << "\tinputAttachmentCount = " << value.inputAttachmentCount << '\n';
-	s << "\tpInputAttachments = " << value.pInputAttachments << '\n';
-	s << "\tcolorAttachmentCount = " << value.colorAttachmentCount << '\n';
-	s << "\tpColorAttachments = " << value.pColorAttachments << '\n';
-	s << "\tpResolveAttachments = " << value.pResolveAttachments << '\n';
-	s << "\tpDepthStencilAttachment = " << value.pDepthStencilAttachment << '\n';
-	s << "\tpreserveAttachmentCount = " << value.preserveAttachmentCount << '\n';
-	s << "\tpPreserveAttachments = " << value.pPreserveAttachments << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSubpassDependency2KHR& value)
-{
-	s << "VkSubpassDependency2KHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tsrcSubpass = " << value.srcSubpass << '\n';
-	s << "\tdstSubpass = " << value.dstSubpass << '\n';
-	s << "\tsrcStageMask = " << getPipelineStageFlagsStr(value.srcStageMask) << '\n';
-	s << "\tdstStageMask = " << getPipelineStageFlagsStr(value.dstStageMask) << '\n';
-	s << "\tsrcAccessMask = " << getAccessFlagsStr(value.srcAccessMask) << '\n';
-	s << "\tdstAccessMask = " << getAccessFlagsStr(value.dstAccessMask) << '\n';
-	s << "\tdependencyFlags = " << getDependencyFlagsStr(value.dependencyFlags) << '\n';
-	s << "\tviewOffset = " << value.viewOffset << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkRenderPassCreateInfo2KHR& value)
-{
-	s << "VkRenderPassCreateInfo2KHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tflags = " << getRenderPassCreateFlagsStr(value.flags) << '\n';
-	s << "\tattachmentCount = " << value.attachmentCount << '\n';
-	s << "\tpAttachments = " << value.pAttachments << '\n';
-	s << "\tsubpassCount = " << value.subpassCount << '\n';
-	s << "\tpSubpasses = " << value.pSubpasses << '\n';
-	s << "\tdependencyCount = " << value.dependencyCount << '\n';
-	s << "\tpDependencies = " << value.pDependencies << '\n';
-	s << "\tcorrelatedViewMaskCount = " << value.correlatedViewMaskCount << '\n';
-	s << "\tpCorrelatedViewMasks = " << value.pCorrelatedViewMasks << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSubpassBeginInfoKHR& value)
-{
-	s << "VkSubpassBeginInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tcontents = " << value.contents << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSubpassEndInfoKHR& value)
-{
-	s << "VkSubpassEndInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkSharedPresentSurfaceCapabilitiesKHR& value)
 {
 	s << "VkSharedPresentSurfaceCapabilitiesKHR = {\n";
@@ -6374,50 +7013,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkImageFormatListCreateInfoKHR& value)
-{
-	s << "VkImageFormatListCreateInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tviewFormatCount = " << value.viewFormatCount << '\n';
-	s << "\tpViewFormats = " << value.pViewFormats << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tshaderSubgroupExtendedTypes = " << value.shaderSubgroupExtendedTypes << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDevice8BitStorageFeaturesKHR& value)
-{
-	s << "VkPhysicalDevice8BitStorageFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tstorageBuffer8BitAccess = " << value.storageBuffer8BitAccess << '\n';
-	s << "\tuniformAndStorageBuffer8BitAccess = " << value.uniformAndStorageBuffer8BitAccess << '\n';
-	s << "\tstoragePushConstant8 = " << value.storagePushConstant8 << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceShaderAtomicInt64FeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tshaderBufferInt64Atomics = " << value.shaderBufferInt64Atomics << '\n';
-	s << "\tshaderSharedInt64Atomics = " << value.shaderSharedInt64Atomics << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderClockFeaturesKHR& value)
 {
 	s << "VkPhysicalDeviceShaderClockFeaturesKHR = {\n";
@@ -6429,161 +7024,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkConformanceVersionKHR& value)
-{
-	s << "VkConformanceVersionKHR = {\n";
-	s << "\tmajor = " << value.major << '\n';
-	s << "\tminor = " << value.minor << '\n';
-	s << "\tsubminor = " << value.subminor << '\n';
-	s << "\tpatch = " << value.patch << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDriverPropertiesKHR& value)
-{
-	s << "VkPhysicalDeviceDriverPropertiesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tdriverID = " << value.driverID << '\n';
-	s << "\tdriverName = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverName)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverName))) << '\n';
-	s << "\tdriverInfo = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.driverInfo)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.driverInfo))) << '\n';
-	s << "\tconformanceVersion = " << value.conformanceVersion << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceFloatControlsPropertiesKHR& value)
-{
-	s << "VkPhysicalDeviceFloatControlsPropertiesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tdenormBehaviorIndependence = " << value.denormBehaviorIndependence << '\n';
-	s << "\troundingModeIndependence = " << value.roundingModeIndependence << '\n';
-	s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
-	s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
-	s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
-	s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
-	s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
-	s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
-	s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
-	s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
-	s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
-	s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
-	s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
-	s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
-	s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
-	s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
-	s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSubpassDescriptionDepthStencilResolveKHR& value)
-{
-	s << "VkSubpassDescriptionDepthStencilResolveKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tdepthResolveMode = " << value.depthResolveMode << '\n';
-	s << "\tstencilResolveMode = " << value.stencilResolveMode << '\n';
-	s << "\tpDepthStencilResolveAttachment = " << value.pDepthStencilResolveAttachment << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDepthStencilResolvePropertiesKHR& value)
-{
-	s << "VkPhysicalDeviceDepthStencilResolvePropertiesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tsupportedDepthResolveModes = " << getResolveModeFlagsKHRStr(value.supportedDepthResolveModes) << '\n';
-	s << "\tsupportedStencilResolveModes = " << getResolveModeFlagsKHRStr(value.supportedStencilResolveModes) << '\n';
-	s << "\tindependentResolveNone = " << value.independentResolveNone << '\n';
-	s << "\tindependentResolve = " << value.independentResolve << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceTimelineSemaphoreFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceTimelineSemaphoreFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\ttimelineSemaphore = " << value.timelineSemaphore << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceTimelineSemaphorePropertiesKHR& value)
-{
-	s << "VkPhysicalDeviceTimelineSemaphorePropertiesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tmaxTimelineSemaphoreValueDifference = " << value.maxTimelineSemaphoreValueDifference << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSemaphoreTypeCreateInfoKHR& value)
-{
-	s << "VkSemaphoreTypeCreateInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tsemaphoreType = " << value.semaphoreType << '\n';
-	s << "\tinitialValue = " << value.initialValue << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkTimelineSemaphoreSubmitInfoKHR& value)
-{
-	s << "VkTimelineSemaphoreSubmitInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\twaitSemaphoreValueCount = " << value.waitSemaphoreValueCount << '\n';
-	s << "\tpWaitSemaphoreValues = " << value.pWaitSemaphoreValues << '\n';
-	s << "\tsignalSemaphoreValueCount = " << value.signalSemaphoreValueCount << '\n';
-	s << "\tpSignalSemaphoreValues = " << value.pSignalSemaphoreValues << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSemaphoreWaitInfoKHR& value)
-{
-	s << "VkSemaphoreWaitInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tflags = " << getSemaphoreWaitFlagsKHRStr(value.flags) << '\n';
-	s << "\tsemaphoreCount = " << value.semaphoreCount << '\n';
-	s << "\tpSemaphores = " << value.pSemaphores << '\n';
-	s << "\tpValues = " << value.pValues << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkSemaphoreSignalInfoKHR& value)
-{
-	s << "VkSemaphoreSignalInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tsemaphore = " << value.semaphore << '\n';
-	s << "\tvalue = " << value.value << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceVulkanMemoryModelFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tvulkanMemoryModel = " << value.vulkanMemoryModel << '\n';
-	s << "\tvulkanMemoryModelDeviceScope = " << value.vulkanMemoryModelDeviceScope << '\n';
-	s << "\tvulkanMemoryModelAvailabilityVisibilityChains = " << value.vulkanMemoryModelAvailabilityVisibilityChains << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkSurfaceProtectedCapabilitiesKHR& value)
 {
 	s << "VkSurfaceProtectedCapabilitiesKHR = {\n";
@@ -6594,99 +7034,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tseparateDepthStencilLayouts = " << value.separateDepthStencilLayouts << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkAttachmentReferenceStencilLayoutKHR& value)
-{
-	s << "VkAttachmentReferenceStencilLayoutKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tstencilLayout = " << value.stencilLayout << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkAttachmentDescriptionStencilLayoutKHR& value)
-{
-	s << "VkAttachmentDescriptionStencilLayoutKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tstencilInitialLayout = " << value.stencilInitialLayout << '\n';
-	s << "\tstencilFinalLayout = " << value.stencilFinalLayout << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tuniformBufferStandardLayout = " << value.uniformBufferStandardLayout << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceBufferDeviceAddressFeaturesKHR& value)
-{
-	s << "VkPhysicalDeviceBufferDeviceAddressFeaturesKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tbufferDeviceAddress = " << value.bufferDeviceAddress << '\n';
-	s << "\tbufferDeviceAddressCaptureReplay = " << value.bufferDeviceAddressCaptureReplay << '\n';
-	s << "\tbufferDeviceAddressMultiDevice = " << value.bufferDeviceAddressMultiDevice << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkBufferDeviceAddressInfoKHR& value)
-{
-	s << "VkBufferDeviceAddressInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tbuffer = " << value.buffer << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkBufferOpaqueCaptureAddressCreateInfoKHR& value)
-{
-	s << "VkBufferOpaqueCaptureAddressCreateInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\topaqueCaptureAddress = " << value.opaqueCaptureAddress << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkMemoryOpaqueCaptureAddressAllocateInfoKHR& value)
-{
-	s << "VkMemoryOpaqueCaptureAddressAllocateInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\topaqueCaptureAddress = " << value.opaqueCaptureAddress << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR& value)
-{
-	s << "VkDeviceMemoryOpaqueCaptureAddressInfoKHR = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tmemory = " << value.memory << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR& value)
 {
 	s << "VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR = {\n";
@@ -7556,27 +7903,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkSamplerReductionModeCreateInfoEXT& value)
-{
-	s << "VkSamplerReductionModeCreateInfoEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\treductionMode = " << value.reductionMode << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT& value)
-{
-	s << "VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tfilterMinmaxSingleComponentFormats = " << value.filterMinmaxSingleComponentFormats << '\n';
-	s << "\tfilterMinmaxImageComponentMapping = " << value.filterMinmaxImageComponentMapping << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceInlineUniformBlockFeaturesEXT& value)
 {
 	s << "VkPhysicalDeviceInlineUniformBlockFeaturesEXT = {\n";
@@ -7884,99 +8210,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT& value)
-{
-	s << "VkDescriptorSetLayoutBindingFlagsCreateInfoEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tbindingCount = " << value.bindingCount << '\n';
-	s << "\tpBindingFlags = " << value.pBindingFlags << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& value)
-{
-	s << "VkPhysicalDeviceDescriptorIndexingFeaturesEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tshaderInputAttachmentArrayDynamicIndexing = " << value.shaderInputAttachmentArrayDynamicIndexing << '\n';
-	s << "\tshaderUniformTexelBufferArrayDynamicIndexing = " << value.shaderUniformTexelBufferArrayDynamicIndexing << '\n';
-	s << "\tshaderStorageTexelBufferArrayDynamicIndexing = " << value.shaderStorageTexelBufferArrayDynamicIndexing << '\n';
-	s << "\tshaderUniformBufferArrayNonUniformIndexing = " << value.shaderUniformBufferArrayNonUniformIndexing << '\n';
-	s << "\tshaderSampledImageArrayNonUniformIndexing = " << value.shaderSampledImageArrayNonUniformIndexing << '\n';
-	s << "\tshaderStorageBufferArrayNonUniformIndexing = " << value.shaderStorageBufferArrayNonUniformIndexing << '\n';
-	s << "\tshaderStorageImageArrayNonUniformIndexing = " << value.shaderStorageImageArrayNonUniformIndexing << '\n';
-	s << "\tshaderInputAttachmentArrayNonUniformIndexing = " << value.shaderInputAttachmentArrayNonUniformIndexing << '\n';
-	s << "\tshaderUniformTexelBufferArrayNonUniformIndexing = " << value.shaderUniformTexelBufferArrayNonUniformIndexing << '\n';
-	s << "\tshaderStorageTexelBufferArrayNonUniformIndexing = " << value.shaderStorageTexelBufferArrayNonUniformIndexing << '\n';
-	s << "\tdescriptorBindingUniformBufferUpdateAfterBind = " << value.descriptorBindingUniformBufferUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingSampledImageUpdateAfterBind = " << value.descriptorBindingSampledImageUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingStorageImageUpdateAfterBind = " << value.descriptorBindingStorageImageUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingStorageBufferUpdateAfterBind = " << value.descriptorBindingStorageBufferUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingUniformTexelBufferUpdateAfterBind = " << value.descriptorBindingUniformTexelBufferUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingStorageTexelBufferUpdateAfterBind = " << value.descriptorBindingStorageTexelBufferUpdateAfterBind << '\n';
-	s << "\tdescriptorBindingUpdateUnusedWhilePending = " << value.descriptorBindingUpdateUnusedWhilePending << '\n';
-	s << "\tdescriptorBindingPartiallyBound = " << value.descriptorBindingPartiallyBound << '\n';
-	s << "\tdescriptorBindingVariableDescriptorCount = " << value.descriptorBindingVariableDescriptorCount << '\n';
-	s << "\truntimeDescriptorArray = " << value.runtimeDescriptorArray << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceDescriptorIndexingPropertiesEXT& value)
-{
-	s << "VkPhysicalDeviceDescriptorIndexingPropertiesEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tmaxUpdateAfterBindDescriptorsInAllPools = " << value.maxUpdateAfterBindDescriptorsInAllPools << '\n';
-	s << "\tshaderUniformBufferArrayNonUniformIndexingNative = " << value.shaderUniformBufferArrayNonUniformIndexingNative << '\n';
-	s << "\tshaderSampledImageArrayNonUniformIndexingNative = " << value.shaderSampledImageArrayNonUniformIndexingNative << '\n';
-	s << "\tshaderStorageBufferArrayNonUniformIndexingNative = " << value.shaderStorageBufferArrayNonUniformIndexingNative << '\n';
-	s << "\tshaderStorageImageArrayNonUniformIndexingNative = " << value.shaderStorageImageArrayNonUniformIndexingNative << '\n';
-	s << "\tshaderInputAttachmentArrayNonUniformIndexingNative = " << value.shaderInputAttachmentArrayNonUniformIndexingNative << '\n';
-	s << "\trobustBufferAccessUpdateAfterBind = " << value.robustBufferAccessUpdateAfterBind << '\n';
-	s << "\tquadDivergentImplicitLod = " << value.quadDivergentImplicitLod << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindSamplers = " << value.maxPerStageDescriptorUpdateAfterBindSamplers << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindUniformBuffers = " << value.maxPerStageDescriptorUpdateAfterBindUniformBuffers << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageBuffers = " << value.maxPerStageDescriptorUpdateAfterBindStorageBuffers << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindSampledImages = " << value.maxPerStageDescriptorUpdateAfterBindSampledImages << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindStorageImages = " << value.maxPerStageDescriptorUpdateAfterBindStorageImages << '\n';
-	s << "\tmaxPerStageDescriptorUpdateAfterBindInputAttachments = " << value.maxPerStageDescriptorUpdateAfterBindInputAttachments << '\n';
-	s << "\tmaxPerStageUpdateAfterBindResources = " << value.maxPerStageUpdateAfterBindResources << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindSamplers = " << value.maxDescriptorSetUpdateAfterBindSamplers << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffers = " << value.maxDescriptorSetUpdateAfterBindUniformBuffers << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindUniformBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffers = " << value.maxDescriptorSetUpdateAfterBindStorageBuffers << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindStorageBuffersDynamic = " << value.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindSampledImages = " << value.maxDescriptorSetUpdateAfterBindSampledImages << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindStorageImages = " << value.maxDescriptorSetUpdateAfterBindStorageImages << '\n';
-	s << "\tmaxDescriptorSetUpdateAfterBindInputAttachments = " << value.maxDescriptorSetUpdateAfterBindInputAttachments << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkDescriptorSetVariableDescriptorCountAllocateInfoEXT& value)
-{
-	s << "VkDescriptorSetVariableDescriptorCountAllocateInfoEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tdescriptorSetCount = " << value.descriptorSetCount << '\n';
-	s << "\tpDescriptorCounts = " << value.pDescriptorCounts << '\n';
-	s << '}';
-	return s;
-}
-
-std::ostream& operator<< (std::ostream& s, const VkDescriptorSetVariableDescriptorCountLayoutSupportEXT& value)
-{
-	s << "VkDescriptorSetVariableDescriptorCountLayoutSupportEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tmaxVariableDescriptorCount = " << value.maxVariableDescriptorCount << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkShadingRatePaletteNV& value)
 {
 	s << "VkShadingRatePaletteNV = {\n";
@@ -8690,16 +8923,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& value)
-{
-	s << "VkPhysicalDeviceScalarBlockLayoutFeaturesEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& value)
 {
 	s << "VkPhysicalDeviceSubgroupSizeControlFeaturesEXT = {\n";
@@ -8818,12 +9041,16 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkImageStencilUsageCreateInfoEXT& value)
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceToolPropertiesEXT& value)
 {
-	s << "VkImageStencilUsageCreateInfoEXT = {\n";
+	s << "VkPhysicalDeviceToolPropertiesEXT = {\n";
 	s << "\tsType = " << value.sType << '\n';
 	s << "\tpNext = " << value.pNext << '\n';
-	s << "\tstencilUsage = " << getImageUsageFlagsStr(value.stencilUsage) << '\n';
+	s << "\tname = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.name)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.name))) << '\n';
+	s << "\tversion = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.version)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.version))) << '\n';
+	s << "\tpurposes = " << getToolPurposeFlagsEXTStr(value.purposes) << '\n';
+	s << "\tdescription = " << (const char*)value.description << '\n';
+	s << "\tlayer = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<char>(DE_ARRAY_BEGIN(value.layer)), tcu::Format::HexIterator<char>(DE_ARRAY_END(value.layer))) << '\n';
 	s << '}';
 	return s;
 }
@@ -8983,16 +9210,6 @@
 	return s;
 }
 
-std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceHostQueryResetFeaturesEXT& value)
-{
-	s << "VkPhysicalDeviceHostQueryResetFeaturesEXT = {\n";
-	s << "\tsType = " << value.sType << '\n';
-	s << "\tpNext = " << value.pNext << '\n';
-	s << "\thostQueryReset = " << value.hostQueryReset << '\n';
-	s << '}';
-	return s;
-}
-
 std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceIndexTypeUint8FeaturesEXT& value)
 {
 	s << "VkPhysicalDeviceIndexTypeUint8FeaturesEXT = {\n";
@@ -9222,7 +9439,7 @@
 	s << "\tpNext = " << value.pNext << '\n';
 	s << "\thandleType = " << value.handleType << '\n';
 	s << "\thandle = " << value.handle << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
@@ -9234,7 +9451,7 @@
 	s << "\tpNext = " << value.pNext << '\n';
 	s << "\tpAttributes = " << value.pAttributes << '\n';
 	s << "\tdwAccess = " << value.dwAccess << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
@@ -9285,7 +9502,7 @@
 	s << "\tflags = " << getSemaphoreImportFlagsStr(value.flags) << '\n';
 	s << "\thandleType = " << value.handleType << '\n';
 	s << "\thandle = " << value.handle << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
@@ -9297,7 +9514,7 @@
 	s << "\tpNext = " << value.pNext << '\n';
 	s << "\tpAttributes = " << value.pAttributes << '\n';
 	s << "\tdwAccess = " << value.dwAccess << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
@@ -9335,7 +9552,7 @@
 	s << "\tflags = " << getFenceImportFlagsStr(value.flags) << '\n';
 	s << "\thandleType = " << value.handleType << '\n';
 	s << "\thandle = " << value.handle << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
@@ -9347,7 +9564,7 @@
 	s << "\tpNext = " << value.pNext << '\n';
 	s << "\tpAttributes = " << value.pAttributes << '\n';
 	s << "\tdwAccess = " << value.dwAccess << '\n';
-	s << "\tname = " << getCharPtrStr(value.name) << '\n';
+	s << "\tname = " << getWStr(value.name) << '\n';
 	s << '}';
 	return s;
 }
diff --git a/external/vulkancts/framework/vulkan/vkStructTypes.inl b/external/vulkancts/framework/vulkan/vkStructTypes.inl
index 1054a81..81f66fc 100644
--- a/external/vulkancts/framework/vulkan/vkStructTypes.inl
+++ b/external/vulkancts/framework/vulkan/vkStructTypes.inl
@@ -1747,6 +1747,614 @@
 	VkBool32		shaderDrawParameters;
 };
 
+struct VkPhysicalDeviceVulkan11Features
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		storageBuffer16BitAccess;
+	VkBool32		uniformAndStorageBuffer16BitAccess;
+	VkBool32		storagePushConstant16;
+	VkBool32		storageInputOutput16;
+	VkBool32		multiview;
+	VkBool32		multiviewGeometryShader;
+	VkBool32		multiviewTessellationShader;
+	VkBool32		variablePointersStorageBuffer;
+	VkBool32		variablePointers;
+	VkBool32		protectedMemory;
+	VkBool32		samplerYcbcrConversion;
+	VkBool32		shaderDrawParameters;
+};
+
+struct VkPhysicalDeviceVulkan11Properties
+{
+	VkStructureType			sType;
+	void*					pNext;
+	deUint8					deviceUUID[VK_UUID_SIZE];
+	deUint8					driverUUID[VK_UUID_SIZE];
+	deUint8					deviceLUID[VK_LUID_SIZE];
+	deUint32				deviceNodeMask;
+	VkBool32				deviceLUIDValid;
+	deUint32				subgroupSize;
+	VkShaderStageFlags		subgroupSupportedStages;
+	VkSubgroupFeatureFlags	subgroupSupportedOperations;
+	VkBool32				subgroupQuadOperationsInAllStages;
+	VkPointClippingBehavior	pointClippingBehavior;
+	deUint32				maxMultiviewViewCount;
+	deUint32				maxMultiviewInstanceIndex;
+	VkBool32				protectedNoFault;
+	deUint32				maxPerSetDescriptors;
+	VkDeviceSize			maxMemoryAllocationSize;
+};
+
+struct VkPhysicalDeviceVulkan12Features
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		samplerMirrorClampToEdge;
+	VkBool32		drawIndirectCount;
+	VkBool32		storageBuffer8BitAccess;
+	VkBool32		uniformAndStorageBuffer8BitAccess;
+	VkBool32		storagePushConstant8;
+	VkBool32		shaderBufferInt64Atomics;
+	VkBool32		shaderSharedInt64Atomics;
+	VkBool32		shaderFloat16;
+	VkBool32		shaderInt8;
+	VkBool32		descriptorIndexing;
+	VkBool32		shaderInputAttachmentArrayDynamicIndexing;
+	VkBool32		shaderUniformTexelBufferArrayDynamicIndexing;
+	VkBool32		shaderStorageTexelBufferArrayDynamicIndexing;
+	VkBool32		shaderUniformBufferArrayNonUniformIndexing;
+	VkBool32		shaderSampledImageArrayNonUniformIndexing;
+	VkBool32		shaderStorageBufferArrayNonUniformIndexing;
+	VkBool32		shaderStorageImageArrayNonUniformIndexing;
+	VkBool32		shaderInputAttachmentArrayNonUniformIndexing;
+	VkBool32		shaderUniformTexelBufferArrayNonUniformIndexing;
+	VkBool32		shaderStorageTexelBufferArrayNonUniformIndexing;
+	VkBool32		descriptorBindingUniformBufferUpdateAfterBind;
+	VkBool32		descriptorBindingSampledImageUpdateAfterBind;
+	VkBool32		descriptorBindingStorageImageUpdateAfterBind;
+	VkBool32		descriptorBindingStorageBufferUpdateAfterBind;
+	VkBool32		descriptorBindingUniformTexelBufferUpdateAfterBind;
+	VkBool32		descriptorBindingStorageTexelBufferUpdateAfterBind;
+	VkBool32		descriptorBindingUpdateUnusedWhilePending;
+	VkBool32		descriptorBindingPartiallyBound;
+	VkBool32		descriptorBindingVariableDescriptorCount;
+	VkBool32		runtimeDescriptorArray;
+	VkBool32		samplerFilterMinmax;
+	VkBool32		scalarBlockLayout;
+	VkBool32		imagelessFramebuffer;
+	VkBool32		uniformBufferStandardLayout;
+	VkBool32		shaderSubgroupExtendedTypes;
+	VkBool32		separateDepthStencilLayouts;
+	VkBool32		hostQueryReset;
+	VkBool32		timelineSemaphore;
+	VkBool32		bufferDeviceAddress;
+	VkBool32		bufferDeviceAddressCaptureReplay;
+	VkBool32		bufferDeviceAddressMultiDevice;
+	VkBool32		vulkanMemoryModel;
+	VkBool32		vulkanMemoryModelDeviceScope;
+	VkBool32		vulkanMemoryModelAvailabilityVisibilityChains;
+	VkBool32		shaderOutputViewportIndex;
+	VkBool32		shaderOutputLayer;
+	VkBool32		subgroupBroadcastDynamicId;
+};
+
+struct VkConformanceVersion
+{
+	deUint8	major;
+	deUint8	minor;
+	deUint8	subminor;
+	deUint8	patch;
+};
+
+struct VkPhysicalDeviceVulkan12Properties
+{
+	VkStructureType						sType;
+	void*								pNext;
+	VkDriverId							driverID;
+	char								driverName[VK_MAX_DRIVER_NAME_SIZE];
+	char								driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+	VkConformanceVersion				conformanceVersion;
+	VkShaderFloatControlsIndependence	denormBehaviorIndependence;
+	VkShaderFloatControlsIndependence	roundingModeIndependence;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat16;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat32;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat64;
+	VkBool32							shaderDenormPreserveFloat16;
+	VkBool32							shaderDenormPreserveFloat32;
+	VkBool32							shaderDenormPreserveFloat64;
+	VkBool32							shaderDenormFlushToZeroFloat16;
+	VkBool32							shaderDenormFlushToZeroFloat32;
+	VkBool32							shaderDenormFlushToZeroFloat64;
+	VkBool32							shaderRoundingModeRTEFloat16;
+	VkBool32							shaderRoundingModeRTEFloat32;
+	VkBool32							shaderRoundingModeRTEFloat64;
+	VkBool32							shaderRoundingModeRTZFloat16;
+	VkBool32							shaderRoundingModeRTZFloat32;
+	VkBool32							shaderRoundingModeRTZFloat64;
+	deUint32							maxUpdateAfterBindDescriptorsInAllPools;
+	VkBool32							shaderUniformBufferArrayNonUniformIndexingNative;
+	VkBool32							shaderSampledImageArrayNonUniformIndexingNative;
+	VkBool32							shaderStorageBufferArrayNonUniformIndexingNative;
+	VkBool32							shaderStorageImageArrayNonUniformIndexingNative;
+	VkBool32							shaderInputAttachmentArrayNonUniformIndexingNative;
+	VkBool32							robustBufferAccessUpdateAfterBind;
+	VkBool32							quadDivergentImplicitLod;
+	deUint32							maxPerStageDescriptorUpdateAfterBindSamplers;
+	deUint32							maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+	deUint32							maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+	deUint32							maxPerStageDescriptorUpdateAfterBindSampledImages;
+	deUint32							maxPerStageDescriptorUpdateAfterBindStorageImages;
+	deUint32							maxPerStageDescriptorUpdateAfterBindInputAttachments;
+	deUint32							maxPerStageUpdateAfterBindResources;
+	deUint32							maxDescriptorSetUpdateAfterBindSamplers;
+	deUint32							maxDescriptorSetUpdateAfterBindUniformBuffers;
+	deUint32							maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+	deUint32							maxDescriptorSetUpdateAfterBindStorageBuffers;
+	deUint32							maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+	deUint32							maxDescriptorSetUpdateAfterBindSampledImages;
+	deUint32							maxDescriptorSetUpdateAfterBindStorageImages;
+	deUint32							maxDescriptorSetUpdateAfterBindInputAttachments;
+	VkResolveModeFlags					supportedDepthResolveModes;
+	VkResolveModeFlags					supportedStencilResolveModes;
+	VkBool32							independentResolveNone;
+	VkBool32							independentResolve;
+	VkBool32							filterMinmaxSingleComponentFormats;
+	VkBool32							filterMinmaxImageComponentMapping;
+	deUint64							maxTimelineSemaphoreValueDifference;
+	VkSampleCountFlags					framebufferIntegerColorSampleCounts;
+};
+
+struct VkImageFormatListCreateInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	deUint32		viewFormatCount;
+	const VkFormat*	pViewFormats;
+};
+
+struct VkAttachmentDescription2
+{
+	VkStructureType					sType;
+	const void*						pNext;
+	VkAttachmentDescriptionFlags	flags;
+	VkFormat						format;
+	VkSampleCountFlagBits			samples;
+	VkAttachmentLoadOp				loadOp;
+	VkAttachmentStoreOp				storeOp;
+	VkAttachmentLoadOp				stencilLoadOp;
+	VkAttachmentStoreOp				stencilStoreOp;
+	VkImageLayout					initialLayout;
+	VkImageLayout					finalLayout;
+};
+
+struct VkAttachmentReference2
+{
+	VkStructureType		sType;
+	const void*			pNext;
+	deUint32			attachment;
+	VkImageLayout		layout;
+	VkImageAspectFlags	aspectMask;
+};
+
+struct VkSubpassDescription2
+{
+	VkStructureType					sType;
+	const void*						pNext;
+	VkSubpassDescriptionFlags		flags;
+	VkPipelineBindPoint				pipelineBindPoint;
+	deUint32						viewMask;
+	deUint32						inputAttachmentCount;
+	const VkAttachmentReference2*	pInputAttachments;
+	deUint32						colorAttachmentCount;
+	const VkAttachmentReference2*	pColorAttachments;
+	const VkAttachmentReference2*	pResolveAttachments;
+	const VkAttachmentReference2*	pDepthStencilAttachment;
+	deUint32						preserveAttachmentCount;
+	const deUint32*					pPreserveAttachments;
+};
+
+struct VkSubpassDependency2
+{
+	VkStructureType			sType;
+	const void*				pNext;
+	deUint32				srcSubpass;
+	deUint32				dstSubpass;
+	VkPipelineStageFlags	srcStageMask;
+	VkPipelineStageFlags	dstStageMask;
+	VkAccessFlags			srcAccessMask;
+	VkAccessFlags			dstAccessMask;
+	VkDependencyFlags		dependencyFlags;
+	deInt32					viewOffset;
+};
+
+struct VkRenderPassCreateInfo2
+{
+	VkStructureType					sType;
+	const void*						pNext;
+	VkRenderPassCreateFlags			flags;
+	deUint32						attachmentCount;
+	const VkAttachmentDescription2*	pAttachments;
+	deUint32						subpassCount;
+	const VkSubpassDescription2*	pSubpasses;
+	deUint32						dependencyCount;
+	const VkSubpassDependency2*		pDependencies;
+	deUint32						correlatedViewMaskCount;
+	const deUint32*					pCorrelatedViewMasks;
+};
+
+struct VkSubpassBeginInfo
+{
+	VkStructureType		sType;
+	const void*			pNext;
+	VkSubpassContents	contents;
+};
+
+struct VkSubpassEndInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+};
+
+struct VkPhysicalDevice8BitStorageFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		storageBuffer8BitAccess;
+	VkBool32		uniformAndStorageBuffer8BitAccess;
+	VkBool32		storagePushConstant8;
+};
+
+struct VkPhysicalDeviceDriverProperties
+{
+	VkStructureType			sType;
+	void*					pNext;
+	VkDriverId				driverID;
+	char					driverName[VK_MAX_DRIVER_NAME_SIZE];
+	char					driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+	VkConformanceVersion	conformanceVersion;
+};
+
+struct VkPhysicalDeviceShaderAtomicInt64Features
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		shaderBufferInt64Atomics;
+	VkBool32		shaderSharedInt64Atomics;
+};
+
+struct VkPhysicalDeviceShaderFloat16Int8Features
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		shaderFloat16;
+	VkBool32		shaderInt8;
+};
+
+struct VkPhysicalDeviceFloatControlsProperties
+{
+	VkStructureType						sType;
+	void*								pNext;
+	VkShaderFloatControlsIndependence	denormBehaviorIndependence;
+	VkShaderFloatControlsIndependence	roundingModeIndependence;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat16;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat32;
+	VkBool32							shaderSignedZeroInfNanPreserveFloat64;
+	VkBool32							shaderDenormPreserveFloat16;
+	VkBool32							shaderDenormPreserveFloat32;
+	VkBool32							shaderDenormPreserveFloat64;
+	VkBool32							shaderDenormFlushToZeroFloat16;
+	VkBool32							shaderDenormFlushToZeroFloat32;
+	VkBool32							shaderDenormFlushToZeroFloat64;
+	VkBool32							shaderRoundingModeRTEFloat16;
+	VkBool32							shaderRoundingModeRTEFloat32;
+	VkBool32							shaderRoundingModeRTEFloat64;
+	VkBool32							shaderRoundingModeRTZFloat16;
+	VkBool32							shaderRoundingModeRTZFloat32;
+	VkBool32							shaderRoundingModeRTZFloat64;
+};
+
+struct VkDescriptorSetLayoutBindingFlagsCreateInfo
+{
+	VkStructureType					sType;
+	const void*						pNext;
+	deUint32						bindingCount;
+	const VkDescriptorBindingFlags*	pBindingFlags;
+};
+
+struct VkPhysicalDeviceDescriptorIndexingFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		shaderInputAttachmentArrayDynamicIndexing;
+	VkBool32		shaderUniformTexelBufferArrayDynamicIndexing;
+	VkBool32		shaderStorageTexelBufferArrayDynamicIndexing;
+	VkBool32		shaderUniformBufferArrayNonUniformIndexing;
+	VkBool32		shaderSampledImageArrayNonUniformIndexing;
+	VkBool32		shaderStorageBufferArrayNonUniformIndexing;
+	VkBool32		shaderStorageImageArrayNonUniformIndexing;
+	VkBool32		shaderInputAttachmentArrayNonUniformIndexing;
+	VkBool32		shaderUniformTexelBufferArrayNonUniformIndexing;
+	VkBool32		shaderStorageTexelBufferArrayNonUniformIndexing;
+	VkBool32		descriptorBindingUniformBufferUpdateAfterBind;
+	VkBool32		descriptorBindingSampledImageUpdateAfterBind;
+	VkBool32		descriptorBindingStorageImageUpdateAfterBind;
+	VkBool32		descriptorBindingStorageBufferUpdateAfterBind;
+	VkBool32		descriptorBindingUniformTexelBufferUpdateAfterBind;
+	VkBool32		descriptorBindingStorageTexelBufferUpdateAfterBind;
+	VkBool32		descriptorBindingUpdateUnusedWhilePending;
+	VkBool32		descriptorBindingPartiallyBound;
+	VkBool32		descriptorBindingVariableDescriptorCount;
+	VkBool32		runtimeDescriptorArray;
+};
+
+struct VkPhysicalDeviceDescriptorIndexingProperties
+{
+	VkStructureType	sType;
+	void*			pNext;
+	deUint32		maxUpdateAfterBindDescriptorsInAllPools;
+	VkBool32		shaderUniformBufferArrayNonUniformIndexingNative;
+	VkBool32		shaderSampledImageArrayNonUniformIndexingNative;
+	VkBool32		shaderStorageBufferArrayNonUniformIndexingNative;
+	VkBool32		shaderStorageImageArrayNonUniformIndexingNative;
+	VkBool32		shaderInputAttachmentArrayNonUniformIndexingNative;
+	VkBool32		robustBufferAccessUpdateAfterBind;
+	VkBool32		quadDivergentImplicitLod;
+	deUint32		maxPerStageDescriptorUpdateAfterBindSamplers;
+	deUint32		maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+	deUint32		maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+	deUint32		maxPerStageDescriptorUpdateAfterBindSampledImages;
+	deUint32		maxPerStageDescriptorUpdateAfterBindStorageImages;
+	deUint32		maxPerStageDescriptorUpdateAfterBindInputAttachments;
+	deUint32		maxPerStageUpdateAfterBindResources;
+	deUint32		maxDescriptorSetUpdateAfterBindSamplers;
+	deUint32		maxDescriptorSetUpdateAfterBindUniformBuffers;
+	deUint32		maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+	deUint32		maxDescriptorSetUpdateAfterBindStorageBuffers;
+	deUint32		maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+	deUint32		maxDescriptorSetUpdateAfterBindSampledImages;
+	deUint32		maxDescriptorSetUpdateAfterBindStorageImages;
+	deUint32		maxDescriptorSetUpdateAfterBindInputAttachments;
+};
+
+struct VkDescriptorSetVariableDescriptorCountAllocateInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	deUint32		descriptorSetCount;
+	const deUint32*	pDescriptorCounts;
+};
+
+struct VkDescriptorSetVariableDescriptorCountLayoutSupport
+{
+	VkStructureType	sType;
+	void*			pNext;
+	deUint32		maxVariableDescriptorCount;
+};
+
+struct VkSubpassDescriptionDepthStencilResolve
+{
+	VkStructureType					sType;
+	const void*						pNext;
+	VkResolveModeFlagBits			depthResolveMode;
+	VkResolveModeFlagBits			stencilResolveMode;
+	const VkAttachmentReference2*	pDepthStencilResolveAttachment;
+};
+
+struct VkPhysicalDeviceDepthStencilResolveProperties
+{
+	VkStructureType		sType;
+	void*				pNext;
+	VkResolveModeFlags	supportedDepthResolveModes;
+	VkResolveModeFlags	supportedStencilResolveModes;
+	VkBool32			independentResolveNone;
+	VkBool32			independentResolve;
+};
+
+struct VkPhysicalDeviceScalarBlockLayoutFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		scalarBlockLayout;
+};
+
+struct VkImageStencilUsageCreateInfo
+{
+	VkStructureType		sType;
+	const void*			pNext;
+	VkImageUsageFlags	stencilUsage;
+};
+
+struct VkSamplerReductionModeCreateInfo
+{
+	VkStructureType			sType;
+	const void*				pNext;
+	VkSamplerReductionMode	reductionMode;
+};
+
+struct VkPhysicalDeviceSamplerFilterMinmaxProperties
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		filterMinmaxSingleComponentFormats;
+	VkBool32		filterMinmaxImageComponentMapping;
+};
+
+struct VkPhysicalDeviceVulkanMemoryModelFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		vulkanMemoryModel;
+	VkBool32		vulkanMemoryModelDeviceScope;
+	VkBool32		vulkanMemoryModelAvailabilityVisibilityChains;
+};
+
+struct VkPhysicalDeviceImagelessFramebufferFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		imagelessFramebuffer;
+};
+
+struct VkFramebufferAttachmentImageInfo
+{
+	VkStructureType		sType;
+	const void*			pNext;
+	VkImageCreateFlags	flags;
+	VkImageUsageFlags	usage;
+	deUint32			width;
+	deUint32			height;
+	deUint32			layerCount;
+	deUint32			viewFormatCount;
+	const VkFormat*		pViewFormats;
+};
+
+struct VkFramebufferAttachmentsCreateInfo
+{
+	VkStructureType							sType;
+	const void*								pNext;
+	deUint32								attachmentImageInfoCount;
+	const VkFramebufferAttachmentImageInfo*	pAttachmentImageInfos;
+};
+
+struct VkRenderPassAttachmentBeginInfo
+{
+	VkStructureType		sType;
+	const void*			pNext;
+	deUint32			attachmentCount;
+	const VkImageView*	pAttachments;
+};
+
+struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		uniformBufferStandardLayout;
+};
+
+struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		shaderSubgroupExtendedTypes;
+};
+
+struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		separateDepthStencilLayouts;
+};
+
+struct VkAttachmentReferenceStencilLayout
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkImageLayout	stencilLayout;
+};
+
+struct VkAttachmentDescriptionStencilLayout
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkImageLayout	stencilInitialLayout;
+	VkImageLayout	stencilFinalLayout;
+};
+
+struct VkPhysicalDeviceHostQueryResetFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		hostQueryReset;
+};
+
+struct VkPhysicalDeviceTimelineSemaphoreFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		timelineSemaphore;
+};
+
+struct VkPhysicalDeviceTimelineSemaphoreProperties
+{
+	VkStructureType	sType;
+	void*			pNext;
+	deUint64		maxTimelineSemaphoreValueDifference;
+};
+
+struct VkSemaphoreTypeCreateInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	VkSemaphoreType	semaphoreType;
+	deUint64		initialValue;
+};
+
+struct VkTimelineSemaphoreSubmitInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	deUint32		waitSemaphoreValueCount;
+	const deUint64*	pWaitSemaphoreValues;
+	deUint32		signalSemaphoreValueCount;
+	const deUint64*	pSignalSemaphoreValues;
+};
+
+struct VkSemaphoreWaitInfo
+{
+	VkStructureType			sType;
+	const void*				pNext;
+	VkSemaphoreWaitFlags	flags;
+	deUint32				semaphoreCount;
+	const VkSemaphore*		pSemaphores;
+	const deUint64*			pValues;
+};
+
+struct VkSemaphoreSignalInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	VkSemaphore		semaphore;
+	deUint64		value;
+};
+
+struct VkPhysicalDeviceBufferDeviceAddressFeatures
+{
+	VkStructureType	sType;
+	void*			pNext;
+	VkBool32		bufferDeviceAddress;
+	VkBool32		bufferDeviceAddressCaptureReplay;
+	VkBool32		bufferDeviceAddressMultiDevice;
+};
+
+struct VkBufferDeviceAddressInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	VkBuffer		buffer;
+};
+
+struct VkBufferOpaqueCaptureAddressCreateInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	deUint64		opaqueCaptureAddress;
+};
+
+struct VkMemoryOpaqueCaptureAddressAllocateInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	deUint64		opaqueCaptureAddress;
+};
+
+struct VkDeviceMemoryOpaqueCaptureAddressInfo
+{
+	VkStructureType	sType;
+	const void*		pNext;
+	VkDeviceMemory	memory;
+};
+
 struct VkSurfaceCapabilitiesKHR
 {
 	deUint32						minImageCount;
@@ -1972,14 +2580,6 @@
 	deUint32		maxPushDescriptors;
 };
 
-struct VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		shaderFloat16;
-	VkBool32		shaderInt8;
-};
-
 struct VkRectLayerKHR
 {
 	VkOffset2D	offset;
@@ -2001,125 +2601,6 @@
 	const VkPresentRegionKHR*	pRegions;
 };
 
-struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		imagelessFramebuffer;
-};
-
-struct VkFramebufferAttachmentImageInfoKHR
-{
-	VkStructureType		sType;
-	const void*			pNext;
-	VkImageCreateFlags	flags;
-	VkImageUsageFlags	usage;
-	deUint32			width;
-	deUint32			height;
-	deUint32			layerCount;
-	deUint32			viewFormatCount;
-	const VkFormat*		pViewFormats;
-};
-
-struct VkFramebufferAttachmentsCreateInfoKHR
-{
-	VkStructureType								sType;
-	const void*									pNext;
-	deUint32									attachmentImageInfoCount;
-	const VkFramebufferAttachmentImageInfoKHR*	pAttachmentImageInfos;
-};
-
-struct VkRenderPassAttachmentBeginInfoKHR
-{
-	VkStructureType		sType;
-	const void*			pNext;
-	deUint32			attachmentCount;
-	const VkImageView*	pAttachments;
-};
-
-struct VkAttachmentDescription2KHR
-{
-	VkStructureType					sType;
-	const void*						pNext;
-	VkAttachmentDescriptionFlags	flags;
-	VkFormat						format;
-	VkSampleCountFlagBits			samples;
-	VkAttachmentLoadOp				loadOp;
-	VkAttachmentStoreOp				storeOp;
-	VkAttachmentLoadOp				stencilLoadOp;
-	VkAttachmentStoreOp				stencilStoreOp;
-	VkImageLayout					initialLayout;
-	VkImageLayout					finalLayout;
-};
-
-struct VkAttachmentReference2KHR
-{
-	VkStructureType		sType;
-	const void*			pNext;
-	deUint32			attachment;
-	VkImageLayout		layout;
-	VkImageAspectFlags	aspectMask;
-};
-
-struct VkSubpassDescription2KHR
-{
-	VkStructureType						sType;
-	const void*							pNext;
-	VkSubpassDescriptionFlags			flags;
-	VkPipelineBindPoint					pipelineBindPoint;
-	deUint32							viewMask;
-	deUint32							inputAttachmentCount;
-	const VkAttachmentReference2KHR*	pInputAttachments;
-	deUint32							colorAttachmentCount;
-	const VkAttachmentReference2KHR*	pColorAttachments;
-	const VkAttachmentReference2KHR*	pResolveAttachments;
-	const VkAttachmentReference2KHR*	pDepthStencilAttachment;
-	deUint32							preserveAttachmentCount;
-	const deUint32*						pPreserveAttachments;
-};
-
-struct VkSubpassDependency2KHR
-{
-	VkStructureType			sType;
-	const void*				pNext;
-	deUint32				srcSubpass;
-	deUint32				dstSubpass;
-	VkPipelineStageFlags	srcStageMask;
-	VkPipelineStageFlags	dstStageMask;
-	VkAccessFlags			srcAccessMask;
-	VkAccessFlags			dstAccessMask;
-	VkDependencyFlags		dependencyFlags;
-	deInt32					viewOffset;
-};
-
-struct VkRenderPassCreateInfo2KHR
-{
-	VkStructureType						sType;
-	const void*							pNext;
-	VkRenderPassCreateFlags				flags;
-	deUint32							attachmentCount;
-	const VkAttachmentDescription2KHR*	pAttachments;
-	deUint32							subpassCount;
-	const VkSubpassDescription2KHR*		pSubpasses;
-	deUint32							dependencyCount;
-	const VkSubpassDependency2KHR*		pDependencies;
-	deUint32							correlatedViewMaskCount;
-	const deUint32*						pCorrelatedViewMasks;
-};
-
-struct VkSubpassBeginInfoKHR
-{
-	VkStructureType		sType;
-	const void*			pNext;
-	VkSubpassContents	contents;
-};
-
-struct VkSubpassEndInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-};
-
 struct VkSharedPresentSurfaceCapabilitiesKHR
 {
 	VkStructureType		sType;
@@ -2271,38 +2752,6 @@
 	VkDisplayPlaneCapabilitiesKHR	capabilities;
 };
 
-struct VkImageFormatListCreateInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	deUint32		viewFormatCount;
-	const VkFormat*	pViewFormats;
-};
-
-struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		shaderSubgroupExtendedTypes;
-};
-
-struct VkPhysicalDevice8BitStorageFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		storageBuffer8BitAccess;
-	VkBool32		uniformAndStorageBuffer8BitAccess;
-	VkBool32		storagePushConstant8;
-};
-
-struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		shaderBufferInt64Atomics;
-	VkBool32		shaderSharedInt64Atomics;
-};
-
 struct VkPhysicalDeviceShaderClockFeaturesKHR
 {
 	VkStructureType	sType;
@@ -2311,125 +2760,6 @@
 	VkBool32		shaderDeviceClock;
 };
 
-struct VkConformanceVersionKHR
-{
-	deUint8	major;
-	deUint8	minor;
-	deUint8	subminor;
-	deUint8	patch;
-};
-
-struct VkPhysicalDeviceDriverPropertiesKHR
-{
-	VkStructureType			sType;
-	void*					pNext;
-	VkDriverIdKHR			driverID;
-	char					driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
-	char					driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
-	VkConformanceVersionKHR	conformanceVersion;
-};
-
-struct VkPhysicalDeviceFloatControlsPropertiesKHR
-{
-	VkStructureType							sType;
-	void*									pNext;
-	VkShaderFloatControlsIndependenceKHR	denormBehaviorIndependence;
-	VkShaderFloatControlsIndependenceKHR	roundingModeIndependence;
-	VkBool32								shaderSignedZeroInfNanPreserveFloat16;
-	VkBool32								shaderSignedZeroInfNanPreserveFloat32;
-	VkBool32								shaderSignedZeroInfNanPreserveFloat64;
-	VkBool32								shaderDenormPreserveFloat16;
-	VkBool32								shaderDenormPreserveFloat32;
-	VkBool32								shaderDenormPreserveFloat64;
-	VkBool32								shaderDenormFlushToZeroFloat16;
-	VkBool32								shaderDenormFlushToZeroFloat32;
-	VkBool32								shaderDenormFlushToZeroFloat64;
-	VkBool32								shaderRoundingModeRTEFloat16;
-	VkBool32								shaderRoundingModeRTEFloat32;
-	VkBool32								shaderRoundingModeRTEFloat64;
-	VkBool32								shaderRoundingModeRTZFloat16;
-	VkBool32								shaderRoundingModeRTZFloat32;
-	VkBool32								shaderRoundingModeRTZFloat64;
-};
-
-struct VkSubpassDescriptionDepthStencilResolveKHR
-{
-	VkStructureType						sType;
-	const void*							pNext;
-	VkResolveModeFlagBitsKHR			depthResolveMode;
-	VkResolveModeFlagBitsKHR			stencilResolveMode;
-	const VkAttachmentReference2KHR*	pDepthStencilResolveAttachment;
-};
-
-struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR
-{
-	VkStructureType			sType;
-	void*					pNext;
-	VkResolveModeFlagsKHR	supportedDepthResolveModes;
-	VkResolveModeFlagsKHR	supportedStencilResolveModes;
-	VkBool32				independentResolveNone;
-	VkBool32				independentResolve;
-};
-
-struct VkPhysicalDeviceTimelineSemaphoreFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		timelineSemaphore;
-};
-
-struct VkPhysicalDeviceTimelineSemaphorePropertiesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	deUint64		maxTimelineSemaphoreValueDifference;
-};
-
-struct VkSemaphoreTypeCreateInfoKHR
-{
-	VkStructureType		sType;
-	const void*			pNext;
-	VkSemaphoreTypeKHR	semaphoreType;
-	deUint64			initialValue;
-};
-
-struct VkTimelineSemaphoreSubmitInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	deUint32		waitSemaphoreValueCount;
-	const deUint64*	pWaitSemaphoreValues;
-	deUint32		signalSemaphoreValueCount;
-	const deUint64*	pSignalSemaphoreValues;
-};
-
-struct VkSemaphoreWaitInfoKHR
-{
-	VkStructureType			sType;
-	const void*				pNext;
-	VkSemaphoreWaitFlagsKHR	flags;
-	deUint32				semaphoreCount;
-	const VkSemaphore*		pSemaphores;
-	const deUint64*			pValues;
-};
-
-struct VkSemaphoreSignalInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	VkSemaphore		semaphore;
-	deUint64		value;
-};
-
-struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		vulkanMemoryModel;
-	VkBool32		vulkanMemoryModelDeviceScope;
-	VkBool32		vulkanMemoryModelAvailabilityVisibilityChains;
-};
-
 struct VkSurfaceProtectedCapabilitiesKHR
 {
 	VkStructureType	sType;
@@ -2437,72 +2767,6 @@
 	VkBool32		supportsProtected;
 };
 
-struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		separateDepthStencilLayouts;
-};
-
-struct VkAttachmentReferenceStencilLayoutKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkImageLayout	stencilLayout;
-};
-
-struct VkAttachmentDescriptionStencilLayoutKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkImageLayout	stencilInitialLayout;
-	VkImageLayout	stencilFinalLayout;
-};
-
-struct VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		uniformBufferStandardLayout;
-};
-
-struct VkPhysicalDeviceBufferDeviceAddressFeaturesKHR
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		bufferDeviceAddress;
-	VkBool32		bufferDeviceAddressCaptureReplay;
-	VkBool32		bufferDeviceAddressMultiDevice;
-};
-
-struct VkBufferDeviceAddressInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	VkBuffer		buffer;
-};
-
-struct VkBufferOpaqueCaptureAddressCreateInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	deUint64		opaqueCaptureAddress;
-};
-
-struct VkMemoryOpaqueCaptureAddressAllocateInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	deUint64		opaqueCaptureAddress;
-};
-
-struct VkDeviceMemoryOpaqueCaptureAddressInfoKHR
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	VkDeviceMemory	memory;
-};
-
 struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR
 {
 	VkStructureType	sType;
@@ -3150,21 +3414,6 @@
 	void*									pUserData;
 };
 
-struct VkSamplerReductionModeCreateInfoEXT
-{
-	VkStructureType				sType;
-	const void*					pNext;
-	VkSamplerReductionModeEXT	reductionMode;
-};
-
-struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		filterMinmaxSingleComponentFormats;
-	VkBool32		filterMinmaxImageComponentMapping;
-};
-
 struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT
 {
 	VkStructureType	sType;
@@ -3391,84 +3640,6 @@
 	VkValidationCacheEXT	validationCache;
 };
 
-struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
-{
-	VkStructureType						sType;
-	const void*							pNext;
-	deUint32							bindingCount;
-	const VkDescriptorBindingFlagsEXT*	pBindingFlags;
-};
-
-struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		shaderInputAttachmentArrayDynamicIndexing;
-	VkBool32		shaderUniformTexelBufferArrayDynamicIndexing;
-	VkBool32		shaderStorageTexelBufferArrayDynamicIndexing;
-	VkBool32		shaderUniformBufferArrayNonUniformIndexing;
-	VkBool32		shaderSampledImageArrayNonUniformIndexing;
-	VkBool32		shaderStorageBufferArrayNonUniformIndexing;
-	VkBool32		shaderStorageImageArrayNonUniformIndexing;
-	VkBool32		shaderInputAttachmentArrayNonUniformIndexing;
-	VkBool32		shaderUniformTexelBufferArrayNonUniformIndexing;
-	VkBool32		shaderStorageTexelBufferArrayNonUniformIndexing;
-	VkBool32		descriptorBindingUniformBufferUpdateAfterBind;
-	VkBool32		descriptorBindingSampledImageUpdateAfterBind;
-	VkBool32		descriptorBindingStorageImageUpdateAfterBind;
-	VkBool32		descriptorBindingStorageBufferUpdateAfterBind;
-	VkBool32		descriptorBindingUniformTexelBufferUpdateAfterBind;
-	VkBool32		descriptorBindingStorageTexelBufferUpdateAfterBind;
-	VkBool32		descriptorBindingUpdateUnusedWhilePending;
-	VkBool32		descriptorBindingPartiallyBound;
-	VkBool32		descriptorBindingVariableDescriptorCount;
-	VkBool32		runtimeDescriptorArray;
-};
-
-struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	deUint32		maxUpdateAfterBindDescriptorsInAllPools;
-	VkBool32		shaderUniformBufferArrayNonUniformIndexingNative;
-	VkBool32		shaderSampledImageArrayNonUniformIndexingNative;
-	VkBool32		shaderStorageBufferArrayNonUniformIndexingNative;
-	VkBool32		shaderStorageImageArrayNonUniformIndexingNative;
-	VkBool32		shaderInputAttachmentArrayNonUniformIndexingNative;
-	VkBool32		robustBufferAccessUpdateAfterBind;
-	VkBool32		quadDivergentImplicitLod;
-	deUint32		maxPerStageDescriptorUpdateAfterBindSamplers;
-	deUint32		maxPerStageDescriptorUpdateAfterBindUniformBuffers;
-	deUint32		maxPerStageDescriptorUpdateAfterBindStorageBuffers;
-	deUint32		maxPerStageDescriptorUpdateAfterBindSampledImages;
-	deUint32		maxPerStageDescriptorUpdateAfterBindStorageImages;
-	deUint32		maxPerStageDescriptorUpdateAfterBindInputAttachments;
-	deUint32		maxPerStageUpdateAfterBindResources;
-	deUint32		maxDescriptorSetUpdateAfterBindSamplers;
-	deUint32		maxDescriptorSetUpdateAfterBindUniformBuffers;
-	deUint32		maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
-	deUint32		maxDescriptorSetUpdateAfterBindStorageBuffers;
-	deUint32		maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
-	deUint32		maxDescriptorSetUpdateAfterBindSampledImages;
-	deUint32		maxDescriptorSetUpdateAfterBindStorageImages;
-	deUint32		maxDescriptorSetUpdateAfterBindInputAttachments;
-};
-
-struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT
-{
-	VkStructureType	sType;
-	const void*		pNext;
-	deUint32		descriptorSetCount;
-	const deUint32*	pDescriptorCounts;
-};
-
-struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	deUint32		maxVariableDescriptorCount;
-};
-
 struct VkShadingRatePaletteNV
 {
 	deUint32							shadingRatePaletteEntryCount;
@@ -3996,13 +4167,6 @@
 	VkAttachmentReference	fragmentDensityMapAttachment;
 };
 
-struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		scalarBlockLayout;
-};
-
 struct VkPhysicalDeviceSubgroupSizeControlFeaturesEXT
 {
 	VkStructureType	sType;
@@ -4088,11 +4252,15 @@
 	VkDeviceAddress	deviceAddress;
 };
 
-struct VkImageStencilUsageCreateInfoEXT
+struct VkPhysicalDeviceToolPropertiesEXT
 {
-	VkStructureType		sType;
-	const void*			pNext;
-	VkImageUsageFlags	stencilUsage;
+	VkStructureType			sType;
+	void*					pNext;
+	char					name[VK_MAX_EXTENSION_NAME_SIZE];
+	char					version[VK_MAX_EXTENSION_NAME_SIZE];
+	VkToolPurposeFlagsEXT	purposes;
+	char					description[VK_MAX_DESCRIPTION_SIZE];
+	char					layer[VK_MAX_EXTENSION_NAME_SIZE];
 };
 
 struct VkValidationFeaturesEXT
@@ -4211,13 +4379,6 @@
 	deUint16					lineStipplePattern;
 };
 
-struct VkPhysicalDeviceHostQueryResetFeaturesEXT
-{
-	VkStructureType	sType;
-	void*			pNext;
-	VkBool32		hostQueryReset;
-};
-
 struct VkPhysicalDeviceIndexTypeUint8FeaturesEXT
 {
 	VkStructureType	sType;
@@ -4386,7 +4547,7 @@
 	const void*							pNext;
 	VkExternalMemoryHandleTypeFlagBits	handleType;
 	pt::Win32Handle						handle;
-	char*								name;
+	pt::Win32LPCWSTR					name;
 };
 
 struct VkExportMemoryWin32HandleInfoKHR
@@ -4395,7 +4556,7 @@
 	const void*						pNext;
 	pt::Win32SecurityAttributesPtr	pAttributes;
 	deUint32						dwAccess;
-	char*							name;
+	pt::Win32LPCWSTR				name;
 };
 
 struct VkMemoryWin32HandlePropertiesKHR
@@ -4434,7 +4595,7 @@
 	VkSemaphoreImportFlags					flags;
 	VkExternalSemaphoreHandleTypeFlagBits	handleType;
 	pt::Win32Handle							handle;
-	char*									name;
+	pt::Win32LPCWSTR						name;
 };
 
 struct VkExportSemaphoreWin32HandleInfoKHR
@@ -4443,7 +4604,7 @@
 	const void*						pNext;
 	pt::Win32SecurityAttributesPtr	pAttributes;
 	deUint32						dwAccess;
-	char*							name;
+	pt::Win32LPCWSTR				name;
 };
 
 struct VkD3D12FenceSubmitInfoKHR
@@ -4472,7 +4633,7 @@
 	VkFenceImportFlags					flags;
 	VkExternalFenceHandleTypeFlagBits	handleType;
 	pt::Win32Handle						handle;
-	char*								name;
+	pt::Win32LPCWSTR					name;
 };
 
 struct VkExportFenceWin32HandleInfoKHR
@@ -4481,7 +4642,7 @@
 	const void*						pNext;
 	pt::Win32SecurityAttributesPtr	pAttributes;
 	deUint32						dwAccess;
-	char*							name;
+	pt::Win32LPCWSTR				name;
 };
 
 struct VkFenceGetWin32HandleInfoKHR
@@ -4684,9 +4845,95 @@
 
 typedef VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures;
 
-typedef VkPhysicalDeviceShaderFloat16Int8FeaturesKHR VkPhysicalDeviceFloat16Int8FeaturesKHR;
+typedef VkConformanceVersion VkConformanceVersionKHR;
 
-typedef VkBufferDeviceAddressInfoKHR VkBufferDeviceAddressInfoEXT;
+typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR;
+
+typedef VkAttachmentDescription2 VkAttachmentDescription2KHR;
+
+typedef VkAttachmentReference2 VkAttachmentReference2KHR;
+
+typedef VkSubpassDescription2 VkSubpassDescription2KHR;
+
+typedef VkSubpassDependency2 VkSubpassDependency2KHR;
+
+typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR;
+
+typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR;
+
+typedef VkSubpassEndInfo VkSubpassEndInfoKHR;
+
+typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR;
+
+typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR;
+
+typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
+
+typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR;
+
+typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+
+typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+
+typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+
+typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR;
+
+typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
+
+typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
+
+typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT;
+
+typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT;
+
+typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
+
+typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
+
+typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
+
+typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR;
+
+typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR;
+
+typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR;
+
+typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
+
+typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
+
+typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
+
+typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR;
+
+typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR;
+
+typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT;
+
+typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
+
+typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
+
+typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR;
+
+typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR;
+
+typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR;
+
+typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR;
+
+typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
+
+typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR;
+
+typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
+
+typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
 
 typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT;
 
diff --git a/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl b/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
index 85d2bc5..0b50966 100644
--- a/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
+++ b/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
@@ -4,6 +4,33 @@
 
 void getCoreDeviceExtensionsImpl (deUint32 coreVersion, ::std::vector<const char*>& dst)
 {
+	if (coreVersion >= VK_API_VERSION_1_2)
+	{
+		dst.push_back("VK_KHR_sampler_mirror_clamp_to_edge");
+		dst.push_back("VK_KHR_shader_float16_int8");
+		dst.push_back("VK_KHR_imageless_framebuffer");
+		dst.push_back("VK_KHR_create_renderpass2");
+		dst.push_back("VK_KHR_image_format_list");
+		dst.push_back("VK_KHR_draw_indirect_count");
+		dst.push_back("VK_KHR_shader_subgroup_extended_types");
+		dst.push_back("VK_KHR_8bit_storage");
+		dst.push_back("VK_KHR_shader_atomic_int64");
+		dst.push_back("VK_KHR_driver_properties");
+		dst.push_back("VK_KHR_shader_float_controls");
+		dst.push_back("VK_KHR_depth_stencil_resolve");
+		dst.push_back("VK_KHR_timeline_semaphore");
+		dst.push_back("VK_KHR_vulkan_memory_model");
+		dst.push_back("VK_KHR_spirv_1_4");
+		dst.push_back("VK_KHR_separate_depth_stencil_layouts");
+		dst.push_back("VK_KHR_uniform_buffer_standard_layout");
+		dst.push_back("VK_KHR_buffer_device_address");
+		dst.push_back("VK_EXT_sampler_filter_minmax");
+		dst.push_back("VK_EXT_descriptor_indexing");
+		dst.push_back("VK_EXT_shader_viewport_index_layer");
+		dst.push_back("VK_EXT_scalar_block_layout");
+		dst.push_back("VK_EXT_separate_stencil_usage");
+		dst.push_back("VK_EXT_host_query_reset");
+	}
 	if (coreVersion >= VK_API_VERSION_1_1)
 	{
 		dst.push_back("VK_KHR_multiview");
diff --git a/external/vulkancts/framework/vulkan/vkTypeUtil.inl b/external/vulkancts/framework/vulkan/vkTypeUtil.inl
index c817527..980d114 100644
--- a/external/vulkancts/framework/vulkan/vkTypeUtil.inl
+++ b/external/vulkancts/framework/vulkan/vkTypeUtil.inl
@@ -398,6 +398,16 @@
 	return res;
 }
 
+inline VkConformanceVersion makeConformanceVersion (deUint8 major, deUint8 minor, deUint8 subminor, deUint8 patch)
+{
+	VkConformanceVersion res;
+	res.major		= major;
+	res.minor		= minor;
+	res.subminor	= subminor;
+	res.patch		= patch;
+	return res;
+}
+
 inline VkSurfaceFormatKHR makeSurfaceFormatKHR (VkFormat format, VkColorSpaceKHR colorSpace)
 {
 	VkSurfaceFormatKHR res;
@@ -422,16 +432,6 @@
 	return res;
 }
 
-inline VkConformanceVersionKHR makeConformanceVersionKHR (deUint8 major, deUint8 minor, deUint8 subminor, deUint8 patch)
-{
-	VkConformanceVersionKHR res;
-	res.major		= major;
-	res.minor		= minor;
-	res.subminor	= subminor;
-	res.patch		= patch;
-	return res;
-}
-
 inline VkShaderResourceUsageAMD makeShaderResourceUsageAMD (deUint32 numUsedVgprs, deUint32 numUsedSgprs, deUint32 ldsSizePerLocalWorkGroup, deUintptr ldsUsageSizeInBytes, deUintptr scratchMemUsageInBytes)
 {
 	VkShaderResourceUsageAMD res;
diff --git a/external/vulkancts/framework/vulkan/vkVirtualDeviceInterface.inl b/external/vulkancts/framework/vulkan/vkVirtualDeviceInterface.inl
index 5114558..b570bde 100644
--- a/external/vulkancts/framework/vulkan/vkVirtualDeviceInterface.inl
+++ b/external/vulkancts/framework/vulkan/vkVirtualDeviceInterface.inl
@@ -138,6 +138,19 @@
 virtual void				destroyDescriptorUpdateTemplate					(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator) const = 0;
 virtual void				updateDescriptorSetWithTemplate					(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) const = 0;
 virtual void				getDescriptorSetLayoutSupport					(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport) const = 0;
+virtual void				cmdDrawIndirectCount							(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const = 0;
+virtual void				cmdDrawIndexedIndirectCount						(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const = 0;
+virtual VkResult			createRenderPass2								(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const = 0;
+virtual void				cmdBeginRenderPass2								(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo) const = 0;
+virtual void				cmdNextSubpass2									(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo) const = 0;
+virtual void				cmdEndRenderPass2								(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo) const = 0;
+virtual void				resetQueryPool									(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const = 0;
+virtual VkResult			getSemaphoreCounterValue						(VkDevice device, VkSemaphore semaphore, deUint64* pValue) const = 0;
+virtual VkResult			waitSemaphores									(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout) const = 0;
+virtual VkResult			signalSemaphore									(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) const = 0;
+virtual VkDeviceAddress		getBufferDeviceAddress							(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const = 0;
+virtual uint64_t			getBufferOpaqueCaptureAddress					(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const = 0;
+virtual uint64_t			getDeviceMemoryOpaqueCaptureAddress				(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) const = 0;
 virtual VkResult			createSwapchainKHR								(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) const = 0;
 virtual void				destroySwapchainKHR								(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) const = 0;
 virtual VkResult			getSwapchainImagesKHR							(VkDevice device, VkSwapchainKHR swapchain, deUint32* pSwapchainImageCount, VkImage* pSwapchainImages) const = 0;
@@ -153,23 +166,11 @@
 virtual VkResult			getSemaphoreFdKHR								(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) const = 0;
 virtual void				cmdPushDescriptorSetKHR							(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, deUint32 set, deUint32 descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites) const = 0;
 virtual void				cmdPushDescriptorSetWithTemplateKHR				(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, deUint32 set, const void* pData) const = 0;
-virtual VkResult			createRenderPass2KHR							(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) const = 0;
-virtual void				cmdBeginRenderPass2KHR							(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo) const = 0;
-virtual void				cmdNextSubpass2KHR								(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo) const = 0;
-virtual void				cmdEndRenderPass2KHR							(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo) const = 0;
 virtual VkResult			getSwapchainStatusKHR							(VkDevice device, VkSwapchainKHR swapchain) const = 0;
 virtual VkResult			importFenceFdKHR								(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo) const = 0;
 virtual VkResult			getFenceFdKHR									(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) const = 0;
 virtual VkResult			acquireProfilingLockKHR							(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo) const = 0;
 virtual void				releaseProfilingLockKHR							(VkDevice device) const = 0;
-virtual void				cmdDrawIndirectCountKHR							(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const = 0;
-virtual void				cmdDrawIndexedIndirectCountKHR					(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride) const = 0;
-virtual VkResult			getSemaphoreCounterValueKHR						(VkDevice device, VkSemaphore semaphore, deUint64* pValue) const = 0;
-virtual VkResult			waitSemaphoresKHR								(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout) const = 0;
-virtual VkResult			signalSemaphoreKHR								(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo) const = 0;
-virtual VkDeviceAddress		getBufferDeviceAddressKHR						(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const = 0;
-virtual uint64_t			getBufferOpaqueCaptureAddressKHR				(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const = 0;
-virtual uint64_t			getDeviceMemoryOpaqueCaptureAddressKHR			(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo) const = 0;
 virtual VkResult			getPipelineExecutablePropertiesKHR				(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, deUint32* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) const = 0;
 virtual VkResult			getPipelineExecutableStatisticsKHR				(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics) const = 0;
 virtual VkResult			getPipelineExecutableInternalRepresentationsKHR	(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, deUint32* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) const = 0;
@@ -255,9 +256,8 @@
 virtual VkResult			queueSetPerformanceConfigurationINTEL			(VkQueue queue, VkPerformanceConfigurationINTEL configuration) const = 0;
 virtual VkResult			getPerformanceParameterINTEL					(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue) const = 0;
 virtual void				setLocalDimmingAMD								(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable) const = 0;
-virtual VkDeviceAddress		getBufferDeviceAddressEXT						(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo) const = 0;
+virtual VkDeviceAddress		getBufferDeviceAddressEXT						(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) const = 0;
 virtual void				cmdSetLineStippleEXT							(VkCommandBuffer commandBuffer, deUint32 lineStippleFactor, deUint16 lineStipplePattern) const = 0;
-virtual void				resetQueryPoolEXT								(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount) const = 0;
 virtual VkResult			getAndroidHardwareBufferPropertiesANDROID		(VkDevice device, const struct pt::AndroidHardwareBufferPtr buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties) const = 0;
 virtual VkResult			getMemoryAndroidHardwareBufferANDROID			(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct pt::AndroidHardwareBufferPtr* pBuffer) const = 0;
 virtual VkResult			getMemoryWin32HandleKHR							(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, pt::Win32Handle* pHandle) const = 0;
diff --git a/external/vulkancts/framework/vulkan/vkVirtualInstanceInterface.inl b/external/vulkancts/framework/vulkan/vkVirtualInstanceInterface.inl
index 078a169..34f38ce 100644
--- a/external/vulkancts/framework/vulkan/vkVirtualInstanceInterface.inl
+++ b/external/vulkancts/framework/vulkan/vkVirtualInstanceInterface.inl
@@ -57,6 +57,7 @@
 virtual void		submitDebugUtilsMessageEXT										(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) const = 0;
 virtual void		getPhysicalDeviceMultisamplePropertiesEXT						(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties) const = 0;
 virtual VkResult	getPhysicalDeviceCalibrateableTimeDomainsEXT					(VkPhysicalDevice physicalDevice, deUint32* pTimeDomainCount, VkTimeDomainEXT* pTimeDomains) const = 0;
+virtual VkResult	getPhysicalDeviceToolPropertiesEXT								(VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties) const = 0;
 virtual VkResult	getPhysicalDeviceCooperativeMatrixPropertiesNV					(VkPhysicalDevice physicalDevice, deUint32* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties) const = 0;
 virtual VkResult	getPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV	(VkPhysicalDevice physicalDevice, deUint32* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations) const = 0;
 virtual VkResult	createHeadlessSurfaceEXT										(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) const = 0;
diff --git a/external/vulkancts/framework/vulkan/vkVulkan_c.inl b/external/vulkancts/framework/vulkan/vkVulkan_c.inl
index 2edcad7..3c44775 100644
--- a/external/vulkancts/framework/vulkan/vkVulkan_c.inl
+++ b/external/vulkancts/framework/vulkan/vkVulkan_c.inl
@@ -47,7 +47,7 @@
 #define VK_VERSION_MINOR(version) (((deUint32)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((deUint32)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 129
+#define VK_HEADER_VERSION 130
 
 
 #define VK_NULL_HANDLE 0
@@ -136,8 +136,11 @@
     VK_ERROR_TOO_MANY_OBJECTS = -10,
     VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
     VK_ERROR_FRAGMENTED_POOL = -12,
+    VK_ERROR_UNKNOWN = -13,
     VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000,
     VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003,
+    VK_ERROR_FRAGMENTATION = -1000161000,
+    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000,
     VK_ERROR_SURFACE_LOST_KHR = -1000000000,
     VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
     VK_SUBOPTIMAL_KHR = 1000001003,
@@ -146,16 +149,16 @@
     VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
     VK_ERROR_INVALID_SHADER_NV = -1000012000,
     VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000,
-    VK_ERROR_FRAGMENTATION_EXT = -1000161000,
     VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
     VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000,
-    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = -1000244000,
     VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
     VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
-    VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR,
-    VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
+    VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
+    VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+    VK_RESULT_BEGIN_RANGE = VK_ERROR_UNKNOWN,
     VK_RESULT_END_RANGE = VK_INCOMPLETE,
-    VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1),
+    VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_UNKNOWN + 1),
     VK_RESULT_MAX_ENUM = 0x7FFFFFFF
 } VkResult;
 
@@ -274,6 +277,56 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52,
+    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000,
+    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000,
+    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002,
+    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001,
+    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002,
+    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003,
+    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004,
+    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001,
+    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002,
+    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003,
+    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004,
     VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
     VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
     VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
@@ -333,7 +386,6 @@
     VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
     VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = 1000082000,
     VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
     VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
     VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
@@ -357,17 +409,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001,
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000,
-    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001,
-    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002,
-    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003,
-    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000,
-    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001,
-    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002,
-    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003,
-    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004,
-    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005,
-    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006,
     VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
     VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
     VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
@@ -402,8 +443,6 @@
     VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
     VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
     VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000,
-    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001,
     VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002,
@@ -413,7 +452,6 @@
     VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
     VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
-    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
     VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
@@ -429,11 +467,6 @@
     VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
     VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
     VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
     VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
@@ -454,12 +487,9 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000,
     VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001,
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = 1000175000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
     VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000,
     VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000,
     VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
@@ -470,10 +500,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
     VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000,
     VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000,
-    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
@@ -483,12 +509,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
     VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
     VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = 1000207000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = 1000207001,
-    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = 1000207002,
-    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = 1000207003,
-    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = 1000207004,
-    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = 1000207005,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000,
     VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = 1000210000,
     VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001,
@@ -496,7 +516,6 @@
     VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003,
     VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004,
     VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
     VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000,
     VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001,
@@ -505,7 +524,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
     VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000,
     VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002,
@@ -516,12 +534,9 @@
     VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
     VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = 1000241000,
-    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = 1000241001,
-    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = 1000241002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000,
     VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
-    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
     VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
     VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
@@ -531,20 +546,13 @@
     VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = 1000253000,
     VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000,
     VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
     VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001,
     VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = 1000257000,
-    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = 1000244001,
-    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = 1000257002,
-    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = 1000257003,
-    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = 1000257004,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = 1000261000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000,
     VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001,
@@ -590,10 +598,22 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
     VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
     VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
     VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
     VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
+    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
     VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
     VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
@@ -605,11 +625,14 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES,
     VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
     VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
+    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
     VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
     VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
+    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
     VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
@@ -618,10 +641,41 @@
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
     VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
     VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
+    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
+    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
-    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
     VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
     VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
     VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
@@ -997,16 +1051,20 @@
     VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
+    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000,
+    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001,
+    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002,
+    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003,
     VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
     VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
     VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003,
     VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000,
-    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = 1000241000,
-    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = 1000241001,
-    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = 1000241002,
-    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = 1000241003,
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
+    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
+    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
+    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
     VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
     VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED,
     VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1),
@@ -1454,11 +1512,12 @@
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000,
     VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000,
     VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000,
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000,
-    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000,
     VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000,
     VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT,
     VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT,
     VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT,
@@ -1666,8 +1725,9 @@
     VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
     VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
     VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008,
-    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000010,
-    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
     VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferCreateFlagBits;
 typedef VkFlags VkBufferCreateFlags;
@@ -1682,12 +1742,13 @@
     VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
     VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000,
     VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800,
     VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000,
     VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
     VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400,
-    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000,
-    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
     VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferUsageFlagBits;
 typedef VkFlags VkBufferUsageFlags;
@@ -1785,22 +1846,25 @@
 typedef VkFlags VkSamplerCreateFlags;
 
 typedef enum VkDescriptorSetLayoutCreateFlagBits {
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002,
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
-    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002,
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorSetLayoutCreateFlagBits;
 typedef VkFlags VkDescriptorSetLayoutCreateFlags;
 
 typedef enum VkDescriptorPoolCreateFlagBits {
     VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
-    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002,
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002,
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
     VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorPoolCreateFlagBits;
 typedef VkFlags VkDescriptorPoolCreateFlags;
 typedef VkFlags VkDescriptorPoolResetFlags;
 
 typedef enum VkFramebufferCreateFlagBits {
-    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001,
+    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001,
+    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,
     VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkFramebufferCreateFlagBits;
 typedef VkFlags VkFramebufferCreateFlags;
@@ -4071,9 +4135,11 @@
 
 typedef enum VkMemoryAllocateFlagBits {
     VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001,
-    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = 0x00000002,
-    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000004,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004,
     VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
     VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkMemoryAllocateFlagBits;
 typedef VkFlags VkMemoryAllocateFlags;
@@ -4840,6 +4906,760 @@
 #endif
 
 
+#define VK_VERSION_1_2 1
+// Vulkan 1.2 version number
+#define VK_API_VERSION_1_2 VK_MAKE_VERSION(1, 2, 0)// Patch version should always be set to 0
+
+typedef deUint64 VkDeviceAddress;
+#define VK_MAX_DRIVER_NAME_SIZE           256
+#define VK_MAX_DRIVER_INFO_SIZE           256
+
+typedef enum VkDriverId {
+    VK_DRIVER_ID_AMD_PROPRIETARY = 1,
+    VK_DRIVER_ID_AMD_OPEN_SOURCE = 2,
+    VK_DRIVER_ID_MESA_RADV = 3,
+    VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4,
+    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5,
+    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6,
+    VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7,
+    VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8,
+    VK_DRIVER_ID_ARM_PROPRIETARY = 9,
+    VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10,
+    VK_DRIVER_ID_GGP_PROPRIETARY = 11,
+    VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12,
+    VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
+    VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
+    VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
+    VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY,
+    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
+    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
+    VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
+    VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+    VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY,
+    VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
+    VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY,
+    VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+    VK_DRIVER_ID_BEGIN_RANGE = VK_DRIVER_ID_AMD_PROPRIETARY,
+    VK_DRIVER_ID_END_RANGE = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+    VK_DRIVER_ID_RANGE_SIZE = (VK_DRIVER_ID_BROADCOM_PROPRIETARY - VK_DRIVER_ID_AMD_PROPRIETARY + 1),
+    VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF
+} VkDriverId;
+
+typedef enum VkShaderFloatControlsIndependence {
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_BEGIN_RANGE = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_END_RANGE = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_RANGE_SIZE = (VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY + 1),
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF
+} VkShaderFloatControlsIndependence;
+
+typedef enum VkSamplerReductionMode {
+    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0,
+    VK_SAMPLER_REDUCTION_MODE_MIN = 1,
+    VK_SAMPLER_REDUCTION_MODE_MAX = 2,
+    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+    VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN,
+    VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX,
+    VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+    VK_SAMPLER_REDUCTION_MODE_END_RANGE = VK_SAMPLER_REDUCTION_MODE_MAX,
+    VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE = (VK_SAMPLER_REDUCTION_MODE_MAX - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE + 1),
+    VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerReductionMode;
+
+typedef enum VkSemaphoreType {
+    VK_SEMAPHORE_TYPE_BINARY = 0,
+    VK_SEMAPHORE_TYPE_TIMELINE = 1,
+    VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY,
+    VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE,
+    VK_SEMAPHORE_TYPE_BEGIN_RANGE = VK_SEMAPHORE_TYPE_BINARY,
+    VK_SEMAPHORE_TYPE_END_RANGE = VK_SEMAPHORE_TYPE_TIMELINE,
+    VK_SEMAPHORE_TYPE_RANGE_SIZE = (VK_SEMAPHORE_TYPE_TIMELINE - VK_SEMAPHORE_TYPE_BINARY + 1),
+    VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreType;
+
+typedef enum VkResolveModeFlagBits {
+    VK_RESOLVE_MODE_NONE = 0,
+    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001,
+    VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002,
+    VK_RESOLVE_MODE_MIN_BIT = 0x00000004,
+    VK_RESOLVE_MODE_MAX_BIT = 0x00000008,
+    VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE,
+    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+    VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT,
+    VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT,
+    VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT,
+    VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkResolveModeFlagBits;
+typedef VkFlags VkResolveModeFlags;
+
+typedef enum VkDescriptorBindingFlagBits {
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
+    VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorBindingFlagBits;
+typedef VkFlags VkDescriptorBindingFlags;
+
+typedef enum VkSemaphoreWaitFlagBits {
+    VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001,
+    VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT,
+    VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreWaitFlagBits;
+typedef VkFlags VkSemaphoreWaitFlags;
+typedef struct VkPhysicalDeviceVulkan11Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           storageBuffer16BitAccess;
+    VkBool32           uniformAndStorageBuffer16BitAccess;
+    VkBool32           storagePushConstant16;
+    VkBool32           storageInputOutput16;
+    VkBool32           multiview;
+    VkBool32           multiviewGeometryShader;
+    VkBool32           multiviewTessellationShader;
+    VkBool32           variablePointersStorageBuffer;
+    VkBool32           variablePointers;
+    VkBool32           protectedMemory;
+    VkBool32           samplerYcbcrConversion;
+    VkBool32           shaderDrawParameters;
+} VkPhysicalDeviceVulkan11Features;
+
+typedef struct VkPhysicalDeviceVulkan11Properties {
+    VkStructureType            sType;
+    void*                      pNext;
+    deUint8                    deviceUUID[VK_UUID_SIZE];
+    deUint8                    driverUUID[VK_UUID_SIZE];
+    deUint8                    deviceLUID[VK_LUID_SIZE];
+    deUint32                   deviceNodeMask;
+    VkBool32                   deviceLUIDValid;
+    deUint32                   subgroupSize;
+    VkShaderStageFlags         subgroupSupportedStages;
+    VkSubgroupFeatureFlags     subgroupSupportedOperations;
+    VkBool32                   subgroupQuadOperationsInAllStages;
+    VkPointClippingBehavior    pointClippingBehavior;
+    deUint32                   maxMultiviewViewCount;
+    deUint32                   maxMultiviewInstanceIndex;
+    VkBool32                   protectedNoFault;
+    deUint32                   maxPerSetDescriptors;
+    VkDeviceSize               maxMemoryAllocationSize;
+} VkPhysicalDeviceVulkan11Properties;
+
+typedef struct VkPhysicalDeviceVulkan12Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           samplerMirrorClampToEdge;
+    VkBool32           drawIndirectCount;
+    VkBool32           storageBuffer8BitAccess;
+    VkBool32           uniformAndStorageBuffer8BitAccess;
+    VkBool32           storagePushConstant8;
+    VkBool32           shaderBufferInt64Atomics;
+    VkBool32           shaderSharedInt64Atomics;
+    VkBool32           shaderFloat16;
+    VkBool32           shaderInt8;
+    VkBool32           descriptorIndexing;
+    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
+    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
+    VkBool32           shaderSampledImageArrayNonUniformIndexing;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageImageArrayNonUniformIndexing;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
+    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
+    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
+    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUpdateUnusedWhilePending;
+    VkBool32           descriptorBindingPartiallyBound;
+    VkBool32           descriptorBindingVariableDescriptorCount;
+    VkBool32           runtimeDescriptorArray;
+    VkBool32           samplerFilterMinmax;
+    VkBool32           scalarBlockLayout;
+    VkBool32           imagelessFramebuffer;
+    VkBool32           uniformBufferStandardLayout;
+    VkBool32           shaderSubgroupExtendedTypes;
+    VkBool32           separateDepthStencilLayouts;
+    VkBool32           hostQueryReset;
+    VkBool32           timelineSemaphore;
+    VkBool32           bufferDeviceAddress;
+    VkBool32           bufferDeviceAddressCaptureReplay;
+    VkBool32           bufferDeviceAddressMultiDevice;
+    VkBool32           vulkanMemoryModel;
+    VkBool32           vulkanMemoryModelDeviceScope;
+    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
+    VkBool32           shaderOutputViewportIndex;
+    VkBool32           shaderOutputLayer;
+    VkBool32           subgroupBroadcastDynamicId;
+} VkPhysicalDeviceVulkan12Features;
+
+typedef struct VkConformanceVersion {
+    deUint8    major;
+    deUint8    minor;
+    deUint8    subminor;
+    deUint8    patch;
+} VkConformanceVersion;
+
+typedef struct VkPhysicalDeviceVulkan12Properties {
+    VkStructureType                      sType;
+    void*                                pNext;
+    VkDriverId                           driverID;
+    char                                 driverName[VK_MAX_DRIVER_NAME_SIZE];
+    char                                 driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+    VkConformanceVersion                 conformanceVersion;
+    VkShaderFloatControlsIndependence    denormBehaviorIndependence;
+    VkShaderFloatControlsIndependence    roundingModeIndependence;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat16;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat32;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat64;
+    VkBool32                             shaderDenormPreserveFloat16;
+    VkBool32                             shaderDenormPreserveFloat32;
+    VkBool32                             shaderDenormPreserveFloat64;
+    VkBool32                             shaderDenormFlushToZeroFloat16;
+    VkBool32                             shaderDenormFlushToZeroFloat32;
+    VkBool32                             shaderDenormFlushToZeroFloat64;
+    VkBool32                             shaderRoundingModeRTEFloat16;
+    VkBool32                             shaderRoundingModeRTEFloat32;
+    VkBool32                             shaderRoundingModeRTEFloat64;
+    VkBool32                             shaderRoundingModeRTZFloat16;
+    VkBool32                             shaderRoundingModeRTZFloat32;
+    VkBool32                             shaderRoundingModeRTZFloat64;
+    deUint32                             maxUpdateAfterBindDescriptorsInAllPools;
+    VkBool32                             shaderUniformBufferArrayNonUniformIndexingNative;
+    VkBool32                             shaderSampledImageArrayNonUniformIndexingNative;
+    VkBool32                             shaderStorageBufferArrayNonUniformIndexingNative;
+    VkBool32                             shaderStorageImageArrayNonUniformIndexingNative;
+    VkBool32                             shaderInputAttachmentArrayNonUniformIndexingNative;
+    VkBool32                             robustBufferAccessUpdateAfterBind;
+    VkBool32                             quadDivergentImplicitLod;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindSamplers;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindSampledImages;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindStorageImages;
+    deUint32                             maxPerStageDescriptorUpdateAfterBindInputAttachments;
+    deUint32                             maxPerStageUpdateAfterBindResources;
+    deUint32                             maxDescriptorSetUpdateAfterBindSamplers;
+    deUint32                             maxDescriptorSetUpdateAfterBindUniformBuffers;
+    deUint32                             maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+    deUint32                             maxDescriptorSetUpdateAfterBindStorageBuffers;
+    deUint32                             maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+    deUint32                             maxDescriptorSetUpdateAfterBindSampledImages;
+    deUint32                             maxDescriptorSetUpdateAfterBindStorageImages;
+    deUint32                             maxDescriptorSetUpdateAfterBindInputAttachments;
+    VkResolveModeFlags                   supportedDepthResolveModes;
+    VkResolveModeFlags                   supportedStencilResolveModes;
+    VkBool32                             independentResolveNone;
+    VkBool32                             independentResolve;
+    VkBool32                             filterMinmaxSingleComponentFormats;
+    VkBool32                             filterMinmaxImageComponentMapping;
+    deUint64                             maxTimelineSemaphoreValueDifference;
+    VkSampleCountFlags                   framebufferIntegerColorSampleCounts;
+} VkPhysicalDeviceVulkan12Properties;
+
+typedef struct VkImageFormatListCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    deUint32           viewFormatCount;
+    const VkFormat*    pViewFormats;
+} VkImageFormatListCreateInfo;
+
+typedef struct VkAttachmentDescription2 {
+    VkStructureType                 sType;
+    const void*                     pNext;
+    VkAttachmentDescriptionFlags    flags;
+    VkFormat                        format;
+    VkSampleCountFlagBits           samples;
+    VkAttachmentLoadOp              loadOp;
+    VkAttachmentStoreOp             storeOp;
+    VkAttachmentLoadOp              stencilLoadOp;
+    VkAttachmentStoreOp             stencilStoreOp;
+    VkImageLayout                   initialLayout;
+    VkImageLayout                   finalLayout;
+} VkAttachmentDescription2;
+
+typedef struct VkAttachmentReference2 {
+    VkStructureType       sType;
+    const void*           pNext;
+    deUint32              attachment;
+    VkImageLayout         layout;
+    VkImageAspectFlags    aspectMask;
+} VkAttachmentReference2;
+
+typedef struct VkSubpassDescription2 {
+    VkStructureType                  sType;
+    const void*                      pNext;
+    VkSubpassDescriptionFlags        flags;
+    VkPipelineBindPoint              pipelineBindPoint;
+    deUint32                         viewMask;
+    deUint32                         inputAttachmentCount;
+    const VkAttachmentReference2*    pInputAttachments;
+    deUint32                         colorAttachmentCount;
+    const VkAttachmentReference2*    pColorAttachments;
+    const VkAttachmentReference2*    pResolveAttachments;
+    const VkAttachmentReference2*    pDepthStencilAttachment;
+    deUint32                         preserveAttachmentCount;
+    const deUint32*                  pPreserveAttachments;
+} VkSubpassDescription2;
+
+typedef struct VkSubpassDependency2 {
+    VkStructureType         sType;
+    const void*             pNext;
+    deUint32                srcSubpass;
+    deUint32                dstSubpass;
+    VkPipelineStageFlags    srcStageMask;
+    VkPipelineStageFlags    dstStageMask;
+    VkAccessFlags           srcAccessMask;
+    VkAccessFlags           dstAccessMask;
+    VkDependencyFlags       dependencyFlags;
+    deInt32                 viewOffset;
+} VkSubpassDependency2;
+
+typedef struct VkRenderPassCreateInfo2 {
+    VkStructureType                    sType;
+    const void*                        pNext;
+    VkRenderPassCreateFlags            flags;
+    deUint32                           attachmentCount;
+    const VkAttachmentDescription2*    pAttachments;
+    deUint32                           subpassCount;
+    const VkSubpassDescription2*       pSubpasses;
+    deUint32                           dependencyCount;
+    const VkSubpassDependency2*        pDependencies;
+    deUint32                           correlatedViewMaskCount;
+    const deUint32*                    pCorrelatedViewMasks;
+} VkRenderPassCreateInfo2;
+
+typedef struct VkSubpassBeginInfo {
+    VkStructureType      sType;
+    const void*          pNext;
+    VkSubpassContents    contents;
+} VkSubpassBeginInfo;
+
+typedef struct VkSubpassEndInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+} VkSubpassEndInfo;
+
+typedef struct VkPhysicalDevice8BitStorageFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           storageBuffer8BitAccess;
+    VkBool32           uniformAndStorageBuffer8BitAccess;
+    VkBool32           storagePushConstant8;
+} VkPhysicalDevice8BitStorageFeatures;
+
+typedef struct VkPhysicalDeviceDriverProperties {
+    VkStructureType         sType;
+    void*                   pNext;
+    VkDriverId              driverID;
+    char                    driverName[VK_MAX_DRIVER_NAME_SIZE];
+    char                    driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+    VkConformanceVersion    conformanceVersion;
+} VkPhysicalDeviceDriverProperties;
+
+typedef struct VkPhysicalDeviceShaderAtomicInt64Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderBufferInt64Atomics;
+    VkBool32           shaderSharedInt64Atomics;
+} VkPhysicalDeviceShaderAtomicInt64Features;
+
+typedef struct VkPhysicalDeviceShaderFloat16Int8Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderFloat16;
+    VkBool32           shaderInt8;
+} VkPhysicalDeviceShaderFloat16Int8Features;
+
+typedef struct VkPhysicalDeviceFloatControlsProperties {
+    VkStructureType                      sType;
+    void*                                pNext;
+    VkShaderFloatControlsIndependence    denormBehaviorIndependence;
+    VkShaderFloatControlsIndependence    roundingModeIndependence;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat16;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat32;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat64;
+    VkBool32                             shaderDenormPreserveFloat16;
+    VkBool32                             shaderDenormPreserveFloat32;
+    VkBool32                             shaderDenormPreserveFloat64;
+    VkBool32                             shaderDenormFlushToZeroFloat16;
+    VkBool32                             shaderDenormFlushToZeroFloat32;
+    VkBool32                             shaderDenormFlushToZeroFloat64;
+    VkBool32                             shaderRoundingModeRTEFloat16;
+    VkBool32                             shaderRoundingModeRTEFloat32;
+    VkBool32                             shaderRoundingModeRTEFloat64;
+    VkBool32                             shaderRoundingModeRTZFloat16;
+    VkBool32                             shaderRoundingModeRTZFloat32;
+    VkBool32                             shaderRoundingModeRTZFloat64;
+} VkPhysicalDeviceFloatControlsProperties;
+
+typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo {
+    VkStructureType                    sType;
+    const void*                        pNext;
+    deUint32                           bindingCount;
+    const VkDescriptorBindingFlags*    pBindingFlags;
+} VkDescriptorSetLayoutBindingFlagsCreateInfo;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
+    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
+    VkBool32           shaderSampledImageArrayNonUniformIndexing;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageImageArrayNonUniformIndexing;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
+    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
+    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
+    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUpdateUnusedWhilePending;
+    VkBool32           descriptorBindingPartiallyBound;
+    VkBool32           descriptorBindingVariableDescriptorCount;
+    VkBool32           runtimeDescriptorArray;
+} VkPhysicalDeviceDescriptorIndexingFeatures;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    deUint32           maxUpdateAfterBindDescriptorsInAllPools;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
+    VkBool32           robustBufferAccessUpdateAfterBind;
+    VkBool32           quadDivergentImplicitLod;
+    deUint32           maxPerStageDescriptorUpdateAfterBindSamplers;
+    deUint32           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+    deUint32           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+    deUint32           maxPerStageDescriptorUpdateAfterBindSampledImages;
+    deUint32           maxPerStageDescriptorUpdateAfterBindStorageImages;
+    deUint32           maxPerStageDescriptorUpdateAfterBindInputAttachments;
+    deUint32           maxPerStageUpdateAfterBindResources;
+    deUint32           maxDescriptorSetUpdateAfterBindSamplers;
+    deUint32           maxDescriptorSetUpdateAfterBindUniformBuffers;
+    deUint32           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+    deUint32           maxDescriptorSetUpdateAfterBindStorageBuffers;
+    deUint32           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+    deUint32           maxDescriptorSetUpdateAfterBindSampledImages;
+    deUint32           maxDescriptorSetUpdateAfterBindStorageImages;
+    deUint32           maxDescriptorSetUpdateAfterBindInputAttachments;
+} VkPhysicalDeviceDescriptorIndexingProperties;
+
+typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    deUint32           descriptorSetCount;
+    const deUint32*    pDescriptorCounts;
+} VkDescriptorSetVariableDescriptorCountAllocateInfo;
+
+typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport {
+    VkStructureType    sType;
+    void*              pNext;
+    deUint32           maxVariableDescriptorCount;
+} VkDescriptorSetVariableDescriptorCountLayoutSupport;
+
+typedef struct VkSubpassDescriptionDepthStencilResolve {
+    VkStructureType                  sType;
+    const void*                      pNext;
+    VkResolveModeFlagBits            depthResolveMode;
+    VkResolveModeFlagBits            stencilResolveMode;
+    const VkAttachmentReference2*    pDepthStencilResolveAttachment;
+} VkSubpassDescriptionDepthStencilResolve;
+
+typedef struct VkPhysicalDeviceDepthStencilResolveProperties {
+    VkStructureType       sType;
+    void*                 pNext;
+    VkResolveModeFlags    supportedDepthResolveModes;
+    VkResolveModeFlags    supportedStencilResolveModes;
+    VkBool32              independentResolveNone;
+    VkBool32              independentResolve;
+} VkPhysicalDeviceDepthStencilResolveProperties;
+
+typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           scalarBlockLayout;
+} VkPhysicalDeviceScalarBlockLayoutFeatures;
+
+typedef struct VkImageStencilUsageCreateInfo {
+    VkStructureType      sType;
+    const void*          pNext;
+    VkImageUsageFlags    stencilUsage;
+} VkImageStencilUsageCreateInfo;
+
+typedef struct VkSamplerReductionModeCreateInfo {
+    VkStructureType           sType;
+    const void*               pNext;
+    VkSamplerReductionMode    reductionMode;
+} VkSamplerReductionModeCreateInfo;
+
+typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           filterMinmaxSingleComponentFormats;
+    VkBool32           filterMinmaxImageComponentMapping;
+} VkPhysicalDeviceSamplerFilterMinmaxProperties;
+
+typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           vulkanMemoryModel;
+    VkBool32           vulkanMemoryModelDeviceScope;
+    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
+} VkPhysicalDeviceVulkanMemoryModelFeatures;
+
+typedef struct VkPhysicalDeviceImagelessFramebufferFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           imagelessFramebuffer;
+} VkPhysicalDeviceImagelessFramebufferFeatures;
+
+typedef struct VkFramebufferAttachmentImageInfo {
+    VkStructureType       sType;
+    const void*           pNext;
+    VkImageCreateFlags    flags;
+    VkImageUsageFlags     usage;
+    deUint32              width;
+    deUint32              height;
+    deUint32              layerCount;
+    deUint32              viewFormatCount;
+    const VkFormat*       pViewFormats;
+} VkFramebufferAttachmentImageInfo;
+
+typedef struct VkFramebufferAttachmentsCreateInfo {
+    VkStructureType                            sType;
+    const void*                                pNext;
+    deUint32                                   attachmentImageInfoCount;
+    const VkFramebufferAttachmentImageInfo*    pAttachmentImageInfos;
+} VkFramebufferAttachmentsCreateInfo;
+
+typedef struct VkRenderPassAttachmentBeginInfo {
+    VkStructureType       sType;
+    const void*           pNext;
+    deUint32              attachmentCount;
+    const VkImageView*    pAttachments;
+} VkRenderPassAttachmentBeginInfo;
+
+typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           uniformBufferStandardLayout;
+} VkPhysicalDeviceUniformBufferStandardLayoutFeatures;
+
+typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderSubgroupExtendedTypes;
+} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures;
+
+typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           separateDepthStencilLayouts;
+} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures;
+
+typedef struct VkAttachmentReferenceStencilLayout {
+    VkStructureType    sType;
+    void*              pNext;
+    VkImageLayout      stencilLayout;
+} VkAttachmentReferenceStencilLayout;
+
+typedef struct VkAttachmentDescriptionStencilLayout {
+    VkStructureType    sType;
+    void*              pNext;
+    VkImageLayout      stencilInitialLayout;
+    VkImageLayout      stencilFinalLayout;
+} VkAttachmentDescriptionStencilLayout;
+
+typedef struct VkPhysicalDeviceHostQueryResetFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           hostQueryReset;
+} VkPhysicalDeviceHostQueryResetFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           timelineSemaphore;
+} VkPhysicalDeviceTimelineSemaphoreFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    deUint64           maxTimelineSemaphoreValueDifference;
+} VkPhysicalDeviceTimelineSemaphoreProperties;
+
+typedef struct VkSemaphoreTypeCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkSemaphoreType    semaphoreType;
+    deUint64           initialValue;
+} VkSemaphoreTypeCreateInfo;
+
+typedef struct VkTimelineSemaphoreSubmitInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    deUint32           waitSemaphoreValueCount;
+    const deUint64*    pWaitSemaphoreValues;
+    deUint32           signalSemaphoreValueCount;
+    const deUint64*    pSignalSemaphoreValues;
+} VkTimelineSemaphoreSubmitInfo;
+
+typedef struct VkSemaphoreWaitInfo {
+    VkStructureType         sType;
+    const void*             pNext;
+    VkSemaphoreWaitFlags    flags;
+    deUint32                semaphoreCount;
+    const VkSemaphore*      pSemaphores;
+    const deUint64*         pValues;
+} VkSemaphoreWaitInfo;
+
+typedef struct VkSemaphoreSignalInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkSemaphore        semaphore;
+    deUint64           value;
+} VkSemaphoreSignalInfo;
+
+typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           bufferDeviceAddress;
+    VkBool32           bufferDeviceAddressCaptureReplay;
+    VkBool32           bufferDeviceAddressMultiDevice;
+} VkPhysicalDeviceBufferDeviceAddressFeatures;
+
+typedef struct VkBufferDeviceAddressInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBuffer           buffer;
+} VkBufferDeviceAddressInfo;
+
+typedef struct VkBufferOpaqueCaptureAddressCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    deUint64           opaqueCaptureAddress;
+} VkBufferOpaqueCaptureAddressCreateInfo;
+
+typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    deUint64           opaqueCaptureAddress;
+} VkMemoryOpaqueCaptureAddressAllocateInfo;
+
+typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkDeviceMemory     memory;
+} VkDeviceMemoryOpaqueCaptureAddressInfo;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, deUint32 maxDrawCount, deUint32 stride);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfo*      pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo*      pSubpassBeginInfo, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, deUint64* pValue);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef deUint64 (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef deUint64 (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    deUint32                                    maxDrawCount,
+    deUint32                                    stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    deUint32                                    maxDrawCount,
+    deUint32                                    stride);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2(
+    VkDevice                                    device,
+    const VkRenderPassCreateInfo2*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkResetQueryPool(
+    VkDevice                                    device,
+    VkQueryPool                                 queryPool,
+    deUint32                                    firstQuery,
+    deUint32                                    queryCount);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore,
+    deUint64*                                   pValue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores(
+    VkDevice                                    device,
+    const VkSemaphoreWaitInfo*                  pWaitInfo,
+    deUint64                                    timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore(
+    VkDevice                                    device,
+    const VkSemaphoreSignalInfo*                pSignalInfo);
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress(
+    VkDevice                                    device,
+    const VkBufferDeviceAddressInfo*            pInfo);
+
+VKAPI_ATTR deUint64 VKAPI_CALL vkGetBufferOpaqueCaptureAddress(
+    VkDevice                                    device,
+    const VkBufferDeviceAddressInfo*            pInfo);
+
+VKAPI_ATTR deUint64 VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress(
+    VkDevice                                    device,
+    const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+#endif
+
+
 #define VK_KHR_surface 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
 #define VK_KHR_SURFACE_SPEC_VERSION       25
@@ -5627,14 +6447,9 @@
 #define VK_KHR_shader_float16_int8 1
 #define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1
 #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8"
-typedef struct VkPhysicalDeviceShaderFloat16Int8FeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderFloat16;
-    VkBool32           shaderInt8;
-} VkPhysicalDeviceShaderFloat16Int8FeaturesKHR;
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR;
 
-typedef VkPhysicalDeviceShaderFloat16Int8FeaturesKHR VkPhysicalDeviceFloat16Int8FeaturesKHR;
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR;
 
 
 
@@ -5708,144 +6523,58 @@
 #define VK_KHR_imageless_framebuffer 1
 #define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1
 #define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer"
-typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           imagelessFramebuffer;
-} VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
+typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
 
-typedef struct VkFramebufferAttachmentImageInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    VkImageCreateFlags    flags;
-    VkImageUsageFlags     usage;
-    deUint32              width;
-    deUint32              height;
-    deUint32              layerCount;
-    deUint32              viewFormatCount;
-    const VkFormat*       pViewFormats;
-} VkFramebufferAttachmentImageInfoKHR;
+typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR;
 
-typedef struct VkFramebufferAttachmentsCreateInfoKHR {
-    VkStructureType                               sType;
-    const void*                                   pNext;
-    deUint32                                      attachmentImageInfoCount;
-    const VkFramebufferAttachmentImageInfoKHR*    pAttachmentImageInfos;
-} VkFramebufferAttachmentsCreateInfoKHR;
+typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR;
 
-typedef struct VkRenderPassAttachmentBeginInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    deUint32              attachmentCount;
-    const VkImageView*    pAttachments;
-} VkRenderPassAttachmentBeginInfoKHR;
+typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR;
 
 
 
 #define VK_KHR_create_renderpass2 1
 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1
 #define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2"
-typedef struct VkAttachmentDescription2KHR {
-    VkStructureType                 sType;
-    const void*                     pNext;
-    VkAttachmentDescriptionFlags    flags;
-    VkFormat                        format;
-    VkSampleCountFlagBits           samples;
-    VkAttachmentLoadOp              loadOp;
-    VkAttachmentStoreOp             storeOp;
-    VkAttachmentLoadOp              stencilLoadOp;
-    VkAttachmentStoreOp             stencilStoreOp;
-    VkImageLayout                   initialLayout;
-    VkImageLayout                   finalLayout;
-} VkAttachmentDescription2KHR;
+typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR;
 
-typedef struct VkAttachmentReference2KHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    deUint32              attachment;
-    VkImageLayout         layout;
-    VkImageAspectFlags    aspectMask;
-} VkAttachmentReference2KHR;
+typedef VkAttachmentDescription2 VkAttachmentDescription2KHR;
 
-typedef struct VkSubpassDescription2KHR {
-    VkStructureType                     sType;
-    const void*                         pNext;
-    VkSubpassDescriptionFlags           flags;
-    VkPipelineBindPoint                 pipelineBindPoint;
-    deUint32                            viewMask;
-    deUint32                            inputAttachmentCount;
-    const VkAttachmentReference2KHR*    pInputAttachments;
-    deUint32                            colorAttachmentCount;
-    const VkAttachmentReference2KHR*    pColorAttachments;
-    const VkAttachmentReference2KHR*    pResolveAttachments;
-    const VkAttachmentReference2KHR*    pDepthStencilAttachment;
-    deUint32                            preserveAttachmentCount;
-    const deUint32*                     pPreserveAttachments;
-} VkSubpassDescription2KHR;
+typedef VkAttachmentReference2 VkAttachmentReference2KHR;
 
-typedef struct VkSubpassDependency2KHR {
-    VkStructureType         sType;
-    const void*             pNext;
-    deUint32                srcSubpass;
-    deUint32                dstSubpass;
-    VkPipelineStageFlags    srcStageMask;
-    VkPipelineStageFlags    dstStageMask;
-    VkAccessFlags           srcAccessMask;
-    VkAccessFlags           dstAccessMask;
-    VkDependencyFlags       dependencyFlags;
-    deInt32                 viewOffset;
-} VkSubpassDependency2KHR;
+typedef VkSubpassDescription2 VkSubpassDescription2KHR;
 
-typedef struct VkRenderPassCreateInfo2KHR {
-    VkStructureType                       sType;
-    const void*                           pNext;
-    VkRenderPassCreateFlags               flags;
-    deUint32                              attachmentCount;
-    const VkAttachmentDescription2KHR*    pAttachments;
-    deUint32                              subpassCount;
-    const VkSubpassDescription2KHR*       pSubpasses;
-    deUint32                              dependencyCount;
-    const VkSubpassDependency2KHR*        pDependencies;
-    deUint32                              correlatedViewMaskCount;
-    const deUint32*                       pCorrelatedViewMasks;
-} VkRenderPassCreateInfo2KHR;
+typedef VkSubpassDependency2 VkSubpassDependency2KHR;
 
-typedef struct VkSubpassBeginInfoKHR {
-    VkStructureType      sType;
-    const void*          pNext;
-    VkSubpassContents    contents;
-} VkSubpassBeginInfoKHR;
+typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR;
 
-typedef struct VkSubpassEndInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-} VkSubpassEndInfoKHR;
+typedef VkSubpassEndInfo VkSubpassEndInfoKHR;
 
-typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
-typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo);
-typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
-typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfo*      pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo*      pSubpassBeginInfo, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo*        pSubpassEndInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(
     VkDevice                                    device,
-    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+    const VkRenderPassCreateInfo2*              pCreateInfo,
     const VkAllocationCallbacks*                pAllocator,
     VkRenderPass*                               pRenderPass);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR(
     VkCommandBuffer                             commandBuffer,
     const VkRenderPassBeginInfo*                pRenderPassBegin,
-    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo);
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR(
     VkCommandBuffer                             commandBuffer,
-    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
-    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR(
     VkCommandBuffer                             commandBuffer,
-    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
 #endif
 
 
@@ -5960,12 +6689,15 @@
 } VkPerformanceCounterUnitKHR;
 
 typedef enum VkPerformanceCounterScopeKHR {
-    VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = 0,
-    VK_QUERY_SCOPE_RENDER_PASS_KHR = 1,
-    VK_QUERY_SCOPE_COMMAND_KHR = 2,
-    VK_PERFORMANCE_COUNTER_SCOPE_BEGIN_RANGE_KHR = VK_QUERY_SCOPE_COMMAND_BUFFER_KHR,
-    VK_PERFORMANCE_COUNTER_SCOPE_END_RANGE_KHR = VK_QUERY_SCOPE_COMMAND_KHR,
-    VK_PERFORMANCE_COUNTER_SCOPE_RANGE_SIZE_KHR = (VK_QUERY_SCOPE_COMMAND_KHR - VK_QUERY_SCOPE_COMMAND_BUFFER_KHR + 1),
+    VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0,
+    VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1,
+    VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2,
+    VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+    VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR,
+    VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_BEGIN_RANGE_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_END_RANGE_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_RANGE_SIZE_KHR = (VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR - VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR + 1),
     VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF
 } VkPerformanceCounterScopeKHR;
 
@@ -6266,12 +6998,7 @@
 #define VK_KHR_image_format_list 1
 #define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1
 #define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list"
-typedef struct VkImageFormatListCreateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    deUint32           viewFormatCount;
-    const VkFormat*    pViewFormats;
-} VkImageFormatListCreateInfoKHR;
+typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR;
 
 
 
@@ -6385,36 +7112,21 @@
 #define VK_KHR_shader_subgroup_extended_types 1
 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1
 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types"
-typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderSubgroupExtendedTypes;
-} VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
+typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
 
 
 
 #define VK_KHR_8bit_storage 1
 #define VK_KHR_8BIT_STORAGE_SPEC_VERSION  1
 #define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
-typedef struct VkPhysicalDevice8BitStorageFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           storageBuffer8BitAccess;
-    VkBool32           uniformAndStorageBuffer8BitAccess;
-    VkBool32           storagePushConstant8;
-} VkPhysicalDevice8BitStorageFeaturesKHR;
+typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR;
 
 
 
 #define VK_KHR_shader_atomic_int64 1
 #define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1
 #define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64"
-typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderBufferInt64Atomics;
-    VkBool32           shaderSharedInt64Atomics;
-} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
+typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
 
 
 
@@ -6431,113 +7143,37 @@
 
 
 #define VK_KHR_driver_properties 1
-#define VK_MAX_DRIVER_NAME_SIZE_KHR       256
-#define VK_MAX_DRIVER_INFO_SIZE_KHR       256
 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1
 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties"
+#define VK_MAX_DRIVER_NAME_SIZE_KHR       VK_MAX_DRIVER_NAME_SIZE
+#define VK_MAX_DRIVER_INFO_SIZE_KHR       VK_MAX_DRIVER_INFO_SIZE
+typedef VkDriverId VkDriverIdKHR;
 
-typedef enum VkDriverIdKHR {
-    VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1,
-    VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2,
-    VK_DRIVER_ID_MESA_RADV_KHR = 3,
-    VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4,
-    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5,
-    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6,
-    VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
-    VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
-    VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
-    VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = 10,
-    VK_DRIVER_ID_GGP_PROPRIETARY_KHR = 11,
-    VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = 12,
-    VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR,
-    VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR,
-    VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1),
-    VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkDriverIdKHR;
-typedef struct VkConformanceVersionKHR {
-    deUint8    major;
-    deUint8    minor;
-    deUint8    subminor;
-    deUint8    patch;
-} VkConformanceVersionKHR;
+typedef VkConformanceVersion VkConformanceVersionKHR;
 
-typedef struct VkPhysicalDeviceDriverPropertiesKHR {
-    VkStructureType            sType;
-    void*                      pNext;
-    VkDriverIdKHR              driverID;
-    char                       driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
-    char                       driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
-    VkConformanceVersionKHR    conformanceVersion;
-} VkPhysicalDeviceDriverPropertiesKHR;
+typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR;
 
 
 
 #define VK_KHR_shader_float_controls 1
 #define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4
 #define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls"
+typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR;
 
-typedef enum VkShaderFloatControlsIndependenceKHR {
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = 0,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = 1,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = 2,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_BEGIN_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_END_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_RANGE_SIZE_KHR = (VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR + 1),
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkShaderFloatControlsIndependenceKHR;
-typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR {
-    VkStructureType                         sType;
-    void*                                   pNext;
-    VkShaderFloatControlsIndependenceKHR    denormBehaviorIndependence;
-    VkShaderFloatControlsIndependenceKHR    roundingModeIndependence;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat16;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat32;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat64;
-    VkBool32                                shaderDenormPreserveFloat16;
-    VkBool32                                shaderDenormPreserveFloat32;
-    VkBool32                                shaderDenormPreserveFloat64;
-    VkBool32                                shaderDenormFlushToZeroFloat16;
-    VkBool32                                shaderDenormFlushToZeroFloat32;
-    VkBool32                                shaderDenormFlushToZeroFloat64;
-    VkBool32                                shaderRoundingModeRTEFloat16;
-    VkBool32                                shaderRoundingModeRTEFloat32;
-    VkBool32                                shaderRoundingModeRTEFloat64;
-    VkBool32                                shaderRoundingModeRTZFloat16;
-    VkBool32                                shaderRoundingModeRTZFloat32;
-    VkBool32                                shaderRoundingModeRTZFloat64;
-} VkPhysicalDeviceFloatControlsPropertiesKHR;
+typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR;
 
 
 
 #define VK_KHR_depth_stencil_resolve 1
 #define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1
 #define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve"
+typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR;
 
-typedef enum VkResolveModeFlagBitsKHR {
-    VK_RESOLVE_MODE_NONE_KHR = 0,
-    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001,
-    VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002,
-    VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004,
-    VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008,
-    VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkResolveModeFlagBitsKHR;
-typedef VkFlags VkResolveModeFlagsKHR;
-typedef struct VkSubpassDescriptionDepthStencilResolveKHR {
-    VkStructureType                     sType;
-    const void*                         pNext;
-    VkResolveModeFlagBitsKHR            depthResolveMode;
-    VkResolveModeFlagBitsKHR            stencilResolveMode;
-    const VkAttachmentReference2KHR*    pDepthStencilResolveAttachment;
-} VkSubpassDescriptionDepthStencilResolveKHR;
+typedef VkResolveModeFlags VkResolveModeFlagsKHR;
 
-typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR {
-    VkStructureType          sType;
-    void*                    pNext;
-    VkResolveModeFlagsKHR    supportedDepthResolveModes;
-    VkResolveModeFlagsKHR    supportedStencilResolveModes;
-    VkBool32                 independentResolveNone;
-    VkBool32                 independentResolve;
-} VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
+typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR;
+
+typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
 
 
 
@@ -6549,68 +7185,27 @@
 #define VK_KHR_timeline_semaphore 1
 #define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2
 #define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore"
+typedef VkSemaphoreType VkSemaphoreTypeKHR;
 
-typedef enum VkSemaphoreTypeKHR {
-    VK_SEMAPHORE_TYPE_BINARY_KHR = 0,
-    VK_SEMAPHORE_TYPE_TIMELINE_KHR = 1,
-    VK_SEMAPHORE_TYPE_BEGIN_RANGE_KHR = VK_SEMAPHORE_TYPE_BINARY_KHR,
-    VK_SEMAPHORE_TYPE_END_RANGE_KHR = VK_SEMAPHORE_TYPE_TIMELINE_KHR,
-    VK_SEMAPHORE_TYPE_RANGE_SIZE_KHR = (VK_SEMAPHORE_TYPE_TIMELINE_KHR - VK_SEMAPHORE_TYPE_BINARY_KHR + 1),
-    VK_SEMAPHORE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkSemaphoreTypeKHR;
+typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR;
 
-typedef enum VkSemaphoreWaitFlagBitsKHR {
-    VK_SEMAPHORE_WAIT_ANY_BIT_KHR = 0x00000001,
-    VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkSemaphoreWaitFlagBitsKHR;
-typedef VkFlags VkSemaphoreWaitFlagsKHR;
-typedef struct VkPhysicalDeviceTimelineSemaphoreFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           timelineSemaphore;
-} VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
+typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR;
 
-typedef struct VkPhysicalDeviceTimelineSemaphorePropertiesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    deUint64           maxTimelineSemaphoreValueDifference;
-} VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
+typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
 
-typedef struct VkSemaphoreTypeCreateInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    VkSemaphoreTypeKHR    semaphoreType;
-    deUint64              initialValue;
-} VkSemaphoreTypeCreateInfoKHR;
+typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
 
-typedef struct VkTimelineSemaphoreSubmitInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    deUint32           waitSemaphoreValueCount;
-    const deUint64*    pWaitSemaphoreValues;
-    deUint32           signalSemaphoreValueCount;
-    const deUint64*    pSignalSemaphoreValues;
-} VkTimelineSemaphoreSubmitInfoKHR;
+typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR;
 
-typedef struct VkSemaphoreWaitInfoKHR {
-    VkStructureType            sType;
-    const void*                pNext;
-    VkSemaphoreWaitFlagsKHR    flags;
-    deUint32                   semaphoreCount;
-    const VkSemaphore*         pSemaphores;
-    const deUint64*            pValues;
-} VkSemaphoreWaitInfoKHR;
+typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR;
 
-typedef struct VkSemaphoreSignalInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkSemaphore        semaphore;
-    deUint64           value;
-} VkSemaphoreSignalInfoKHR;
+typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR;
+
+typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR;
 
 typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, deUint64* pValue);
-typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, deUint64 timeout);
-typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, deUint64 timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR(
@@ -6620,25 +7215,19 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR(
     VkDevice                                    device,
-    const VkSemaphoreWaitInfoKHR*               pWaitInfo,
+    const VkSemaphoreWaitInfo*                  pWaitInfo,
     deUint64                                    timeout);
 
 VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR(
     VkDevice                                    device,
-    const VkSemaphoreSignalInfoKHR*             pSignalInfo);
+    const VkSemaphoreSignalInfo*                pSignalInfo);
 #endif
 
 
 #define VK_KHR_vulkan_memory_model 1
 #define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3
 #define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model"
-typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           vulkanMemoryModel;
-    VkBool32           vulkanMemoryModelDeviceScope;
-    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
-} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
+typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
 
 
 
@@ -6661,90 +7250,50 @@
 #define VK_KHR_separate_depth_stencil_layouts 1
 #define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1
 #define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts"
-typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           separateDepthStencilLayouts;
-} VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
+typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
 
-typedef struct VkAttachmentReferenceStencilLayoutKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkImageLayout      stencilLayout;
-} VkAttachmentReferenceStencilLayoutKHR;
+typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR;
 
-typedef struct VkAttachmentDescriptionStencilLayoutKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkImageLayout      stencilInitialLayout;
-    VkImageLayout      stencilFinalLayout;
-} VkAttachmentDescriptionStencilLayoutKHR;
+typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR;
 
 
 
 #define VK_KHR_uniform_buffer_standard_layout 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout"
-typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           uniformBufferStandardLayout;
-} VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
+typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
 
 
 
 #define VK_KHR_buffer_device_address 1
-typedef deUint64 VkDeviceAddress;
 #define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1
 #define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address"
-typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           bufferDeviceAddress;
-    VkBool32           bufferDeviceAddressCaptureReplay;
-    VkBool32           bufferDeviceAddressMultiDevice;
-} VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
+typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
 
-typedef struct VkBufferDeviceAddressInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkBuffer           buffer;
-} VkBufferDeviceAddressInfoKHR;
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR;
 
-typedef struct VkBufferOpaqueCaptureAddressCreateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    deUint64           opaqueCaptureAddress;
-} VkBufferOpaqueCaptureAddressCreateInfoKHR;
+typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR;
 
-typedef struct VkMemoryOpaqueCaptureAddressAllocateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    deUint64           opaqueCaptureAddress;
-} VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
+typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
 
-typedef struct VkDeviceMemoryOpaqueCaptureAddressInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkDeviceMemory     memory;
-} VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
+typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
 
-typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef deUint64 (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef deUint64 (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef deUint64 (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef deUint64 (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
 
 VKAPI_ATTR deUint64 VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
 
 VKAPI_ATTR deUint64 VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR(
     VkDevice                                    device,
-    const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo);
+    const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 #endif
 
 
@@ -8241,28 +8790,11 @@
 #define VK_EXT_sampler_filter_minmax 1
 #define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2
 #define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax"
+typedef VkSamplerReductionMode VkSamplerReductionModeEXT;
 
-typedef enum VkSamplerReductionModeEXT {
-    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0,
-    VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1,
-    VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2,
-    VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT,
-    VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT,
-    VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1),
-    VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkSamplerReductionModeEXT;
-typedef struct VkSamplerReductionModeCreateInfoEXT {
-    VkStructureType              sType;
-    const void*                  pNext;
-    VkSamplerReductionModeEXT    reductionMode;
-} VkSamplerReductionModeCreateInfoEXT;
+typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT;
 
-typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           filterMinmaxSingleComponentFormats;
-    VkBool32           filterMinmaxImageComponentMapping;
-} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
+typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
 
 
 
@@ -8621,87 +9153,19 @@
 #define VK_EXT_descriptor_indexing 1
 #define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
 #define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT;
 
-typedef enum VkDescriptorBindingFlagBitsEXT {
-    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001,
-    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002,
-    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004,
-    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
-    VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkDescriptorBindingFlagBitsEXT;
-typedef VkFlags VkDescriptorBindingFlagsEXT;
-typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
-    VkStructureType                       sType;
-    const void*                           pNext;
-    deUint32                              bindingCount;
-    const VkDescriptorBindingFlagsEXT*    pBindingFlags;
-} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT;
 
-typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
-    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
-    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
-    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
-    VkBool32           shaderSampledImageArrayNonUniformIndexing;
-    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
-    VkBool32           shaderStorageImageArrayNonUniformIndexing;
-    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
-    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
-    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
-    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
-    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
-    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
-    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
-    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
-    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
-    VkBool32           descriptorBindingUpdateUnusedWhilePending;
-    VkBool32           descriptorBindingPartiallyBound;
-    VkBool32           descriptorBindingVariableDescriptorCount;
-    VkBool32           runtimeDescriptorArray;
-} VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
 
-typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    deUint32           maxUpdateAfterBindDescriptorsInAllPools;
-    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
-    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
-    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
-    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
-    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
-    VkBool32           robustBufferAccessUpdateAfterBind;
-    VkBool32           quadDivergentImplicitLod;
-    deUint32           maxPerStageDescriptorUpdateAfterBindSamplers;
-    deUint32           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
-    deUint32           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
-    deUint32           maxPerStageDescriptorUpdateAfterBindSampledImages;
-    deUint32           maxPerStageDescriptorUpdateAfterBindStorageImages;
-    deUint32           maxPerStageDescriptorUpdateAfterBindInputAttachments;
-    deUint32           maxPerStageUpdateAfterBindResources;
-    deUint32           maxDescriptorSetUpdateAfterBindSamplers;
-    deUint32           maxDescriptorSetUpdateAfterBindUniformBuffers;
-    deUint32           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
-    deUint32           maxDescriptorSetUpdateAfterBindStorageBuffers;
-    deUint32           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
-    deUint32           maxDescriptorSetUpdateAfterBindSampledImages;
-    deUint32           maxDescriptorSetUpdateAfterBindStorageImages;
-    deUint32           maxDescriptorSetUpdateAfterBindInputAttachments;
-} VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
 
-typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
-    VkStructureType    sType;
-    const void*        pNext;
-    deUint32           descriptorSetCount;
-    const deUint32*    pDescriptorCounts;
-} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
 
-typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    deUint32           maxVariableDescriptorCount;
-} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
 
 
 
@@ -9134,7 +9598,7 @@
 
 
 #define VK_EXT_filter_cubic 1
-#define VK_EXT_FILTER_CUBIC_SPEC_VERSION  2
+#define VK_EXT_FILTER_CUBIC_SPEC_VERSION  3
 #define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic"
 typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT {
     VkStructureType    sType;
@@ -9146,7 +9610,7 @@
     VkStructureType    sType;
     void*              pNext;
     VkBool32           filterCubic;
-    VkBool32           filterCubicMinmax ;
+    VkBool32           filterCubicMinmax;
 } VkFilterCubicImageViewImageFormatPropertiesEXT;
 
 
@@ -9765,11 +10229,7 @@
 #define VK_EXT_scalar_block_layout 1
 #define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1
 #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
-typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           scalarBlockLayout;
-} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
+typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
 
 
 
@@ -9891,7 +10351,7 @@
 
 typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT;
 
-typedef VkBufferDeviceAddressInfoKHR VkBufferDeviceAddressInfoEXT;
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT;
 
 typedef struct VkBufferDeviceAddressCreateInfoEXT {
     VkStructureType    sType;
@@ -9899,23 +10359,54 @@
     VkDeviceAddress    deviceAddress;
 } VkBufferDeviceAddressCreateInfoEXT;
 
-typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
+#endif
+
+
+#define VK_EXT_tooling_info 1
+#define VK_EXT_TOOLING_INFO_SPEC_VERSION  1
+#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info"
+
+typedef enum VkToolPurposeFlagBitsEXT {
+    VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001,
+    VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002,
+    VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004,
+    VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008,
+    VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010,
+    VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020,
+    VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040,
+    VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkToolPurposeFlagBitsEXT;
+typedef VkFlags VkToolPurposeFlagsEXT;
+typedef struct VkPhysicalDeviceToolPropertiesEXT {
+    VkStructureType          sType;
+    void*                    pNext;
+    char                     name[VK_MAX_EXTENSION_NAME_SIZE];
+    char                     version[VK_MAX_EXTENSION_NAME_SIZE];
+    VkToolPurposeFlagsEXT    purposes;
+    char                     description[VK_MAX_DESCRIPTION_SIZE];
+    char                     layer[VK_MAX_EXTENSION_NAME_SIZE];
+} VkPhysicalDeviceToolPropertiesEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, deUint32* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT(
+    VkPhysicalDevice                            physicalDevice,
+    deUint32*                                   pToolCount,
+    VkPhysicalDeviceToolPropertiesEXT*          pToolProperties);
 #endif
 
 
 #define VK_EXT_separate_stencil_usage 1
 #define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
 #define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage"
-typedef struct VkImageStencilUsageCreateInfoEXT {
-    VkStructureType      sType;
-    const void*          pNext;
-    VkImageUsageFlags    stencilUsage;
-} VkImageStencilUsageCreateInfoEXT;
+typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT;
 
 
 
@@ -10168,11 +10659,7 @@
 #define VK_EXT_host_query_reset 1
 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1
 #define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset"
-typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           hostQueryReset;
-} VkPhysicalDeviceHostQueryResetFeaturesEXT;
+typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT;
 
 typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount);
 
diff --git a/external/vulkancts/framework/vulkan/vkWsiUtil.cpp b/external/vulkancts/framework/vulkan/vkWsiUtil.cpp
index d9a8a80..3dbffb2 100644
--- a/external/vulkancts/framework/vulkan/vkWsiUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkWsiUtil.cpp
@@ -21,11 +21,28 @@
  * \brief Windowing System Integration (WSI) Utilities.
  *//*--------------------------------------------------------------------*/
 
+#include "vkRefUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkQueryUtil.hpp"
 #include "vkWsiUtil.hpp"
+#include "vkBarrierUtil.hpp"
+
 #include "deArrayUtil.hpp"
 #include "deMemory.h"
 
 #include <limits>
+#include <vector>
+
+using std::vector;
+
+#if defined (DEQP_SUPPORT_X11)
+#	include <X11/Xlib.h>
+#	if defined (DEQP_SUPPORT_XCB)
+#		include <xcb/xcb.h>
+#	endif // DEQP_SUPPORT_XCB
+#endif // DEQP_SUPPORT_X11
 
 namespace vk
 {
@@ -255,6 +272,56 @@
 	return result;
 }
 
+VkBool32 getPhysicalDevicePresentationSupport (const InstanceInterface&	vki,
+											   VkPhysicalDevice			physicalDevice,
+											   deUint32					queueFamilyIndex,
+											   Type						wsiType,
+											   const Display&			nativeDisplay)
+{
+	switch (wsiType)
+	{
+		case TYPE_XLIB:
+		{
+			const XlibDisplayInterface&		xlibDisplay	= dynamic_cast<const XlibDisplayInterface&>(nativeDisplay);
+			pt::XlibVisualID				visualID	(0U);
+#if defined (DEQP_SUPPORT_X11)
+			::Display*						displayPtr	= (::Display*)(xlibDisplay.getNative().internal);
+			visualID.internal							= (deUint32)(::XDefaultVisual(displayPtr,0)->visualid);
+#endif
+			return vki.getPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, xlibDisplay.getNative(), visualID);
+		}
+		case TYPE_XCB:
+		{
+			const XcbDisplayInterface&		xcbDisplay	= dynamic_cast<const XcbDisplayInterface&>(nativeDisplay);
+			pt::XcbVisualid					visualID	(0U);
+#if defined (DEQP_SUPPORT_XCB)
+			xcb_connection_t*				connPtr		= (xcb_connection_t*)(xcbDisplay.getNative().internal);
+			xcb_screen_t*					screen		= xcb_setup_roots_iterator(xcb_get_setup(connPtr)).data;
+			visualID.internal							= (deUint32)(screen->root_visual);
+#endif
+			return vki.getPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, xcbDisplay.getNative(), visualID);
+		}
+		case TYPE_WAYLAND:
+		{
+			const WaylandDisplayInterface&	waylandDisplay	= dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay);
+			return vki.getPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, waylandDisplay.getNative());
+		}
+		case TYPE_WIN32:
+		{
+			return vki.getPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
+		}
+		case TYPE_ANDROID:
+		case TYPE_MACOS:
+		{
+			return 1;
+		}
+		default:
+			DE_FATAL("Unknown WSI type");
+			return 0;
+	}
+	return 1;
+}
+
 VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface&		vki,
 															   VkPhysicalDevice				physicalDevice,
 															   VkSurfaceKHR					surface)
@@ -268,6 +335,38 @@
 	return capabilities;
 }
 
+VkSurfaceCapabilities2EXT getPhysicalDeviceSurfaceCapabilities2EXT (const InstanceInterface&		vki,
+																	VkPhysicalDevice				physicalDevice,
+																	VkSurfaceKHR					surface)
+{
+	VkSurfaceCapabilities2EXT capabilities;
+
+	deMemset(&capabilities, 0, sizeof(capabilities));
+	capabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT;
+
+	VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, &capabilities));
+
+	return capabilities;
+}
+
+bool sameSurfaceCapabilities (const VkSurfaceCapabilitiesKHR&	khr,
+							  const VkSurfaceCapabilities2EXT&	ext)
+{
+	return (	khr.minImageCount			== ext.minImageCount &&
+				khr.maxImageCount			== ext.maxImageCount &&
+				khr.currentExtent.width		== ext.currentExtent.width &&
+				khr.currentExtent.height	== ext.currentExtent.height &&
+				khr.minImageExtent.width	== ext.minImageExtent.width &&
+				khr.minImageExtent.height	== ext.minImageExtent.height &&
+				khr.maxImageExtent.width	== ext.maxImageExtent.width &&
+				khr.maxImageExtent.height	== ext.maxImageExtent.height &&
+				khr.maxImageArrayLayers		== ext.maxImageArrayLayers &&
+				khr.supportedTransforms		== ext.supportedTransforms &&
+				khr.currentTransform		== ext.currentTransform &&
+				khr.supportedCompositeAlpha	== ext.supportedCompositeAlpha &&
+				khr.supportedUsageFlags		== ext.supportedUsageFlags	);
+}
+
 std::vector<VkSurfaceFormatKHR> getPhysicalDeviceSurfaceFormats (const InstanceInterface&		vki,
 																 VkPhysicalDevice				physicalDevice,
 																 VkSurfaceKHR					surface)
@@ -328,5 +427,502 @@
 		return std::vector<VkImage>();
 }
 
+namespace
+{
+
+std::vector<deUint32> getSupportedQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
+{
+	deUint32 numTotalFamilyIndices;
+	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, DE_NULL);
+
+	std::vector<VkQueueFamilyProperties> queueFamilyProperties(numTotalFamilyIndices);
+	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, &queueFamilyProperties[0]);
+
+	std::vector<deUint32> supportedFamilyIndices;
+	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
+	{
+		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
+			supportedFamilyIndices.push_back(queueFamilyNdx);
+	}
+
+	return supportedFamilyIndices;
+}
+
+std::vector<deUint32> getSortedSupportedQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
+{
+	std::vector<deUint32> indices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
+	std::sort(begin(indices), end(indices));
+	return indices;
+}
+
+} // anonymous
+
+deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, const std::vector<vk::VkSurfaceKHR>& surfaces)
+{
+	auto indices = getCompatibleQueueFamilyIndices(vki, physicalDevice, surfaces);
+
+	if (indices.empty())
+		TCU_THROW(NotSupportedError, "Device does not support presentation to the given surfaces");
+
+	return indices[0];
+}
+
+deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
+{
+	return chooseQueueFamilyIndex(vki, physicalDevice, std::vector<vk::VkSurfaceKHR>(1u, surface));
+}
+
+std::vector<deUint32> getCompatibleQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const std::vector<VkSurfaceKHR>& surfaces)
+{
+	DE_ASSERT(!surfaces.empty());
+
+	auto indices = getSortedSupportedQueueFamilyIndices(vki, physicalDevice, surfaces[0]);
+
+	for (size_t i = 1; i < surfaces.size(); ++i)
+	{
+		auto newIndices = getSortedSupportedQueueFamilyIndices(vki, physicalDevice, surfaces[i]);
+
+		// Set intersection and overwrite.
+		decltype(indices) intersection;
+		std::set_intersection(begin(indices), end(indices), begin(newIndices), end(newIndices), std::back_inserter(intersection));
+		indices = std::move(intersection);
+	}
+
+	return indices;
+}
+
+Move<VkRenderPass> WsiTriangleRenderer::createRenderPass (const DeviceInterface&	vkd,
+														  const VkDevice			device,
+														  const VkFormat			colorAttachmentFormat,
+														  const bool				explicitLayoutTransitions)
+{
+	const VkAttachmentDescription	colorAttDesc		=
+	{
+		(VkAttachmentDescriptionFlags)0,
+		colorAttachmentFormat,
+		VK_SAMPLE_COUNT_1_BIT,
+		VK_ATTACHMENT_LOAD_OP_CLEAR,
+		VK_ATTACHMENT_STORE_OP_STORE,
+		VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+		VK_ATTACHMENT_STORE_OP_DONT_CARE,
+		(explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+		(explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+	};
+	const VkAttachmentReference		colorAttRef			=
+	{
+		0u,
+		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+	};
+	const VkSubpassDescription		subpassDesc			=
+	{
+		(VkSubpassDescriptionFlags)0u,
+		VK_PIPELINE_BIND_POINT_GRAPHICS,
+		0u,							// inputAttachmentCount
+		DE_NULL,					// pInputAttachments
+		1u,							// colorAttachmentCount
+		&colorAttRef,				// pColorAttachments
+		DE_NULL,					// pResolveAttachments
+		DE_NULL,					// depthStencilAttachment
+		0u,							// preserveAttachmentCount
+		DE_NULL,					// pPreserveAttachments
+	};
+	const VkSubpassDependency		dependencies[]		=
+	{
+		{
+			VK_SUBPASS_EXTERNAL,	// srcSubpass
+			0u,						// dstSubpass
+			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+			VK_ACCESS_MEMORY_READ_BIT,
+			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
+			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
+			VK_DEPENDENCY_BY_REGION_BIT
+		},
+		{
+			0u,						// srcSubpass
+			VK_SUBPASS_EXTERNAL,	// dstSubpass
+			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
+			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
+			VK_ACCESS_MEMORY_READ_BIT,
+			VK_DEPENDENCY_BY_REGION_BIT
+		},
+	};
+	const VkRenderPassCreateInfo	renderPassParams	=
+	{
+		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+		DE_NULL,
+		(VkRenderPassCreateFlags)0,
+		1u,
+		&colorAttDesc,
+		1u,
+		&subpassDesc,
+		DE_LENGTH_OF_ARRAY(dependencies),
+		dependencies,
+	};
+
+	return vk::createRenderPass(vkd, device, &renderPassParams);
+}
+
+Move<VkPipelineLayout> WsiTriangleRenderer::createPipelineLayout (const DeviceInterface&	vkd,
+																  const VkDevice			device)
+{
+	const VkPushConstantRange						pushConstantRange		=
+	{
+		VK_SHADER_STAGE_VERTEX_BIT,
+		0u,											// offset
+		(deUint32)sizeof(deUint32),					// size
+	};
+	const VkPipelineLayoutCreateInfo				pipelineLayoutParams	=
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+		DE_NULL,
+		(vk::VkPipelineLayoutCreateFlags)0,
+		0u,											// setLayoutCount
+		DE_NULL,									// pSetLayouts
+		1u,
+		&pushConstantRange,
+	};
+
+	return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
+}
+
+Move<VkPipeline> WsiTriangleRenderer::createPipeline (const DeviceInterface&	vkd,
+													  const VkDevice			device,
+													  const VkRenderPass		renderPass,
+													  const VkPipelineLayout	pipelineLayout,
+													  const BinaryCollection&	binaryCollection,
+													  const tcu::UVec2&			renderSize)
+{
+	// \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
+	//		 and can be deleted immediately following that call.
+	const Unique<VkShaderModule>					vertShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
+	const Unique<VkShaderModule>					fragShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
+	const std::vector<VkViewport>					viewports				(1, makeViewport(renderSize));
+	const std::vector<VkRect2D>						scissors				(1, makeRect2D(renderSize));
+
+	return vk::makeGraphicsPipeline(vkd,				// const DeviceInterface&            vk
+									device,				// const VkDevice                    device
+									pipelineLayout,		// const VkPipelineLayout            pipelineLayout
+									*vertShaderModule,	// const VkShaderModule              vertexShaderModule
+									DE_NULL,			// const VkShaderModule              tessellationControlShaderModule
+									DE_NULL,			// const VkShaderModule              tessellationEvalShaderModule
+									DE_NULL,			// const VkShaderModule              geometryShaderModule
+									*fragShaderModule,	// const VkShaderModule              fragmentShaderModule
+									renderPass,			// const VkRenderPass                renderPass
+									viewports,			// const std::vector<VkViewport>&    viewports
+									scissors);			// const std::vector<VkRect2D>&      scissors
+}
+
+Move<VkImageView> WsiTriangleRenderer::createAttachmentView (const DeviceInterface&	vkd,
+															 const VkDevice			device,
+															 const VkImage			image,
+															 const VkFormat			format)
+{
+	const VkImageViewCreateInfo		viewParams	=
+	{
+		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+		DE_NULL,
+		(VkImageViewCreateFlags)0,
+		image,
+		VK_IMAGE_VIEW_TYPE_2D,
+		format,
+		vk::makeComponentMappingRGBA(),
+		{
+			VK_IMAGE_ASPECT_COLOR_BIT,
+			0u,						// baseMipLevel
+			1u,						// levelCount
+			0u,						// baseArrayLayer
+			1u,						// layerCount
+		},
+	};
+
+	return vk::createImageView(vkd, device, &viewParams);
+}
+
+Move<VkFramebuffer> WsiTriangleRenderer::createFramebuffer	(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 const VkRenderPass			renderPass,
+															 const VkImageView			colorAttachment,
+															 const tcu::UVec2&			renderSize)
+{
+	const VkFramebufferCreateInfo	framebufferParams	=
+	{
+		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+		DE_NULL,
+		(VkFramebufferCreateFlags)0,
+		renderPass,
+		1u,
+		&colorAttachment,
+		renderSize.x(),
+		renderSize.y(),
+		1u,							// layers
+	};
+
+	return vk::createFramebuffer(vkd, device, &framebufferParams);
+}
+
+Move<VkBuffer> WsiTriangleRenderer::createBuffer (const DeviceInterface&	vkd,
+												  VkDevice					device,
+												  VkDeviceSize				size,
+												  VkBufferUsageFlags		usage)
+{
+	const VkBufferCreateInfo	bufferParams	=
+	{
+		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+		DE_NULL,
+		(VkBufferCreateFlags)0,
+		size,
+		usage,
+		VK_SHARING_MODE_EXCLUSIVE,
+		0,
+		DE_NULL
+	};
+
+	return vk::createBuffer(vkd, device, &bufferParams);
+}
+
+WsiTriangleRenderer::WsiTriangleRenderer (const DeviceInterface&	vkd,
+										  const VkDevice			device,
+										  Allocator&				allocator,
+										  const BinaryCollection&	binaryRegistry,
+										  bool						explicitLayoutTransitions,
+										  const vector<VkImage>		swapchainImages,
+										  const vector<VkImage>		aliasImages,
+										  const VkFormat			framebufferFormat,
+										  const tcu::UVec2&			renderSize)
+	: m_vkd							(vkd)
+	, m_explicitLayoutTransitions	(explicitLayoutTransitions)
+	, m_swapchainImages				(swapchainImages)
+	, m_aliasImages					(aliasImages)
+	, m_renderSize					(renderSize)
+	, m_renderPass					(createRenderPass(vkd, device, framebufferFormat, m_explicitLayoutTransitions))
+	, m_pipelineLayout				(createPipelineLayout(vkd, device))
+	, m_pipeline					(createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
+	, m_vertexBuffer				(createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
+	, m_vertexBufferMemory			(allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
+									 MemoryRequirement::HostVisible))
+{
+	m_attachmentViews.resize(swapchainImages.size());
+	m_attachmentLayouts.resize(swapchainImages.size());
+	m_framebuffers.resize(swapchainImages.size());
+
+	for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
+	{
+		m_attachmentViews[imageNdx]		= ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
+		m_attachmentLayouts[imageNdx]	= VK_IMAGE_LAYOUT_UNDEFINED;
+		m_framebuffers[imageNdx]		= FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
+	}
+
+	VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
+
+	{
+		const VkMappedMemoryRange	memRange	=
+		{
+			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
+			DE_NULL,
+			m_vertexBufferMemory->getMemory(),
+			m_vertexBufferMemory->getOffset(),
+			VK_WHOLE_SIZE
+		};
+		const tcu::Vec4				vertices[]	=
+		{
+			tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+			tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+			tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+		};
+		DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
+
+		deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
+		VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
+	}
+}
+
+WsiTriangleRenderer::WsiTriangleRenderer (WsiTriangleRenderer&& other)
+	: m_vkd					(other.m_vkd)
+	, m_explicitLayoutTransitions	(other.m_explicitLayoutTransitions)
+	, m_swapchainImages		(other.m_swapchainImages)
+	, m_aliasImages			(other.m_aliasImages)
+	, m_renderSize			(other.m_renderSize)
+	, m_renderPass			(other.m_renderPass)
+	, m_pipelineLayout		(other.m_pipelineLayout)
+	, m_pipeline			(other.m_pipeline)
+	, m_vertexBuffer		(other.m_vertexBuffer)
+	, m_vertexBufferMemory	(other.m_vertexBufferMemory)
+	, m_attachmentViews		(other.m_attachmentViews)
+	, m_attachmentLayouts	(other.m_attachmentLayouts)
+	, m_framebuffers		(other.m_framebuffers)
+{
+}
+
+WsiTriangleRenderer::~WsiTriangleRenderer (void)
+{
+}
+
+void WsiTriangleRenderer::recordFrame (VkCommandBuffer	cmdBuffer,
+									   deUint32			imageNdx,
+									   deUint32			frameNdx) const
+{
+	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
+
+	beginCommandBuffer(m_vkd, cmdBuffer, 0u);
+
+	if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
+	{
+		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+																		 m_aliasImages[imageNdx], range);
+		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	}
+
+	beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
+
+	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+	{
+		const VkDeviceSize bindingOffset = 0;
+		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
+	}
+
+	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
+	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
+	endRenderPass(m_vkd, cmdBuffer);
+
+	if (m_explicitLayoutTransitions)
+	{
+		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
+																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+																		 m_aliasImages[imageNdx], range);
+		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+	}
+
+	endCommandBuffer(m_vkd, cmdBuffer);
+}
+
+void WsiTriangleRenderer::recordDeviceGroupFrame (VkCommandBuffer	cmdBuffer,
+												  deUint32			firstDeviceID,
+												  deUint32			secondDeviceID,
+												  deUint32			devicesCount,
+												  deUint32			imageNdx,
+												  deUint32			frameNdx) const
+{
+	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
+
+	beginCommandBuffer(m_vkd, cmdBuffer, 0u);
+
+	if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
+	{
+		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+																		 m_aliasImages[imageNdx], range);
+		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	}
+
+	// begin renderpass
+	{
+		const VkClearValue clearValue = makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
+
+		VkRect2D zeroRect = { { 0, 0, },{ 0, 0, } };
+		vector<VkRect2D> renderAreas;
+		for (deUint32 i = 0; i < devicesCount; i++)
+			renderAreas.push_back(zeroRect);
+
+		// Render completely if there is only 1 device
+		if (devicesCount == 1u)
+		{
+			renderAreas[0].extent.width = (deInt32)m_renderSize.x();
+			renderAreas[0].extent.height = (deInt32)m_renderSize.y();
+		}
+		else
+		{
+			// Split into 2 vertical halves
+			renderAreas[firstDeviceID].extent.width		= (deInt32)m_renderSize.x() / 2;
+			renderAreas[firstDeviceID].extent.height	= (deInt32)m_renderSize.y();
+			renderAreas[secondDeviceID]					= renderAreas[firstDeviceID];
+			renderAreas[secondDeviceID].offset.x		= (deInt32)m_renderSize.x() / 2;
+		}
+
+		const VkDeviceGroupRenderPassBeginInfo deviceGroupRPBeginInfo =
+		{
+			VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
+			DE_NULL,
+			(deUint32)((1 << devicesCount) - 1),
+			devicesCount,
+			&renderAreas[0]
+		};
+
+		const VkRenderPassBeginInfo passBeginParams =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,						// sType
+			&deviceGroupRPBeginInfo,										// pNext
+			*m_renderPass,													// renderPass
+			curFramebuffer,													// framebuffer
+			{
+				{ 0, 0 },
+				{ m_renderSize.x(), m_renderSize.y() }
+			},																// renderArea
+			1u,																// clearValueCount
+			&clearValue,													// pClearValues
+		};
+		m_vkd.cmdBeginRenderPass(cmdBuffer, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
+	}
+
+	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+	{
+		const VkDeviceSize bindingOffset = 0;
+		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
+	}
+
+	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
+	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
+	endRenderPass(m_vkd, cmdBuffer);
+
+	if (m_explicitLayoutTransitions)
+	{
+		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
+																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+																		 m_aliasImages[imageNdx], range);
+		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+	}
+
+	endCommandBuffer(m_vkd, cmdBuffer);
+}
+
+void WsiTriangleRenderer::getPrograms (SourceCollections& dst)
+{
+	dst.glslSources.add("tri-vert") << glu::VertexSource(
+		"#version 310 es\n"
+		"layout(location = 0) in highp vec4 a_position;\n"
+		"layout(push_constant) uniform FrameData\n"
+		"{\n"
+		"    highp uint frameNdx;\n"
+		"} frameData;\n"
+		"void main (void)\n"
+		"{\n"
+		"    highp float angle = float(frameData.frameNdx) / 100.0;\n"
+		"    highp float c     = cos(angle);\n"
+		"    highp float s     = sin(angle);\n"
+		"    highp mat4  t     = mat4( c, -s,  0,  0,\n"
+		"                              s,  c,  0,  0,\n"
+		"                              0,  0,  1,  0,\n"
+		"                              0,  0,  0,  1);\n"
+		"    gl_Position = t * a_position;\n"
+		"}\n");
+	dst.glslSources.add("tri-frag") << glu::FragmentSource(
+		"#version 310 es\n"
+		"layout(location = 0) out lowp vec4 o_color;\n"
+		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
+}
+
 } // wsi
 } // vk
diff --git a/external/vulkancts/framework/vulkan/vkWsiUtil.hpp b/external/vulkancts/framework/vulkan/vkWsiUtil.hpp
index bee82de..9cdc08d 100644
--- a/external/vulkancts/framework/vulkan/vkWsiUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkWsiUtil.hpp
@@ -26,6 +26,8 @@
 #include "vkDefs.hpp"
 #include "vkWsiPlatform.hpp"
 #include "vkRef.hpp"
+#include "vkMemUtil.hpp"
+#include "vkPrograms.hpp"
 
 #include <vector>
 
@@ -82,10 +84,23 @@
 																		 deUint32						queueFamilyIndex,
 																		 VkSurfaceKHR					surface);
 
+VkBool32						getPhysicalDevicePresentationSupport	(const InstanceInterface&		vki,
+																		 VkPhysicalDevice				physicalDevice,
+																		 deUint32						queueFamilyIndex,
+																		 Type							wsiType,
+																		 const Display&					nativeDisplay);
+
 VkSurfaceCapabilitiesKHR		getPhysicalDeviceSurfaceCapabilities	(const InstanceInterface&		vki,
 																		 VkPhysicalDevice				physicalDevice,
 																		 VkSurfaceKHR					surface);
 
+VkSurfaceCapabilities2EXT		getPhysicalDeviceSurfaceCapabilities2EXT(const InstanceInterface&		vki,
+																		 VkPhysicalDevice				physicalDevice,
+																		 VkSurfaceKHR					surface);
+
+bool							sameSurfaceCapabilities					(const VkSurfaceCapabilitiesKHR&	khr,
+																		 const VkSurfaceCapabilities2EXT&	ext);
+
 std::vector<VkSurfaceFormatKHR>	getPhysicalDeviceSurfaceFormats			(const InstanceInterface&		vki,
 																		 VkPhysicalDevice				physicalDevice,
 																		 VkSurfaceKHR					surface);
@@ -98,6 +113,102 @@
 																		 VkDevice						device,
 																		 VkSwapchainKHR					swapchain);
 
+deUint32						chooseQueueFamilyIndex					(const InstanceInterface&			vki,
+																		 VkPhysicalDevice					physicalDevice,
+																		 const std::vector<VkSurfaceKHR>&	surfaces);
+
+deUint32						chooseQueueFamilyIndex					(const InstanceInterface&		vki,
+																		 VkPhysicalDevice				physicalDevice,
+																		 VkSurfaceKHR					surface);
+
+std::vector<deUint32>			getCompatibleQueueFamilyIndices			(const InstanceInterface&			vki,
+																		 VkPhysicalDevice					physicalDevice,
+																		 const std::vector<VkSurfaceKHR>&	surface);
+
+class WsiTriangleRenderer
+{
+public:
+										WsiTriangleRenderer	(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 Allocator&					allocator,
+															 const BinaryCollection&	binaryRegistry,
+															 bool						explicitLayoutTransitions,
+															 const std::vector<VkImage>	swapchainImages,
+															 const std::vector<VkImage>	aliasImages,
+															 const VkFormat				framebufferFormat,
+															 const tcu::UVec2&			renderSize);
+
+										WsiTriangleRenderer	(WsiTriangleRenderer&&		other);
+
+										~WsiTriangleRenderer(void);
+
+	void								recordFrame			(VkCommandBuffer			cmdBuffer,
+															 deUint32					imageNdx,
+															 deUint32					frameNdx) const;
+
+	void								recordDeviceGroupFrame (VkCommandBuffer			cmdBuffer,
+																deUint32				imageNdx,
+																deUint32				firstDeviceID,
+																deUint32				secondDeviceID,
+																deUint32				devicesCount,
+																deUint32				frameNdx) const;
+
+	static void							getPrograms			(SourceCollections& dst);
+
+private:
+	static Move<VkRenderPass>			createRenderPass	(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 const VkFormat				colorAttachmentFormat,
+															 const bool					explicitLayoutTransitions);
+
+	static Move<VkPipelineLayout>		createPipelineLayout(const DeviceInterface&		vkd,
+															 VkDevice					device);
+
+	static Move<VkPipeline>				createPipeline		(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 const VkRenderPass			renderPass,
+															 const VkPipelineLayout		pipelineLayout,
+															 const BinaryCollection&	binaryCollection,
+															 const tcu::UVec2&			renderSize);
+
+	static Move<VkImageView>			createAttachmentView(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 const VkImage				image,
+															 const VkFormat				format);
+
+	static Move<VkFramebuffer>			createFramebuffer	(const DeviceInterface&		vkd,
+															 const VkDevice				device,
+															 const VkRenderPass			renderPass,
+															 const VkImageView			colorAttachment,
+															 const tcu::UVec2&			renderSize);
+
+	static Move<VkBuffer>				createBuffer		(const DeviceInterface&		vkd,
+															 VkDevice					device,
+															 VkDeviceSize				size,
+															 VkBufferUsageFlags			usage);
+
+	const DeviceInterface&				m_vkd;
+
+	bool								m_explicitLayoutTransitions;
+	std::vector<VkImage>				m_swapchainImages;
+	std::vector<VkImage>				m_aliasImages;
+	tcu::UVec2							m_renderSize;
+
+	Move<VkRenderPass>					m_renderPass;
+	Move<VkPipelineLayout>				m_pipelineLayout;
+	Move<VkPipeline>					m_pipeline;
+
+	Move<VkBuffer>						m_vertexBuffer;
+	de::MovePtr<Allocation>				m_vertexBufferMemory;
+
+	using ImageViewSp	= de::SharedPtr<Unique<VkImageView>>;
+	using FramebufferSp	= de::SharedPtr<Unique<VkFramebuffer>>;
+
+	std::vector<ImageViewSp>			m_attachmentViews;
+	mutable std::vector<VkImageLayout>	m_attachmentLayouts;
+	std::vector<FramebufferSp>			m_framebuffers;
+};
+
 } // wsi
 } // vk
 
diff --git a/external/vulkancts/modules/vulkan/CMakeLists.txt b/external/vulkancts/modules/vulkan/CMakeLists.txt
index c2234b0..a65120a 100644
--- a/external/vulkancts/modules/vulkan/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/CMakeLists.txt
@@ -35,8 +35,8 @@
 add_subdirectory(transform_feedback)
 add_subdirectory(util)
 add_subdirectory(amber)
-add_subdirectory(descriptor_indexing)
 add_subdirectory(imageless_framebuffer)
+add_subdirectory(descriptor_indexing)
 add_subdirectory(fragment_shader_interlock)
 
 include_directories(
@@ -75,8 +75,8 @@
 	transform_feedback
 	util
 	amber
-	descriptor_indexing
 	imageless_framebuffer
+	descriptor_indexing
 	fragment_shader_interlock
 	)
 
@@ -135,9 +135,9 @@
 	deqp-vk-protected-memory
 	deqp-vk-memory-model
 	deqp-vk-amber
+	deqp-vk-imageless-framebuffer
 	deqp-vk-transform-feedback
 	deqp-vk-descriptor-indexing
-	deqp-vk-imageless-framebuffer
 	deqp-vk-fragment-shader-interlock
 	)
 
diff --git a/external/vulkancts/modules/vulkan/amber/vktAmberGraphicsFuzzTests.cpp b/external/vulkancts/modules/vulkan/amber/vktAmberGraphicsFuzzTests.cpp
index f878701..93b5035 100644
--- a/external/vulkancts/modules/vulkan/amber/vktAmberGraphicsFuzzTests.cpp
+++ b/external/vulkancts/modules/vulkan/amber/vktAmberGraphicsFuzzTests.cpp
@@ -38,59 +38,7 @@
 {
 	tcu::TestContext& testCtx = group->getTestContext();
 
-	static const struct
-	{
-		const std::string	filename;
-		const char*			name;
-		const char*			description;
-	}
-	tests[] =
-	{
-		{	"barrier-in-loop-with-break.amber",				"barrier-in-loop-with-break",			"A compute shader with a barrier in a loop with a break"								},
-		{	"color-write-in-loop.amber",					"color-write-in-loop",					"A fragment shader that writes to color in a loop"										},
-		{	"continue-and-merge.amber",						"continue-and-merge",					"A fragment shader with two nested loops"												},
-		{	"control-flow-in-function.amber",				"control-flow-in-function",				"A fragment shader with a lot of control flow"											},
-		{	"control-flow-switch.amber",					"control-flow-switch",					"A fragment shader with somewhat complex control flow and a switch"						},
-		{	"dead-barriers-in-loops.amber",					"dead-barriers-in-loops",				"A compute shader with dead barriers"													},
-		{	"dead-struct-init.amber",						"dead-struct-init",						"A fragment shader that uses struct initializers"										},
-		{	"discard-continue-return.amber",				"discard-continue-return",				"A fragment shader with a discard, continue, and return"								},
-		{	"do-while-loop-in-conditionals.amber",			"do-while-loop-in-conditionals",		"A fragment shader with do-while loop in conditional nest"								},
-		{	"early-return-and-barrier.amber",				"early-return-and-barrier",				"A compute shader with an early return and a barrier"									},
-		{	"for-condition-always-false.amber",				"for-condition-always-false",			"A fragment shader that uses a for loop with condition always false"					},
-		{	"for-with-ifs-and-return.amber",				"for-with-ifs-and-return",				"A fragment shader with two ifs and return/continue inside a for loop"					},
-		{	"fragcoord-control-flow.amber",					"fragcoord-control-flow",				"A fragment shader that uses FragCoord and somewhat complex control flow"				},
-		{	"fragcoord-control-flow-2.amber",				"fragcoord-control-flow-2",				"A fragment shader that uses FragCoord and somewhat complex control flow"				},
-		{	"if-and-switch.amber",							"if-and-switch",						"A fragment shader with a switch and some data flow"									},
-		{	"loop-call-discard.amber",						"loop-call-discard",					"A fragment shader with nested loops and a function call"								},
-		{	"loop-nested-ifs.amber",						"loop-nested-ifs",						"A fragment shader with a for loop containing nested ifs"								},
-		{	"mat-array-deep-control-flow.amber",			"mat-array-deep-control-flow",			"A fragment shader that uses an array of matrices and has deep control flow"			},
-		{	"mat-array-distance.amber",						"mat-array-distance",					"A fragment shader that uses an array of matrices and distance"							},
-		{	"matrices-and-return-in-loop.amber",			"matrices-and-return-in-loop",			"A fragment shader with matrices and a return in a loop"								},
-		{	"max-mix-conditional-discard.amber",			"max-mix-conditional-discard",			"A fragment shader with an expression used in two discard guards"						},
-		{	"mix-floor-add.amber",							"mix-floor-add",						"A fragment shader with mix, uintBitsToFloat, and floor"								},
-		{	"nested-for-loops-with-return.amber",			"nested-for-loops-with-return",			"A fragment shader with two nested for loops with return"								},
-		{	"nested-ifs-and-return-in-for-loop.amber",		"nested-ifs-and-return-in-for-loop",	"A fragment shader with return in nest of ifs, inside loop"								},
-		{	"nested-loops-switch.amber",					"nested-loops-switch",					"A fragment shader with nested loops and a switch"										},
-		{	"pow-vec4.amber",								"pow-vec4",								"A fragment shader that uses pow"														},
-		{	"return-in-loop-in-function.amber",				"return-in-loop-in-function",			"A fragment shader with early return from loop in function"								},
-		{	"similar-nested-ifs.amber",						"similar-nested-ifs",					"A fragment shader with similar nested ifs and loops"									},
-		{	"struct-used-as-temporary.amber",				"struct-used-as-temporary",				"A fragment shader that uses a temporary struct variable"								},
-		{	"swizzle-struct-init-min.amber",				"swizzle-struct-init-min",				"A fragment shader that uses vector swizzles, struct initializers, and min"				},
-		{	"two-loops-matrix.amber",						"two-loops-matrix",						"A fragment shader with two loops and some matrices"									},
-		{	"two-loops-set-struct.amber",					"two-loops-set-struct",					"A fragment shader with two loops that write to a struct"								},
-		{	"two-loops-with-break.amber",					"two-loops-with-break",					"A fragment shader with two loops with breaks"											},
-		{	"unreachable-barrier-in-loops.amber",			"unreachable-barrier-in-loops",			"A compute shader with an unreachable barrier in a loop nest"							},
-		{	"unreachable-continue-statement.amber",			"unreachable-continue-statement",		"A fragment shader with unreachable continue statement"									},
-		{	"unreachable-loops.amber",						"unreachable-loops",					"Fragment shader that writes red despite unreachable loops"								},
-		{	"unreachable-loops-in-switch.amber",			"unreachable-loops-in-switch",			"A fragment shader with unreachable loops in a switch"									},
-		{	"while-inside-switch.amber",					"while-inside-switch",					"A fragment shader that uses a while loop inside a switch"								},
-		{	"write-before-break.amber",						"write-before-break",					"Fragment shader that writes red before loop break"										},
-		{	"write-red-after-search.amber",					"write-red-after-search",				"A fragment shader performing a search computation, then writing red regardless"		},
-		{	"write-red-in-loop-nest.amber",					"write-red-in-loop-nest",				"A fragment shader that writes red in a nest of loops"									},
-	};
-
-	for (size_t i = 0; i < sizeof tests / sizeof tests[0]; i++)
-		group->addChild(createAmberTestCase(testCtx, tests[i].name, tests[i].description, "graphicsfuzz", tests[i].filename));
+	createAmberTestsFromIndexFile(testCtx, group, "index.txt", "graphicsfuzz");
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp
index 5586bb7..12793b2 100644
--- a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp
+++ b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp
@@ -43,11 +43,13 @@
 namespace cts_amber
 {
 
-AmberTestCase::AmberTestCase (tcu::TestContext& testCtx,
-							  const char*		name,
-							  const char*		description)
+AmberTestCase::AmberTestCase (tcu::TestContext&		testCtx,
+							  const char*			name,
+							  const char*			description,
+							  const std::string&	readFilename)
 	: TestCase(testCtx, name, description),
-	  m_recipe(DE_NULL)
+	  m_recipe(DE_NULL),
+	  m_readFilename(readFilename)
 {
 }
 
@@ -95,6 +97,16 @@
 	TCU_THROW(InternalError, message.c_str());
 }
 
+void AmberTestCase::delayedInit(void)
+{
+	// Make sure the input can be parsed before we use it.
+	if (!parse(m_readFilename))
+	{
+		std::string message = "Failed to parse Amber file: " + m_readFilename;
+		TCU_THROW(InternalError, message.c_str());
+	}
+}
+
 void AmberTestCase::checkSupport(Context& ctx) const
 {
 	// Check for instance and device extensions as declared by the test code.
@@ -146,45 +158,21 @@
 			TCU_THROW(NotSupportedError, message.c_str());
 		}
 	}
-
-	// Check for extensions as declared by the Amber script itself.  Throw an internal
-	// error if that's more demanding.
-	amber::Amber			am;
-	amber::Options			amber_options;
-	amber_options.engine	= amber::kEngineTypeVulkan;
-	amber_options.config	= createEngineConfig(ctx);
-	amber_options.delegate	= DE_NULL;
-
-	amber::Result r = am.AreAllRequirementsSupported(m_recipe, &amber_options);
-	if (!r.IsSuccess())
-	{
-		// dEQP does not to rely on external code to determine whether
-		// a test is supported.  So throw an internal error here instead
-		// of a NotSupportedError.  If an Amber test is not supported, then
-		// you must override this method and throw a NotSupported exception
-		// before reach here.
-		TCU_THROW(InternalError, r.Error().c_str());
-	}
-
-	delete amber_options.config;
 }
 
-bool AmberTestCase::parse(const char* category, const std::string& filename)
+bool AmberTestCase::parse(const std::string& readFilename)
 {
-	std::string readFilename("vulkan/amber/");
-	readFilename.append(category);
-	readFilename.append("/");
-	readFilename.append(filename);
-
 	std::string script = ShaderSourceProvider::getSource(m_testCtx.getArchive(), readFilename.c_str());
 	if (script.empty())
 		return false;
 
 	m_recipe = new amber::Recipe();
-	m_recipe->SetFenceTimeout(1000 * 60 * 10); // 10 minutes
 
 	amber::Amber am;
 	amber::Result r = am.Parse(script, m_recipe);
+
+	m_recipe->SetFenceTimeout(1000 * 60 * 10); // 10 minutes
+
 	if (!r.IsSuccess())
 	{
 		getTestContext().getLog()
@@ -265,7 +253,28 @@
 
 tcu::TestStatus AmberTestInstance::iterate (void)
 {
-	amber::ShaderMap shaderMap;
+	amber::Amber		am;
+	amber::Options		amber_options;
+	amber::ShaderMap	shaderMap;
+	amber::Result		r;
+
+	amber_options.engine			= amber::kEngineTypeVulkan;
+	amber_options.config			= createEngineConfig(m_context);
+	amber_options.delegate			= DE_NULL;
+	amber_options.execution_type	= amber::ExecutionType::kExecute;
+
+	// Check for extensions as declared by the Amber script itself.  Throw an internal
+	// error if that's more demanding.
+	r = am.AreAllRequirementsSupported(m_recipe, &amber_options);
+	if (!r.IsSuccess())
+	{
+		// dEQP does not to rely on external code to determine whether
+		// a test is supported.  So throw an internal error here instead
+		// of a NotSupportedError.  If an Amber test is not supported, then
+		// you must override this method and throw a NotSupported exception
+		// before reach here.
+		TCU_THROW(InternalError, r.Error().c_str());
+	}
 
 	std::vector<amber::ShaderInfo> shaders = m_recipe->GetShaderInfo();
 	for (size_t i = 0; i < shaders.size(); ++i)
@@ -286,14 +295,7 @@
 		shaderMap[shader.shader_name] = data;
 	}
 
-	amber::Amber						am;
-	amber::Options						amber_options;
-	amber_options.engine				= amber::kEngineTypeVulkan;
-	amber_options.config				= createEngineConfig(m_context);
-	amber_options.delegate				= DE_NULL;
-	amber_options.execution_type		= amber::ExecutionType::kExecute;
-
-	amber::Result r = am.ExecuteWithShaderData(m_recipe, &amber_options, shaderMap);
+	r = am.ExecuteWithShaderData(m_recipe, &amber_options, shaderMap);
 	if (!r.IsSuccess()) {
 		m_context.getTestContext().getLog()
 			<< tcu::TestLog::Message
diff --git a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.hpp b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.hpp
index 24111a4..f0c61c1 100644
--- a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.hpp
+++ b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.hpp
@@ -58,7 +58,8 @@
 public:
 	AmberTestCase	(tcu::TestContext&	testCtx,
 					 const char*		name,
-					 const char*		description);
+					 const char*		description,
+					 const std::string&	readFilename);
 
 	virtual ~AmberTestCase (void);
 
@@ -67,19 +68,18 @@
 	// Check that the Vulkan implementation supports this test.
 	// We have the principle that client code in dEQP should independently
 	// determine if the test should be supported:
-	//  - If any of the extensions registered via
-	//    |addRequiredDeviceExtension| is not supported then throw a
-	//    NotSupported exception.
+	//  - If any of the extensions registered via |addRequirement| is not
+	//    supported then throw a NotSupported exception.
 	//  - Otherwise, we do a secondary sanity check depending on code inside
 	//    Amber itself: if the Amber test says it is not supported, then
 	//    throw an internal error exception.
-	virtual void checkSupport(Context& ctx) const; // override
+	virtual void checkSupport (Context& ctx) const; // override
 
-	bool parse(const char* category, const std::string& filename);
-	void initPrograms(vk::SourceCollections& programCollection) const;
 	// If the test case uses SPIR-V Assembly, use these build options.
 	// Otherwise, defaults to target Vulkan 1.0, SPIR-V 1.0.
 	void setSpirVAsmBuildOptions(const vk::SpirVAsmBuildOptions& asm_options);
+	virtual void delayedInit (void);
+	virtual void initPrograms (vk::SourceCollections& programCollection) const;
 
 	// Add a required instance extension, device extension, or feature bit.
 	// A feature bit is represented by a string of form "<structure>.<feature>", where
@@ -89,9 +89,13 @@
 	void addRequirement(const std::string& requirement);
 
 private:
+	bool parse (const std::string& readFilename);
+
 	amber::Recipe* m_recipe;
 	vk::SpirVAsmBuildOptions m_asm_options;
 
+	std::string m_readFilename;
+
 	// Instance and device extensions required by the test.
 	// We don't differentiate between the two:  We consider the requirement
 	// satisfied if the string is registered as either an instance or device
@@ -113,6 +117,11 @@
 									const std::string&				filename,
 									const std::vector<std::string>	requirements = std::vector<std::string>());
 
+void createAmberTestsFromIndexFile (tcu::TestContext&	testCtx,
+									tcu::TestCaseGroup*	group,
+									const std::string	filename,
+									const char*			category);
+
 } // cts_amber
 } // vkt
 
diff --git a/external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp b/external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp
index 3b20b30..c68e9d2 100644
--- a/external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp
+++ b/external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp
@@ -21,12 +21,158 @@
 
 #include "vktAmberTestCase.hpp"
 #include "vktTestGroupUtil.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "tcuResource.hpp"
+
 
 namespace vkt
 {
 namespace cts_amber
 {
 
+class AmberIndexFileParser
+{
+	std::string			m_str;
+	size_t				m_idx;
+	size_t				m_len;
+	static const int	m_fieldLen = 256;
+	char				m_scratch[m_fieldLen];
+	char				m_filenameField[m_fieldLen];
+	char				m_testnameField[m_fieldLen];
+	char				m_descField[m_fieldLen];
+
+	bool isWhitespace (char c)
+	{
+		if (c == ' '  ||
+			c == '\t' ||
+			c == '\r' ||
+			c == '\n')
+		{
+			return true;
+		}
+		return false;
+	}
+
+	void skipWhitespace (void)
+	{
+		while (m_idx < m_len && isWhitespace(m_str[m_idx]))
+			m_idx++;
+	}
+
+	void accept (char c)
+	{
+		if (m_str[m_idx] == c)
+			m_idx++;
+	}
+
+	void expect (char c)
+	{
+		if (m_str[m_idx] != c || m_idx >= m_len)
+			TCU_THROW(ResourceError, "Error parsing amber index file");
+
+		m_idx++;
+	}
+
+	void captureString (char* field)
+	{
+		int i = 0;
+
+		while (m_idx < m_len && i < m_fieldLen && m_str[m_idx] != '"')
+		{
+			field[i] = m_str[m_idx];
+			i++;
+			m_idx++;
+		}
+
+		field[i] = 0;
+		m_idx++;
+	}
+
+
+public:
+	AmberIndexFileParser (tcu::TestContext& testCtx, const char* filename, const char* category)
+	{
+		std::string	indexFilename("vulkan/amber/");
+		indexFilename.append(category);
+		indexFilename.append("/");
+		indexFilename.append(filename);
+
+		m_str = ShaderSourceProvider::getSource(testCtx.getArchive(), indexFilename.c_str());
+		m_len = m_str.length();
+		m_idx = 0;
+	}
+
+	~AmberIndexFileParser (void) { }
+
+	AmberTestCase* parse (const char* category, tcu::TestContext& testCtx)
+	{
+		// Format:
+		// {"filename","test name","description"[,requirement[,requirement[,requirement..]]]}[,]
+		// Things inside [] are optional. Whitespace is allowed everywhere.
+		//
+		// For example, test without requirements might be:
+		// {"testname.amber","test name","test description"},
+
+		if (m_idx < m_len)
+		{
+			skipWhitespace();
+			expect('{');
+			skipWhitespace();
+			expect('"');
+			captureString(m_filenameField);
+			skipWhitespace();
+			expect(',');
+			skipWhitespace();
+			expect('"');
+			captureString(m_testnameField);
+			skipWhitespace();
+			expect(',');
+			skipWhitespace();
+			expect('"');
+			captureString(m_descField);
+			skipWhitespace();
+
+			std::string testFilename("vulkan/amber/");
+			testFilename.append(category);
+			testFilename.append("/");
+			testFilename.append(m_filenameField);
+			AmberTestCase *testCase = new AmberTestCase(testCtx, m_testnameField, m_descField, testFilename);
+
+			while (m_idx < m_len && m_str[m_idx] == ',')
+			{
+				accept(',');
+				skipWhitespace();
+				expect('"');
+				captureString(m_scratch);
+				skipWhitespace();
+				testCase->addRequirement(m_scratch);
+			}
+
+			expect('}');
+			skipWhitespace();
+			accept(',');
+			skipWhitespace();
+			return testCase;
+		}
+		return 0;
+	}
+};
+
+void createAmberTestsFromIndexFile (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string filename, const char* category)
+{
+	AmberTestCase*			testCase = 0;
+	AmberIndexFileParser	parser(testCtx, filename.c_str(), category);
+
+	do
+	{
+		testCase = parser.parse(category, testCtx);
+		if (testCase)
+		{
+			group->addChild(testCase);
+		}
+	} while (testCase);
+}
+
 AmberTestCase* createAmberTestCase (tcu::TestContext&				testCtx,
 									const char*						name,
 									const char*						description,
@@ -34,24 +180,18 @@
 									const std::string&				filename,
 									const std::vector<std::string>	requirements)
 {
-	AmberTestCase *testCase = new AmberTestCase(testCtx, name, description);
+	// shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
+	std::string readFilename("vulkan/amber/");
+	readFilename.append(category);
+	readFilename.append("/");
+	readFilename.append(filename);
+
+	AmberTestCase *testCase = new AmberTestCase(testCtx, name, description, readFilename);
 
 	for (auto req : requirements)
 		testCase->addRequirement(req);
 
-	// shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
-	// Make sure the input can be parsed before we use it.
-	if (testCase->parse(category, filename))
-		return testCase;
-	else
-	{
-		const std::string msg = "Failed to parse Amber file: " + filename;
-
-		delete testCase;
-		TCU_THROW(InternalError, msg.c_str());
-	}
-
-	return DE_NULL;
+	return testCase;
 }
 
 } // cts_amber
diff --git a/external/vulkancts/modules/vulkan/api/CMakeLists.txt b/external/vulkancts/modules/vulkan/api/CMakeLists.txt
index 0db5ff9..0fd6c24 100644
--- a/external/vulkancts/modules/vulkan/api/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/api/CMakeLists.txt
@@ -20,6 +20,8 @@
 	vktApiObjectManagementTests.hpp
 	vktApiBufferTests.cpp
 	vktApiBufferTests.hpp
+	vktApiBufferMarkerTests.cpp
+	vktApiBufferMarkerTests.hpp
 	vktApiBufferViewCreateTests.cpp
 	vktApiBufferViewCreateTests.hpp
 	vktApiBufferViewAccessTests.cpp
diff --git a/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.cpp
new file mode 100644
index 0000000..be54a88
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.cpp
@@ -0,0 +1,1131 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_buffer_marker
+ *//*--------------------------------------------------------------------*/
+
+#include "vktApiBufferMarkerTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktExternalMemoryUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
+#include "deRandom.hpp"
+
+#include <vector>
+
+namespace vkt
+{
+namespace api
+{
+namespace
+{
+using namespace vk;
+using de::UniquePtr;
+using de::MovePtr;
+using de::SharedPtr;
+using namespace vkt::ExternalMemoryUtil;
+
+template<typename T>
+inline const T* dataOrNullPtr(const std::vector<T>& v)
+{
+	return (v.empty() ? DE_NULL : &v[0]);
+}
+
+template<typename T>
+inline T* dataOrNullPtr(std::vector<T>& v)
+{
+	return (v.empty() ? DE_NULL : &v[0]);
+}
+
+//! Common test data related to the device
+struct WorkingDevice
+{
+	Move<VkDevice>          logicalDevice;
+	MovePtr<DeviceDriver>   deviceDriver;
+	MovePtr<Allocator>      allocator;
+	VkQueue                 queue;
+	deUint32                queueFamilyIdx;
+	VkQueueFamilyProperties queueProps;
+};
+
+bool queueFamilyMatchesTestCase(const VkQueueFamilyProperties& props, VkQueueFlagBits testQueue)
+{
+	// The goal is to find a queue family that most accurately represents the required queue flag.  For example, if flag is
+	// VK_QUEUE_TRANSFER_BIT, we want to target transfer-only queues for such a test case rather than universal queues which
+	// may include VK_QUEUE_TRANSFER_BIT along with other queue flags.
+	const VkQueueFlags flags = props.queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT);
+
+	// for VK_QUEUE_TRANSFER_BIT, target transfer-only queues:
+	if (testQueue == VK_QUEUE_TRANSFER_BIT)
+		return (flags == VK_QUEUE_TRANSFER_BIT);
+
+	// for VK_QUEUE_COMPUTE_BIT, target compute only queues
+	if (testQueue == VK_QUEUE_COMPUTE_BIT)
+		return ((flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)) == VK_QUEUE_COMPUTE_BIT);
+
+	// for VK_QUEUE_GRAPHICS_BIT, target universal queues (queues which support graphics)
+	if (testQueue == VK_QUEUE_GRAPHICS_BIT)
+		return ((flags & VK_QUEUE_GRAPHICS_BIT) != 0);
+
+	DE_FATAL("Unexpected test queue flag");
+
+	return false;
+}
+
+// We create a custom device because we don't want to always use the universal queue.
+void createDeviceWithExtension (Context& context, WorkingDevice& wd, VkQueueFlagBits testQueue, bool hostPtr)
+{
+	const PlatformInterface&	vkp				= context.getPlatformInterface();
+	const VkInstance			instance		= context.getInstance();
+	const InstanceInterface&	instanceDriver	= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
+
+	// Create a device with extension enabled and a queue with a family which supports the buffer marker extension
+	const std::vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
+	const float									queuePriority			= 1.0f;
+	VkDeviceQueueCreateInfo						queueCreateInfo			= {};
+
+	for (deUint32 familyIdx = 0; familyIdx < queueFamilyProperties.size(); ++familyIdx)
+	{
+		if (queueFamilyMatchesTestCase(queueFamilyProperties[familyIdx], testQueue) &&
+			queueFamilyProperties[familyIdx].queueCount > 0)
+		{
+			queueCreateInfo.sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+			queueCreateInfo.pNext				= DE_NULL;
+			queueCreateInfo.pQueuePriorities	= &queuePriority;
+			queueCreateInfo.queueCount			= 1;
+			queueCreateInfo.queueFamilyIndex	= familyIdx;
+
+			break;
+		}
+	}
+
+	if (queueCreateInfo.queueCount == 0)
+	{
+		TCU_THROW(NotSupportedError, "No compatible queue family for this test case");
+	}
+
+	std::vector<const char*> cstrDeviceExtensions;
+
+	cstrDeviceExtensions.push_back("VK_AMD_buffer_marker");
+
+	if (hostPtr)
+		cstrDeviceExtensions.push_back("VK_EXT_external_memory_host");
+
+	const VkDeviceCreateInfo deviceInfo =
+	{
+		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,				// VkStructureType					sType;
+		DE_NULL,											// const void*						pNext;
+		0u,													// VkDeviceCreateFlags				flags;
+		1,													// deUint32							queueCreateInfoCount;
+		&queueCreateInfo,									// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
+		0u,													// deUint32							enabledLayerCount;
+		DE_NULL,											// const char* const*				ppEnabledLayerNames;
+		static_cast<deUint32>(cstrDeviceExtensions.size()),	// deUint32							enabledExtensionCount;
+		dataOrNullPtr(cstrDeviceExtensions),				// const char* const*				ppEnabledExtensionNames;
+		&context.getDeviceFeatures(),						// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
+	};
+
+	wd.logicalDevice	= createDevice(vkp, instance, instanceDriver, physicalDevice, &deviceInfo);
+	wd.deviceDriver		= MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, *wd.logicalDevice));
+	wd.allocator		= MovePtr<Allocator>(new SimpleAllocator(*wd.deviceDriver, *wd.logicalDevice, getPhysicalDeviceMemoryProperties(instanceDriver, physicalDevice)));
+	wd.queueFamilyIdx	= queueCreateInfo.queueFamilyIndex;
+	wd.queue			= getDeviceQueue(*wd.deviceDriver, *wd.logicalDevice, wd.queueFamilyIdx, 0u);
+	wd.queueProps		= queueFamilyProperties[queueCreateInfo.queueFamilyIndex];
+}
+
+bool checkMarkerBuffer	(const DeviceInterface& vk, VkDevice device, const MovePtr<vk::Allocation>& memory, size_t offset,
+						 const std::vector<deUint32>& expected)
+{
+	invalidateMappedMemoryRange(vk, device, memory->getMemory(), memory->getOffset(), VK_WHOLE_SIZE);
+
+	const deUint32* data = reinterpret_cast<const deUint32*>(static_cast<const char*>(memory->getHostPtr()) + offset);
+
+	for (size_t i = 0; i < expected.size(); ++i)
+	{
+		if (data[i] != expected[i])
+			return false;
+	}
+
+	return true;
+}
+
+struct BaseTestParams
+{
+	VkQueueFlagBits			testQueue;	// Queue type that this test case targets
+	VkPipelineStageFlagBits stage;		// Pipeline stage where any marker writes for this test case occur in
+	deUint32				size;		// Number of buffer markers
+	bool					useHostPtr;	// Whether to use host pointer as backing buffer memory
+};
+
+deUint32 chooseExternalMarkerMemoryType(const DeviceInterface&				vkd,
+										VkDevice							device,
+										VkExternalMemoryHandleTypeFlagBits	externalType,
+										deUint32							allowedBits,
+										MovePtr<ExternalHostMemory>&		hostMemory)
+{
+	VkMemoryHostPointerPropertiesEXT props =
+	{
+		vk::VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
+		DE_NULL,
+		0u,
+	};
+
+	if (vkd.getMemoryHostPointerPropertiesEXT(device, externalType, hostMemory->data, &props) == VK_SUCCESS)
+	{
+		allowedBits &= props.memoryTypeBits;
+	}
+
+	deUint32 index = 0;
+
+	while ((index < VK_MAX_MEMORY_TYPES) && ((allowedBits & 0x1) == 0))
+	{
+		index++;
+		allowedBits >>= 1;
+	}
+
+	return index;
+}
+
+class ExternalHostAllocation : public Allocation
+{
+public:
+	ExternalHostAllocation(Move<VkDeviceMemory> mem, void* hostPtr) : Allocation(*mem, (VkDeviceSize)0, hostPtr), m_memHolder(mem) { }
+
+private:
+	const Unique<VkDeviceMemory>	m_memHolder;
+};
+
+void createMarkerBufferMemory(const InstanceInterface&		vki,
+							 const DeviceInterface&			vkd,
+							 VkPhysicalDevice				physicalDevice,
+							 VkDevice						device,
+							 VkBuffer						buffer,
+							 MovePtr<Allocator>&			allocator,
+							 const MemoryRequirement		allocRequirement,
+							 bool							externalHostPtr,
+							 MovePtr<ExternalHostMemory>&	hostMemory,
+							 MovePtr<Allocation>&			deviceMemory)
+{
+	VkMemoryRequirements memReqs = getBufferMemoryRequirements(vkd, device, buffer);
+
+	if (externalHostPtr == false)
+	{
+		deviceMemory = allocator->allocate(memReqs, allocRequirement);
+	}
+	else
+	{
+		const VkExternalMemoryHandleTypeFlagBits externalType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
+
+		const VkPhysicalDeviceExternalMemoryHostPropertiesEXT hostProps = getPhysicalDeviceExternalMemoryHostProperties(vki, physicalDevice);
+
+		hostMemory = MovePtr<ExternalHostMemory>(new ExternalHostMemory(memReqs.size, hostProps.minImportedHostPointerAlignment));
+
+		const deUint32 externalMemType = chooseExternalMarkerMemoryType(vkd, device, externalType, memReqs.memoryTypeBits, hostMemory);
+
+		if (externalMemType == VK_MAX_MEMORY_TYPES)
+		{
+			TCU_FAIL("Failed to find compatible external host memory type for marker buffer");
+		}
+
+		const VkImportMemoryHostPointerInfoEXT	importInfo =
+		{
+			VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
+			DE_NULL,
+			externalType,
+			hostMemory->data
+		};
+
+		const VkMemoryAllocateInfo				info =
+		{
+			VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+			(const void*)&importInfo,
+			hostMemory->size,
+			externalMemType
+		};
+
+		deviceMemory = MovePtr<Allocation>(new ExternalHostAllocation(allocateMemory(vkd, device, &info), hostMemory->data));
+	}
+
+	VK_CHECK(vkd.bindBufferMemory(device, buffer, deviceMemory->getMemory(), deviceMemory->getOffset()));
+}
+
+tcu::TestStatus bufferMarkerSequential(Context& context, BaseTestParams params)
+{
+	WorkingDevice wd;
+
+	createDeviceWithExtension(context, wd, params.testQueue, params.useHostPtr);
+
+	const DeviceInterface&			vk(*wd.deviceDriver);
+	const VkDevice					device(*wd.logicalDevice);
+	const VkDeviceSize				markerBufferSize(params.size * sizeof(deUint32));
+	Move<VkBuffer>					markerBuffer(makeBuffer(vk, device, markerBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
+	MovePtr<ExternalHostMemory>		hostMemory;
+	MovePtr<Allocation>				markerMemory;
+
+	createMarkerBufferMemory(context.getInstanceInterface(), vk, context.getPhysicalDevice(), device,
+							 *markerBuffer, wd.allocator, MemoryRequirement::HostVisible, params.useHostPtr, hostMemory, markerMemory);
+
+	de::Random						rng(12345 ^ params.size);
+	std::vector<deUint32>			expected(params.size);
+
+	for (size_t i = 0; i < params.size; ++i)
+		expected[i] = rng.getUint32();
+
+	deMemcpy(markerMemory->getHostPtr(), &expected[0], static_cast<size_t>(markerBufferSize));
+	flushMappedMemoryRange(vk, device, markerMemory->getMemory(), markerMemory->getOffset(), VK_WHOLE_SIZE);
+
+	const Unique<VkCommandPool>		cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, wd.queueFamilyIdx));
+	const Unique<VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	for (size_t i = 0; i < params.size; ++i)
+	{
+		vk.cmdWriteBufferMarkerAMD(*cmdBuffer, params.stage, *markerBuffer, static_cast<VkDeviceSize>(sizeof(deUint32) * i), expected[i]);
+	}
+
+	const VkMemoryBarrier memoryDep =
+	{
+		VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+		DE_NULL,
+		VK_ACCESS_TRANSFER_WRITE_BIT,
+		VK_ACCESS_HOST_READ_BIT,
+	};
+
+	vk.cmdPipelineBarrier(*cmdBuffer, params.stage, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memoryDep, 0, DE_NULL, 0, DE_NULL);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+
+	submitCommandsAndWait(vk, device, wd.queue, *cmdBuffer);
+
+	if (!checkMarkerBuffer(vk, device, markerMemory, 0, expected))
+		return tcu::TestStatus::fail("Some marker values were incorrect");
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+tcu::TestStatus bufferMarkerOverwrite(Context& context, BaseTestParams params)
+{
+	WorkingDevice wd;
+
+	createDeviceWithExtension(context, wd, params.testQueue, params.useHostPtr);
+
+	const DeviceInterface&			vk(*wd.deviceDriver);
+	const VkDevice					device(*wd.logicalDevice);
+	const VkDeviceSize				markerBufferSize(params.size * sizeof(deUint32));
+	Move<VkBuffer>					markerBuffer(makeBuffer(vk, device, markerBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
+	MovePtr<ExternalHostMemory>		hostMemory;
+	MovePtr<Allocation>				markerMemory;
+
+	createMarkerBufferMemory(context.getInstanceInterface(), vk, context.getPhysicalDevice(), device,
+							 *markerBuffer, wd.allocator, MemoryRequirement::HostVisible, params.useHostPtr, hostMemory, markerMemory);
+
+	de::Random						rng(12345 ^ params.size);
+	std::vector<deUint32>			expected(params.size);
+
+	for (size_t i = 0; i < params.size; ++i)
+		expected[i] = 0;
+
+	deMemcpy(markerMemory->getHostPtr(), &expected[0], static_cast<size_t>(markerBufferSize));
+	flushMappedMemoryRange(vk, device, markerMemory->getMemory(), markerMemory->getOffset(), VK_WHOLE_SIZE);
+
+	const Unique<VkCommandPool>		cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, wd.queueFamilyIdx));
+	const Unique<VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	for (deUint32 i = 0; i < params.size * 10; ++i)
+	{
+		const deUint32 slot  = rng.getUint32() % static_cast<deUint32>(params.size);
+		const deUint32 value = i;
+
+		expected[slot] = value;
+
+		vk.cmdWriteBufferMarkerAMD(*cmdBuffer, params.stage, *markerBuffer, static_cast<VkDeviceSize>(sizeof(deUint32) * slot), expected[slot]);
+	}
+
+	const VkMemoryBarrier memoryDep = {
+		VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+		DE_NULL,
+		VK_ACCESS_TRANSFER_WRITE_BIT,
+		VK_ACCESS_HOST_READ_BIT,
+	};
+
+	vk.cmdPipelineBarrier(*cmdBuffer, params.stage, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memoryDep, 0, DE_NULL, 0, DE_NULL);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+
+	submitCommandsAndWait(vk, device, wd.queue, *cmdBuffer);
+
+	if (!checkMarkerBuffer(vk, device, markerMemory, 0, expected))
+		return tcu::TestStatus::fail("Some marker values were incorrect");
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+enum MemoryDepMethod
+{
+	MEMORY_DEP_DRAW,
+	MEMORY_DEP_DISPATCH,
+	MEMORY_DEP_COPY
+};
+
+struct MemoryDepParams
+{
+	BaseTestParams			base;
+	MemoryDepMethod			method;
+};
+
+enum MemoryDepOwner
+{
+	MEMORY_DEP_OWNER_NOBODY = 0,
+	MEMORY_DEP_OWNER_MARKER = 1,
+	MEMORY_DEP_OWNER_NON_MARKER = 2
+};
+
+void computeMemoryDepBarrier(MemoryDepMethod			method,
+							 MemoryDepOwner				owner,
+							 VkPipelineStageFlagBits	markerStage,
+							 VkAccessFlags*				memoryDepAccess,
+							 VkPipelineStageFlags*		executionScope)
+{
+	DE_ASSERT(owner != MEMORY_DEP_OWNER_NOBODY);
+
+	if (owner == MEMORY_DEP_OWNER_MARKER)
+	{
+		*memoryDepAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
+		*executionScope  = markerStage;
+	}
+	else
+	{
+		if (method == MEMORY_DEP_COPY)
+		{
+			*memoryDepAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
+			*executionScope  = VK_PIPELINE_STAGE_TRANSFER_BIT;
+		}
+		else if (method == MEMORY_DEP_DISPATCH)
+		{
+			*memoryDepAccess = VK_ACCESS_SHADER_WRITE_BIT;
+			*executionScope  = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+		}
+		else
+		{
+			*memoryDepAccess = VK_ACCESS_SHADER_WRITE_BIT;
+			*executionScope  = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+		}
+	}
+}
+
+// Randomly do buffer marker writes and other operations (draws, dispatches) that shader-write to a shared buffer.  Insert pipeline barriers
+// when necessary and make sure that the synchronization between marker writes and non-marker writes are correctly handled by the barriers.
+tcu::TestStatus bufferMarkerMemoryDep(Context& context, MemoryDepParams params)
+{
+	WorkingDevice wd;
+
+	createDeviceWithExtension(context, wd, params.base.testQueue, params.base.useHostPtr);
+
+	VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+
+	if ((params.method == MEMORY_DEP_DRAW) || (params.method == MEMORY_DEP_DISPATCH))
+		usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+	else
+		usageFlags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+
+	const deUint32					numIters(1000);
+	const DeviceInterface&			vk(*wd.deviceDriver);
+	const VkDevice					device(*wd.logicalDevice);
+	const deUint32					size(params.base.size);
+	const VkDeviceSize				markerBufferSize(params.base.size * sizeof(deUint32));
+	Move<VkBuffer>					markerBuffer(makeBuffer(vk, device, params.base.size * sizeof(deUint32), usageFlags));
+	MovePtr<ExternalHostMemory>		hostMemory;
+	MovePtr<Allocation>				markerMemory;
+
+	createMarkerBufferMemory(context.getInstanceInterface(), vk, context.getPhysicalDevice(), device,
+		*markerBuffer, wd.allocator, MemoryRequirement::HostVisible, params.base.useHostPtr, hostMemory, markerMemory);
+
+	de::Random						rng(size ^ params.base.size);
+	std::vector<deUint32>			expected(params.base.size, 0);
+
+	Move<VkDescriptorPool>			descriptorPool;
+	Move<VkDescriptorSetLayout>		descriptorSetLayout;
+	Move<VkDescriptorSet>			descriptorSet;
+	Move<VkPipelineLayout>			pipelineLayout;
+	VkShaderStageFlags				pushConstantStage = 0;
+
+	if ((params.method == MEMORY_DEP_DRAW) || (params.method == MEMORY_DEP_DISPATCH))
+	{
+		DescriptorPoolBuilder descriptorPoolBuilder;
+
+		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u);
+		descriptorPool = descriptorPoolBuilder.build(vk, device, 0, 1u);
+
+		DescriptorSetLayoutBuilder setLayoutBuilder;
+
+		setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
+		descriptorSetLayout = setLayoutBuilder.build(vk, device);
+
+		const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
+		{
+			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
+			DE_NULL,											// const void*					pNext;
+			*descriptorPool,									// VkDescriptorPool				descriptorPool;
+			1u,													// deUint32						setLayoutCount;
+			&descriptorSetLayout.get()						// const VkDescriptorSetLayout*	pSetLayouts;
+		};
+
+		descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocateInfo);
+
+		VkDescriptorBufferInfo markerBufferInfo = { *markerBuffer, 0, VK_WHOLE_SIZE };
+
+		VkWriteDescriptorSet writeSet[] =
+		{
+			{
+				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType                  sType;
+				DE_NULL,								// const void*                      pNext;
+				descriptorSet.get(),					// VkDescriptorSet                  dstSet;
+				0,										// uint32_t                         dstBinding;
+				0,										// uint32_t                         dstArrayElement;
+				1,										// uint32_t                         descriptorCount;
+				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType                 descriptorType;
+				DE_NULL,								// const VkDescriptorImageInfo*     pImageInfo;
+				&markerBufferInfo,						// const VkDescriptorBufferInfo*    pBufferInfo;
+				DE_NULL									// const VkBufferView*              pTexelBufferViev
+			}
+		};
+
+		vk.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(writeSet), writeSet, 0, DE_NULL);
+
+		VkDescriptorSetLayout setLayout = descriptorSetLayout.get();
+
+		pushConstantStage = (params.method == MEMORY_DEP_DISPATCH ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT);
+
+		const VkPushConstantRange pushConstantRange =
+		{
+			pushConstantStage,	// VkShaderStageFlags    stageFlags;
+			0u,					// uint32_t              offset;
+			2*sizeof(deUint32),	// uint32_t              size;
+		};
+
+		const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
+			DE_NULL,											// const void*					pNext;
+			(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
+			1u,													// deUint32						setLayoutCount;
+			&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
+			1u,													// deUint32						pushConstantRangeCount;
+			&pushConstantRange,									// const VkPushConstantRange*	pPushConstantRanges;
+		};
+
+		pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutInfo);
+	}
+
+	Move<VkRenderPass>		renderPass;
+	Move<VkFramebuffer>		fbo;
+	Move<VkPipeline>		pipeline;
+	Move<VkShaderModule>	vertexModule;
+	Move<VkShaderModule>	fragmentModule;
+	Move<VkShaderModule>	computeModule;
+
+	if (params.method == MEMORY_DEP_DRAW)
+	{
+		const VkSubpassDescription subpassInfo =
+		{
+			0,									// VkSubpassDescriptionFlags       flags;
+			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint             pipelineBindPoint;
+			0,									// uint32_t                        inputAttachmentCount;
+			DE_NULL,							// const VkAttachmentReference*    pInputAttachments;
+			0,									// uint32_t                        colorAttachmentCount;
+			DE_NULL,							// const VkAttachmentReference*    pColorAttachments;
+			0,									// const VkAttachmentReference*    pResolveAttachments;
+			DE_NULL,							// const VkAttachmentReference*    pDepthStencilAttachment;
+			0,									// uint32_t                        preserveAttachmentCount;
+			DE_NULL								// const uint32_t*                 pPreserveAttachments;
+		};
+
+		const VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType                   sType;
+			DE_NULL,									// const void*                       pNext;
+			0,											// VkRenderPassCreateFlags           flags;
+			0,											// uint32_t                          attachmentCount;
+			DE_NULL,									// const VkAttachmentDescription*    pAttachments;
+			1,											// uint32_t                          subpassCount;
+			&subpassInfo,								// const VkSubpassDescription*       pSubpasses;
+			0,											// uint32_t                          dependencyCount;
+			DE_NULL										// const VkSubpassDependency*        pDependencies
+		};
+
+		renderPass = createRenderPass(vk, device, &renderPassInfo);
+
+		const VkFramebufferCreateInfo framebufferInfo =
+		{
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType             sType;
+			DE_NULL,									// const void*                 pNext;
+			0,											// VkFramebufferCreateFlags    flags;
+			renderPass.get(),							// VkRenderPass                renderPass;
+			0,											// uint32_t                    attachmentCount;
+			DE_NULL,									// const VkImageView*          pAttachments;
+			1,											// uint32_t                    width;
+			1,											// uint32_t                    height;
+			1,											// uint32_t                    layers;
+		};
+
+		fbo = createFramebuffer(vk, device, &framebufferInfo);
+
+		vertexModule   = createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u);
+		fragmentModule = createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u);
+
+		const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+			DE_NULL,														// const void*								pNext;
+			(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags	flags;
+			0,																// uint32_t									vertexBindingDescriptionCount;
+			DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+			0,																// uint32_t									vertexAttributeDescriptionCount;
+			DE_NULL,														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+		};
+
+		const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,														// const void*								pNext;
+			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
+			VK_PRIMITIVE_TOPOLOGY_POINT_LIST,								// VkPrimitiveTopology						topology;
+			VK_FALSE,														// VkBool32									primitiveRestartEnable;
+		};
+
+		std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
+
+		{
+			const VkPipelineShaderStageCreateInfo createInfo =
+			{
+				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+				DE_NULL,												// const void*							pNext;
+				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+				VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
+				vertexModule.get(),										// VkShaderModule						module;
+				"main",													// const char*							pName;
+				DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+			};
+
+			shaderStages.push_back(createInfo);
+		}
+
+		{
+			const VkPipelineShaderStageCreateInfo createInfo =
+			{
+				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+				DE_NULL,												// const void*							pNext;
+				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+				VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
+				fragmentModule.get(),									// VkShaderModule						module;
+				"main",													// const char*							pName;
+				DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+			};
+
+			shaderStages.push_back(createInfo);
+		}
+
+		VkViewport viewport = {};
+
+		viewport.x			= 0;
+		viewport.y			= 0;
+		viewport.width		= 1;
+		viewport.height		= 1;
+		viewport.minDepth	= 0.0f;
+		viewport.maxDepth	= 1.0f;
+
+		VkRect2D scissor = {};
+
+		scissor.offset.x		= 0;
+		scissor.offset.y		= 0;
+		scissor.extent.width	= 1;
+		scissor.extent.height	= 1;
+
+		const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
+			DE_NULL,														// const void*							pNext;
+			(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags	flags;
+			1u,																// uint32_t								viewportCount;
+			&viewport,														// const VkViewport*					pViewports;
+			1u,																// uint32_t								scissorCount;
+			&scissor,														// const VkRect2D*						pScissors;
+		};
+
+		const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,													// const void*								pNext;
+			(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags	flags;
+			VK_FALSE,													// VkBool32									depthClampEnable;
+			VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
+			VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
+			VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
+			VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
+			VK_FALSE,													// VkBool32									depthBiasEnable;
+			0.0f,														// float									depthBiasConstantFactor;
+			0.0f,														// float									depthBiasClamp;
+			0.0f,														// float									depthBiasSlopeFactor;
+			1.0f,														// float									lineWidth;
+		};
+
+		const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
+		{
+
+			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,													// const void*								pNext;
+			(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
+			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
+			VK_FALSE,													// VkBool32									sampleShadingEnable;
+			1.0f,														// float									minSampleShading;
+			DE_NULL,													// const VkSampleMask*						pSampleMask;
+			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
+			VK_FALSE,													// VkBool32									alphaToOneEnable;
+		};
+
+		const VkStencilOpState noStencilOp = {};
+
+		VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,													// const void*								pNext;
+			(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
+			VK_FALSE,													// VkBool32									depthTestEnable;
+			VK_FALSE,													// VkBool32									depthWriteEnable;
+			VK_COMPARE_OP_ALWAYS,										// VkCompareOp								depthCompareOp;
+			VK_FALSE,													// VkBool32									depthBoundsTestEnable;
+			VK_FALSE,													// VkBool32									stencilTestEnable;
+			noStencilOp,												// VkStencilOpState							front;
+			noStencilOp,												// VkStencilOpState							back;
+			0.0f,														// float									minDepthBounds;
+			1.0f,														// float									maxDepthBounds;
+		};
+
+		const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+			DE_NULL,													// const void*									pNext;
+			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
+			VK_FALSE,													// VkBool32										logicOpEnable;
+			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+			0,															// deUint32										attachmentCount;
+			DE_NULL,													// const VkPipelineColorBlendAttachmentState*	pAttachments;
+			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
+		};
+
+		const VkGraphicsPipelineCreateInfo	graphicsPipelineInfo =
+		{
+			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,			// VkStructureType									sType;
+			DE_NULL,													// const void*										pNext;
+			(VkPipelineCreateFlags)0,									// VkPipelineCreateFlags							flags;
+			static_cast<deUint32>(shaderStages.size()),					// deUint32											stageCount;
+			dataOrNullPtr(shaderStages),								// const VkPipelineShaderStageCreateInfo*			pStages;
+			&vertexInputStateInfo,										// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
+			&pipelineInputAssemblyStateInfo,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
+			DE_NULL,													// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
+			&pipelineViewportStateInfo,									// const VkPipelineViewportStateCreateInfo*			pViewportState;
+			&pipelineRasterizationStateInfo,							// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
+			&pipelineMultisampleStateInfo,								// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
+			&pipelineDepthStencilStateInfo,								// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
+			&pipelineColorBlendStateInfo,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
+			DE_NULL,													// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
+			pipelineLayout.get(),										// VkPipelineLayout									layout;
+			renderPass.get(),											// VkRenderPass										renderPass;
+			0,															// deUint32											subpass;
+			DE_NULL,													// VkPipeline										basePipelineHandle;
+			-1,															// deInt32											basePipelineIndex;
+		};
+
+		pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
+	}
+	else if (params.method == MEMORY_DEP_DISPATCH)
+	{
+		computeModule = createShaderModule(vk, device, context.getBinaryCollection().get("comp"), 0u);
+
+		const VkPipelineShaderStageCreateInfo shaderStageInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			DE_NULL,												// const void*							pNext;
+			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
+			computeModule.get(),									// VkShaderModule						module;
+			"main",													// const char*							pName;
+			DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
+		};
+
+		const VkComputePipelineCreateInfo computePipelineInfo =
+		{
+			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType;
+			DE_NULL,										// const void*                        pNext;
+			0u,												// VkPipelineCreateFlags              flags;
+			shaderStageInfo,								// VkPipelineShaderStageCreateInfo    stage;
+			pipelineLayout.get(),							// VkPipelineLayout                   layout;
+			DE_NULL,										// VkPipeline                         basePipelineHandle;
+			0												// int32_t                            basePipelineIndex;
+		};
+
+		pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineInfo);
+	}
+
+	deMemcpy(markerMemory->getHostPtr(), &expected[0], static_cast<size_t>(markerBufferSize));
+	flushMappedMemoryRange(vk, device, markerMemory->getMemory(), markerMemory->getOffset(), VK_WHOLE_SIZE);
+
+	const Unique<VkCommandPool>		cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, wd.queueFamilyIdx));
+	const Unique<VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	VkDescriptorSet setHandle = *descriptorSet;
+
+	std::vector<MemoryDepOwner>	dataOwner(size, MEMORY_DEP_OWNER_NOBODY);
+
+	if (params.method == MEMORY_DEP_DRAW)
+	{
+		const VkRenderPassBeginInfo beginInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType        sType;
+			DE_NULL,									// const void*            pNext;
+			renderPass.get(),							// VkRenderPass           renderPass;
+			fbo.get(),									// VkFramebuffer          framebuffer;
+			{ { 0, 0, }, { 1, 1 } },					// VkRect2D               renderArea;
+			0,											// uint32_t               clearValueCount;
+			DE_NULL										// const VkClearValue*    pClearValues;
+		};
+
+		vk.cmdBeginRenderPass(*cmdBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
+		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
+		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &setHandle, 0, DE_NULL);
+	}
+	else if (params.method == MEMORY_DEP_DISPATCH)
+	{
+		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &setHandle, 0, DE_NULL);
+	}
+
+	deMemcpy(markerMemory->getHostPtr(), &expected[0], static_cast<size_t>(markerBufferSize));
+	flushMappedMemoryRange(vk, device, markerMemory->getMemory(), markerMemory->getOffset(), VK_WHOLE_SIZE);
+
+	deUint32 writeStages = 0;
+	deUint32 writeAccess = 0;
+
+	for (deUint32 i = 0; i < numIters; ++i)
+	{
+		deUint32		slot		= rng.getUint32() % size;
+		MemoryDepOwner	oldOwner	= dataOwner[slot];
+		MemoryDepOwner	newOwner	= static_cast<MemoryDepOwner>(1 + (rng.getUint32() % 2));
+
+		DE_ASSERT(newOwner == MEMORY_DEP_OWNER_MARKER || newOwner == MEMORY_DEP_OWNER_NON_MARKER);
+		DE_ASSERT(slot < size);
+
+		if ((oldOwner != newOwner && oldOwner != MEMORY_DEP_OWNER_NOBODY) ||
+			(oldOwner == MEMORY_DEP_OWNER_NON_MARKER && newOwner == MEMORY_DEP_OWNER_NON_MARKER))
+		{
+			VkBufferMemoryBarrier memoryDep =
+			{
+				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,    // VkStructureType    sType;
+				DE_NULL,                                    // const void*        pNext;
+				0,                                          // VkAccessFlags      srcAccessMask;
+				0,                                          // VkAccessFlags      dstAccessMask;
+				wd.queueFamilyIdx,                          // uint32_t           srcQueueFamilyIndex;
+				wd.queueFamilyIdx,                          // uint32_t           dstQueueFamilyIndex;
+				*markerBuffer,                              // VkBuffer           buffer;
+				sizeof(deUint32) * slot,                    // VkDeviceSize       offset;
+				sizeof(deUint32)                            // VkDeviceSize       size;
+			};
+
+			VkPipelineStageFlags srcStageMask;
+			VkPipelineStageFlags dstStageMask;
+
+			computeMemoryDepBarrier(params.method, oldOwner, params.base.stage, &memoryDep.srcAccessMask, &srcStageMask);
+			computeMemoryDepBarrier(params.method, newOwner, params.base.stage, &memoryDep.dstAccessMask, &dstStageMask);
+
+			vk.cmdPipelineBarrier(*cmdBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 1, &memoryDep, 0, DE_NULL);
+		}
+
+		const deUint32 value = i;
+
+		if (newOwner == MEMORY_DEP_OWNER_MARKER)
+		{
+			vk.cmdWriteBufferMarkerAMD(*cmdBuffer, params.base.stage, *markerBuffer, sizeof(deUint32) * slot, value);
+
+			writeStages |= params.base.stage;
+			writeAccess |= VK_ACCESS_TRANSFER_WRITE_BIT;
+		}
+		else
+		{
+			DE_ASSERT(newOwner == MEMORY_DEP_OWNER_NON_MARKER);
+
+			if (params.method == MEMORY_DEP_COPY)
+			{
+				vk.cmdUpdateBuffer(*cmdBuffer, *markerBuffer, sizeof(deUint32) * slot, sizeof(deUint32), &value);
+
+				writeStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+				writeAccess |= VK_ACCESS_TRANSFER_WRITE_BIT;
+			}
+			else if (params.method == MEMORY_DEP_DRAW)
+			{
+				const deUint32 pushConst[] = { slot, value };
+
+				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, pushConstantStage, 0, sizeof(pushConst), pushConst);
+				vk.cmdDraw(*cmdBuffer, 1, 1, i, 0);
+
+				writeStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+				writeAccess |= VK_ACCESS_SHADER_WRITE_BIT;
+			}
+			else
+			{
+				const deUint32 pushConst[] = { slot, value };
+
+				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, pushConstantStage, 0, sizeof(pushConst), pushConst);
+				vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
+
+				writeStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+				writeAccess |= VK_ACCESS_SHADER_WRITE_BIT;
+			}
+		}
+
+		dataOwner[slot] = newOwner;
+		expected[slot]  = value;
+	}
+
+	if (params.method == MEMORY_DEP_DRAW)
+	{
+		vk.cmdEndRenderPass(*cmdBuffer);
+	}
+
+	const VkMemoryBarrier memoryDep =
+	{
+		VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+		DE_NULL,
+		writeAccess,
+		VK_ACCESS_HOST_READ_BIT,
+	};
+
+	vk.cmdPipelineBarrier(*cmdBuffer, writeStages, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memoryDep, 0, DE_NULL, 0, DE_NULL);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+
+	submitCommandsAndWait(vk, device, wd.queue, *cmdBuffer);
+
+	if (!checkMarkerBuffer(vk, device, markerMemory, 0, expected))
+		return tcu::TestStatus::fail("Some marker values were incorrect");
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+void initMemoryDepPrograms(SourceCollections& programCollection, const MemoryDepParams params)
+{
+	if (params.method == MEMORY_DEP_DRAW)
+	{
+		{
+			std::ostringstream src;
+
+            src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                << "layout(location = 0) flat out uint offset;\n"
+                << "out gl_PerVertex { vec4 gl_Position; };\n"
+				<< "void main() {\n"
+				<< "	offset = gl_VertexIndex;\n"
+				<< "	gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
+				<< "}\n";
+
+			programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+		}
+
+		{
+			std::ostringstream src;
+
+			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+				<< "layout(push_constant) uniform Constants { uvec2 params; } pc;\n"
+				<< "layout(std430, set = 0, binding = 0) buffer Data { uint elems[]; } data;\n"
+				<< "layout(location = 0) flat in uint offset;\n"
+				<< "void main() {\n"
+				<< "	data.elems[pc.params.x] = pc.params.y;\n"
+				<< "}\n";
+
+			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+		}
+	}
+	else if (params.method == MEMORY_DEP_DISPATCH)
+	{
+		{
+			std::ostringstream src;
+
+			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+				<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
+				<< "layout(push_constant) uniform Constants { uvec2 params; } pc;\n"
+				<< "layout(std430, set = 0, binding = 0) buffer Data { uint elems[]; } data;\n"
+				<< "void main() {\n"
+				<< "	data.elems[pc.params.x] = pc.params.y;\n"
+				<< "}\n";
+
+			programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
+		}
+	}
+}
+
+void checkBufferMarkerSupport (Context& context, BaseTestParams params)
+{
+	if (params.useHostPtr)
+		context.requireDeviceFunctionality("VK_EXT_external_memory_host");
+
+	context.requireDeviceFunctionality("VK_AMD_buffer_marker");
+}
+
+void checkBufferMarkerSupport (Context& context, MemoryDepParams params)
+{
+	if (params.base.useHostPtr)
+		context.requireDeviceFunctionality("VK_EXT_external_memory_host");
+
+	context.requireDeviceFunctionality("VK_AMD_buffer_marker");
+}
+
+tcu::TestCaseGroup* createBufferMarkerTestsInGroup(tcu::TestContext& testCtx)
+{
+	tcu::TestCaseGroup* root = (new tcu::TestCaseGroup(testCtx, "buffer_marker", "AMD_buffer_marker Tests"));
+
+	VkQueueFlagBits queues[] = { VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT };
+	const char* queueNames[] = { "graphics", "compute", "transfer" };
+
+	BaseTestParams base = {};
+
+	for (size_t queueNdx = 0; queueNdx < DE_LENGTH_OF_ARRAY(queues); ++queueNdx)
+	{
+		tcu::TestCaseGroup* queueGroup = (new tcu::TestCaseGroup(testCtx, queueNames[queueNdx], "Buffer marker tests for a specific queue family"));
+
+		const char* memoryNames[] = { "external_host_mem", "default_mem" };
+		const bool memoryTypes[] = { true, false };
+
+		base.testQueue = queues[queueNdx];
+
+		for (size_t memNdx = 0; memNdx < DE_LENGTH_OF_ARRAY(memoryTypes); ++memNdx)
+		{
+			tcu::TestCaseGroup* memoryGroup = (new tcu::TestCaseGroup(testCtx, memoryNames[memNdx], "Buffer marker tests for different kinds of backing memory"));
+
+			base.useHostPtr = memoryTypes[memNdx];
+
+			VkPipelineStageFlagBits stages[] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT };
+			const char* stageNames[] = { "top_of_pipe", "bottom_of_pipe" };
+
+			for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
+			{
+				tcu::TestCaseGroup* stageGroup = (new tcu::TestCaseGroup(testCtx, stageNames[stageNdx], "Buffer marker tests for a specific pipeline stage"));
+
+				base.stage = stages[stageNdx];
+
+				{
+					tcu::TestCaseGroup* sequentialGroup = (new tcu::TestCaseGroup(testCtx, "sequential", "Buffer marker tests for sequentially writing"));
+
+					base.size = 4;
+
+					addFunctionCase(sequentialGroup, "4", "Writes 4 sequential marker values into a buffer", checkBufferMarkerSupport, bufferMarkerSequential, base);
+
+					base.size = 64;
+
+					addFunctionCase(sequentialGroup, "64", "Writes 64 sequential marker values into a buffer", checkBufferMarkerSupport, bufferMarkerSequential, base);
+
+					base.size = 65536;
+
+					addFunctionCase(sequentialGroup, "65536", "Writes 65536 sequential marker values into a buffer", checkBufferMarkerSupport, bufferMarkerSequential, base);
+
+					stageGroup->addChild(sequentialGroup);
+				}
+
+				{
+					tcu::TestCaseGroup* overwriteGroup = (new tcu::TestCaseGroup(testCtx, "overwrite", "Buffer marker tests for overwriting values with implicit synchronization"));
+
+					base.size = 1;
+
+					addFunctionCase(overwriteGroup, "1", "Randomly overwrites marker values to a 1-size buffer", checkBufferMarkerSupport, bufferMarkerOverwrite, base);
+
+					base.size = 4;
+
+					addFunctionCase(overwriteGroup, "4", "Randomly overwrites marker values to a 4-size buffer", checkBufferMarkerSupport, bufferMarkerOverwrite, base);
+
+					base.size = 64;
+
+					addFunctionCase(overwriteGroup, "64", "Randomly overwrites markers values to a 64-size buffer", checkBufferMarkerSupport, bufferMarkerOverwrite, base);
+
+					stageGroup->addChild(overwriteGroup);
+				}
+
+				{
+					tcu::TestCaseGroup* memoryDepGroup = (new tcu::TestCaseGroup(testCtx, "memory_dep", "Buffer marker tests for memory dependencies between marker writes and other operations"));
+
+					MemoryDepParams params = {};
+
+					params.base		 = base;
+					params.base.size = 128;
+
+					if (params.base.testQueue == VK_QUEUE_GRAPHICS_BIT)
+					{
+						params.method = MEMORY_DEP_DRAW;
+
+						addFunctionCaseWithPrograms(memoryDepGroup, "draw", "Test memory dependencies between marker writes and draws", checkBufferMarkerSupport, initMemoryDepPrograms, bufferMarkerMemoryDep, params);
+					}
+
+					if (params.base.testQueue != VK_QUEUE_TRANSFER_BIT)
+					{
+						params.method = MEMORY_DEP_DISPATCH;
+
+						addFunctionCaseWithPrograms(memoryDepGroup, "dispatch", "Test memory dependencies between marker writes and compute dispatches", checkBufferMarkerSupport, initMemoryDepPrograms, bufferMarkerMemoryDep, params);
+					}
+
+					params.method = MEMORY_DEP_COPY;
+
+					addFunctionCaseWithPrograms(memoryDepGroup, "buffer_copy", "Test memory dependencies between marker writes and buffer copies", checkBufferMarkerSupport, initMemoryDepPrograms, bufferMarkerMemoryDep, params);
+
+					stageGroup->addChild(memoryDepGroup);
+				}
+
+				memoryGroup->addChild(stageGroup);
+			}
+
+			queueGroup->addChild(memoryGroup);
+		}
+
+		root->addChild(queueGroup);
+	}
+
+	return root;
+}
+
+} // anonymous ns
+
+tcu::TestCaseGroup* createBufferMarkerTests (tcu::TestContext& testCtx)
+{
+	return createBufferMarkerTestsInGroup(testCtx);
+}
+
+} // api
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.hpp b/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.hpp
new file mode 100644
index 0000000..da60329
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/api/vktApiBufferMarkerTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTAPIBUFFERMARKERTESTS_HPP
+#define _VKTAPIBUFFERMARKERTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_buffer_marker
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace api
+{
+
+extern tcu::TestCaseGroup* createBufferMarkerTests (tcu::TestContext& testCtx);
+
+} // api
+} // vkt
+
+#endif // _VKTAPIBUFFERMARKERTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
index 768a500..c40b85d 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
@@ -276,6 +276,7 @@
 	tcu::TextureFormat format;
 	switch (combinedFormat.type)
 	{
+		case tcu::TextureFormat::UNORM_INT16:
 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
 			break;
@@ -283,6 +284,7 @@
 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
 			break;
 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
+		case tcu::TextureFormat::FLOAT:
 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
 			break;
 		default:
@@ -627,8 +629,16 @@
 	else
 	{
 		const tcu::UVec4 threshold (0u);
-		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
-			return tcu::TestStatus::fail("CopiesAndBlitting test");
+		if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
+		{
+			if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
+				return tcu::TestStatus::fail("CopiesAndBlitting test");
+		}
+		else
+		{
+			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
+				return tcu::TestStatus::fail("CopiesAndBlitting test");
+		}
 	}
 
 	return tcu::TestStatus::pass("CopiesAndBlitting test");
@@ -1783,6 +1793,314 @@
 	}
 }
 
+class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
+{
+public:
+								CopyBufferToDepthStencil	(Context& context,
+															 TestParams	testParams);
+	virtual tcu::TestStatus		iterate						(void);
+private:
+	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
+
+	tcu::TextureFormat			m_textureFormat;
+	VkDeviceSize				m_bufferSize;
+
+	Move<VkBuffer>				m_source;
+	de::MovePtr<Allocation>		m_sourceBufferAlloc;
+	Move<VkImage>				m_destination;
+	de::MovePtr<Allocation>		m_destinationImageAlloc;
+};
+
+void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
+{
+	DE_UNREF(mipLevel);
+
+	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
+	if (!rowLength)
+		rowLength = region.bufferImageCopy.imageExtent.width;
+
+	deUint32			imageHeight = region.bufferImageCopy.bufferImageHeight;
+	if (!imageHeight)
+		imageHeight = region.bufferImageCopy.imageExtent.height;
+
+	const int			texelSize	= dst.getFormat().getPixelSize();
+	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
+	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
+	const int			texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
+
+	for (deUint32 z = 0; z < extent.depth; z++)
+	{
+		for (deUint32 y = 0; y < extent.height; y++)
+		{
+			int									texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
+			const tcu::ConstPixelBufferAccess	srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
+			const tcu::PixelBufferAccess		dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
+				region.bufferImageCopy.imageExtent.width, 1, 1);
+
+			if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
+			{
+				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
+			}
+			else
+			{
+				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
+			}
+		}
+	}
+}
+
+bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
+{
+	VkFormatProperties formatProps;
+	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
+	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
+}
+
+CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
+	: CopiesAndBlittingTestInstance(context, testParams)
+	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
+	, m_bufferSize(0)
+{
+	const InstanceInterface&	vki					= context.getInstanceInterface();
+	const DeviceInterface&		vk					= context.getDeviceInterface();
+	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
+	const VkDevice				vkDevice			= context.getDevice();
+	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
+	Allocator&					memAlloc			= context.getDefaultAllocator();
+	const bool					hasDepth			= tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
+	const bool					hasStencil			= tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
+
+	if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
+	{
+		TCU_THROW(NotSupportedError, "Image format not supported.");
+	}
+
+	if (hasDepth)
+	{
+		glw::GLuint texelSize = m_textureFormat.getPixelSize();
+		if (texelSize > sizeof(float))
+		{
+			// We must have D32F_S8 format, depth must be packed so we only need
+			// to allocate space for the D32F part. Stencil will be separate
+			texelSize = sizeof(float);
+		}
+		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
+	}
+	if (hasStencil)
+	{
+		// Stencil is always 8bits and packed.
+		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
+	}
+
+	// Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
+	{
+		const VkBufferCreateInfo	sourceBufferParams		=
+		{
+			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
+			DE_NULL,									// const void*			pNext;
+			0u,											// VkBufferCreateFlags	flags;
+			m_bufferSize,								// VkDeviceSize			size;
+			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
+			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
+			1u,											// deUint32				queueFamilyIndexCount;
+			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
+		};
+
+		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
+		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
+		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
+	}
+
+	// Create destination image
+	{
+		const VkImageCreateInfo		destinationImageParams	=
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
+			DE_NULL,								// const void*			pNext;
+			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
+			m_params.dst.image.imageType,			// VkImageType			imageType;
+			m_params.dst.image.format,				// VkFormat				format;
+			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
+			1u,										// deUint32				mipLevels;
+			getArraySize(m_params.dst.image),		// deUint32				arraySize;
+			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
+			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
+			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
+			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
+			1u,										// deUint32				queueFamilyCount;
+			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
+		};
+
+		m_destination				= createImage(vk, vkDevice, &destinationImageParams);
+		m_destinationImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
+		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
+	}
+}
+
+tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
+{
+	// Create source depth/stencil content. Treat as 1D texture to get different pattern
+	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
+	// Fill buffer with linear gradiant
+	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
+
+	// Create image layer for depth/stencil
+	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
+		m_params.dst.image.extent.width,
+		m_params.dst.image.extent.height,
+		m_params.dst.image.extent.depth));
+
+	// Fill image layer with 2D gradiant
+	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
+
+	// Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
+	// Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
+	// This emulates what the HW will be doing.
+	generateExpectedResult();
+
+	// Upload our source depth/stencil content to the source buffer
+	// This is the buffer that will be used by region commands
+	std::vector<VkBufferImageCopy>	bufferImageCopies;
+	VkDeviceSize					bufferOffset	= 0;
+	const VkDevice					vkDevice		= m_context.getDevice();
+	const DeviceInterface&			vk				= m_context.getDeviceInterface();
+	const VkQueue					queue			= m_context.getUniversalQueue();
+	char*							dstPtr			= reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
+	bool							depthLoaded		= DE_FALSE;
+	bool							stencilLoaded	= DE_FALSE;
+	VkDeviceSize					depthOffset		= 0;
+	VkDeviceSize					stencilOffset	= 0;
+
+	// To be able to test ordering depth & stencil differently
+	// We take the given copy regions and use that as the desired order
+	// and copy the appropriate data into place and compute the appropriate
+	// data offsets to be used in the copy command.
+	for (deUint32 i = 0; i < m_params.regions.size(); i++)
+	{
+		tcu::ConstPixelBufferAccess bufferAccess	= m_sourceTextureLevel->getAccess();
+		deUint32					bufferSize		= bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
+		VkBufferImageCopy			copyData		= m_params.regions[i].bufferImageCopy;
+		char*						srcPtr;
+
+		if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
+		{
+			if (!depthLoaded)
+			{
+				// Create level that is same component as depth buffer (e.g. D16, D24, D32F)
+				tcu::TextureLevel	depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
+				bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
+				// Copy depth component only from source data. This gives us packed depth-only data.
+				tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
+				srcPtr = (char*)depthTexture.getAccess().getDataPtr();
+				// Copy packed depth-only data to output buffer
+				deMemcpy(dstPtr, srcPtr, bufferSize);
+				depthLoaded = DE_TRUE;
+				depthOffset = bufferOffset;
+				dstPtr += bufferSize;
+				bufferOffset += bufferSize;
+			}
+			copyData.bufferOffset += depthOffset;
+		}
+		else if (!stencilLoaded)
+		{
+			if (!stencilLoaded)
+			{
+				// Create level that is same component as stencil buffer (always 8-bits)
+				tcu::TextureLevel	stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
+				// Copy stencil component only from source data. This gives us packed stencil-only data.
+				tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
+				srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
+				// Copy packed stencil-only data to output buffer
+				deMemcpy(dstPtr, srcPtr, bufferSize);
+				stencilLoaded = DE_TRUE;
+				stencilOffset = bufferOffset;
+				dstPtr += bufferSize;
+				bufferOffset += bufferSize;
+			}
+			copyData.bufferOffset += stencilOffset;
+		}
+
+		bufferImageCopies.push_back(copyData);
+	}
+
+	flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
+
+	// Upload the depth/stencil data from m_destinationTextureLevel to initialize
+	// depth and stencil to known values.
+	// Uses uploadImageAspect so makes its own buffers for depth and stencil
+	// aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
+	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
+
+	const VkImageMemoryBarrier	imageBarrier	=
+	{
+		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
+		DE_NULL,									// const void*				pNext;
+		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
+		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
+		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
+		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
+		*m_destination,								// VkImage					image;
+		{											// VkImageSubresourceRange	subresourceRange;
+			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
+			0u,								// deUint32				baseMipLevel;
+			1u,								// deUint32				mipLevels;
+			0u,								// deUint32				baseArraySlice;
+			1u								// deUint32				arraySize;
+		}
+	};
+
+	// Copy from buffer to depth/stencil image
+
+	beginCommandBuffer(vk, *m_cmdBuffer);
+	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
+
+	if (m_params.singleCommand)
+	{
+		// Issue a single copy command with regions defined by the test.
+		vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
+	}
+	else
+	{
+		// Issue a a copy command per region defined by the test.
+		for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
+		{
+			vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
+		}
+	}
+	endCommandBuffer(vk, *m_cmdBuffer);
+
+	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
+
+	de::MovePtr<tcu::TextureLevel>	resultLevel = readImage(*m_destination, m_params.dst.image);
+
+	return checkTestResult(resultLevel->getAccess());
+}
+
+class CopyBufferToDepthStencilTestCase : public vkt::TestCase
+{
+public:
+							CopyBufferToDepthStencilTestCase	(tcu::TestContext&		testCtx,
+																 const std::string&		name,
+																 const std::string&		description,
+																 const TestParams		params)
+								: vkt::TestCase(testCtx, name, description)
+								, m_params(params)
+							{}
+
+	virtual					~CopyBufferToDepthStencilTestCase	(void) {}
+
+	virtual TestInstance*	createInstance						(Context&				context) const
+							{
+								return new CopyBufferToDepthStencil(context, m_params);
+							}
+private:
+	TestParams				m_params;
+};
+
 // Copy from image to image with scaling.
 
 class BlittingImages : public CopiesAndBlittingTestInstance
@@ -5041,6 +5359,9 @@
 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
 		params.allocationKind				= allocationKind;
 
+		bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
+		bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
+
 		const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
 		const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
 
@@ -5051,7 +5372,7 @@
 			const VkOffset3D	dstOffset	= {i, 0, 0};
 			const VkExtent3D	extent		= {defaultFourthSize, 1, 1};
 
-			if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
+			if (hasDepth)
 			{
 				const VkImageCopy				testCopy	=
 				{
@@ -5065,7 +5386,7 @@
 				copyRegion.imageCopy	= testCopy;
 				params.regions.push_back(copyRegion);
 			}
-			if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
+			if (hasStencil)
 			{
 				const VkImageCopy				testCopy	=
 				{
@@ -5100,12 +5421,12 @@
 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
 		params.allocationKind				= allocationKind;
 
-		const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
-		const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
-
 		bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
 		bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
 
+		const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
+		const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
+
 		for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
 		{
 			CopyRegion			copyRegion;
@@ -5656,6 +5977,134 @@
 	}
 }
 
+void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+	tcu::TestContext& testCtx = group->getTestContext();
+
+	const struct
+	{
+		const char* name;
+		const VkFormat							format;
+	} depthAndStencilFormats[] =
+	{
+		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
+		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
+		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
+		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
+		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
+		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
+	};
+
+	const VkImageSubresourceLayers	depthSourceLayer =
+	{
+		VK_IMAGE_ASPECT_DEPTH_BIT,		// VkImageAspectFlags	aspectMask;
+		0u,							// deUint32				mipLevel;
+		0u,							// deUint32				baseArrayLayer;
+		1u,							// deUint32				layerCount;
+	};
+
+	const VkBufferImageCopy	bufferDepthCopy =
+	{
+		0u,											// VkDeviceSize				bufferOffset;
+		0u,											// deUint32					bufferRowLength;
+		0u,											// deUint32					bufferImageHeight;
+		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
+		{0, 0, 0},									// VkOffset3D				imageOffset;
+		defaultExtent								// VkExtent3D				imageExtent;
+	};
+	CopyRegion	copyDepthRegion;
+	copyDepthRegion.bufferImageCopy = bufferDepthCopy;
+
+	const VkImageSubresourceLayers	stencilSourceLayer =
+	{
+		VK_IMAGE_ASPECT_STENCIL_BIT,		// VkImageAspectFlags	aspectMask;
+		0u,							// deUint32				mipLevel;
+		0u,							// deUint32				baseArrayLayer;
+		1u,							// deUint32				layerCount;
+	};
+
+	const VkBufferImageCopy	bufferStencilCopy =
+	{
+		0u,											// VkDeviceSize				bufferOffset;
+		0u,											// deUint32					bufferRowLength;
+		0u,											// deUint32					bufferImageHeight;
+		stencilSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
+		{0, 0, 0},									// VkOffset3D				imageOffset;
+		defaultExtent								// VkExtent3D				imageExtent;
+	};
+
+	CopyRegion	copyStencilRegion;
+	copyStencilRegion.bufferImageCopy = bufferStencilCopy;
+
+	// Note: Depth stencil tests I want to do
+	// Formats: D16, D24S8, D32FS8
+	// Test writing each component with separate CopyBufferToImage commands
+	// Test writing both components in one CopyBufferToImage command
+	// Swap order of writes of Depth & Stencil
+	// whole surface, subimages?
+	// Similar tests as BufferToImage?
+	for (const auto config : depthAndStencilFormats)
+	{
+		// TODO: Check that this format is supported before creating tests?
+		//if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
+
+		const tcu::TextureFormat format = mapVkFormat(config.format);
+		const bool hasDepth = tcu::hasDepthComponent(format.order);
+		const bool hasStencil = tcu::hasStencilComponent(format.order);
+		std::string description = config.name;
+
+		TestParams	params;
+		params.src.buffer.size = defaultSize * defaultSize;
+		params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+		params.dst.image.format = config.format;
+		params.dst.image.extent = defaultExtent;
+		params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
+		params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+		params.allocationKind = allocationKind;
+
+		if (hasDepth && hasStencil)
+		{
+			params.singleCommand = DE_TRUE;
+
+			params.regions.push_back(copyDepthRegion);
+			params.regions.push_back(copyStencilRegion);
+
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
+
+			params.singleCommand = DE_FALSE;
+
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
+
+			params.regions.clear();
+			params.regions.push_back(copyStencilRegion);
+			params.regions.push_back(copyDepthRegion);
+
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
+
+			params.singleCommand = DE_TRUE;
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
+
+		}
+
+		if (hasStencil)
+		{
+			params.regions.clear();
+			params.regions.push_back(copyStencilRegion);
+
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
+		}
+
+
+		if (hasDepth)
+		{
+			params.regions.clear();
+			params.regions.push_back(copyDepthRegion);
+
+			group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
+		}
+	}
+}
+
 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
 {
 	tcu::TestContext& testCtx	= group->getTestContext();
@@ -8147,6 +8596,7 @@
 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
+	addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind);
 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
diff --git a/external/vulkancts/modules/vulkan/api/vktApiDriverPropertiesTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiDriverPropertiesTests.cpp
index 1ca6caf..419dc20 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiDriverPropertiesTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiDriverPropertiesTests.cpp
@@ -65,25 +65,33 @@
 
 static const VkConformanceVersionKHR knownConformanceVersions[] =
 {
-	makeConformanceVersionKHR(1, 1, 6, 3),
-	makeConformanceVersionKHR(1, 1, 6, 2),
-	makeConformanceVersionKHR(1, 1, 6, 1),
-	makeConformanceVersionKHR(1, 1, 6, 0),
-	makeConformanceVersionKHR(1, 1, 5, 2),
-	makeConformanceVersionKHR(1, 1, 5, 1),
-	makeConformanceVersionKHR(1, 1, 5, 0),
-	makeConformanceVersionKHR(1, 1, 4, 3),
-	makeConformanceVersionKHR(1, 1, 4, 2),
-	makeConformanceVersionKHR(1, 1, 4, 1),
-	makeConformanceVersionKHR(1, 1, 4, 0),
-	makeConformanceVersionKHR(1, 1, 3, 3),
-	makeConformanceVersionKHR(1, 1, 3, 2),
-	makeConformanceVersionKHR(1, 1, 3, 1),
-	makeConformanceVersionKHR(1, 1, 3, 0),
-	makeConformanceVersionKHR(1, 1, 2, 3),
-	makeConformanceVersionKHR(1, 1, 2, 2),
-	makeConformanceVersionKHR(1, 1, 2, 1),
-	makeConformanceVersionKHR(1, 1, 2, 0),
+	makeConformanceVersion(1, 2, 1, 0),
+	makeConformanceVersion(1, 2, 0, 2),
+	makeConformanceVersion(1, 2, 0, 1),
+	makeConformanceVersion(1, 2, 0, 0),
+	makeConformanceVersion(1, 1, 6, 3),
+	makeConformanceVersion(1, 1, 6, 2),
+	makeConformanceVersion(1, 1, 6, 1),
+	makeConformanceVersion(1, 1, 6, 0),
+	makeConformanceVersion(1, 1, 5, 2),
+	makeConformanceVersion(1, 1, 5, 1),
+	makeConformanceVersion(1, 1, 5, 0),
+	makeConformanceVersion(1, 1, 4, 3),
+	makeConformanceVersion(1, 1, 4, 2),
+	makeConformanceVersion(1, 1, 4, 1),
+	makeConformanceVersion(1, 1, 4, 0),
+	makeConformanceVersion(1, 1, 3, 3),
+	makeConformanceVersion(1, 1, 3, 2),
+	makeConformanceVersion(1, 1, 3, 1),
+	makeConformanceVersion(1, 1, 3, 0),
+	makeConformanceVersion(1, 1, 2, 3),
+	makeConformanceVersion(1, 1, 2, 2),
+	makeConformanceVersion(1, 1, 2, 1),
+	makeConformanceVersion(1, 1, 2, 0),
+	makeConformanceVersion(1, 1, 1, 3),
+	makeConformanceVersion(1, 1, 1, 2),
+	makeConformanceVersion(1, 1, 1, 1),
+	makeConformanceVersion(1, 1, 1, 0),
 };
 
 DE_INLINE bool isNullTerminated(const char* str, const deUint32 maxSize)
@@ -91,7 +99,7 @@
 	return deStrnlen(str, maxSize) < maxSize;
 }
 
-DE_INLINE bool operator==(const VkConformanceVersionKHR& a, const VkConformanceVersionKHR& b)
+DE_INLINE bool operator==(const VkConformanceVersion& a, const VkConformanceVersion& b)
 {
 	return ((a.major == b.major)		&&
 			(a.minor == b.minor)		&&
@@ -134,8 +142,18 @@
 		TCU_FAIL("Driver info is not a null-terminated string");
 }
 
-void testVersion (const VkPhysicalDeviceDriverPropertiesKHR& deviceDriverProperties)
+void testVersion (const VkPhysicalDeviceDriverPropertiesKHR& deviceDriverProperties, deUint32 usedApiVersion)
 {
+	const deUint32 apiMajorVersion = VK_VERSION_MAJOR(usedApiVersion);
+	const deUint32 apiMinorVersion = VK_VERSION_MINOR(usedApiVersion);
+
+	if (deviceDriverProperties.conformanceVersion.major < apiMajorVersion ||
+		(deviceDriverProperties.conformanceVersion.major == apiMajorVersion &&
+		 deviceDriverProperties.conformanceVersion.minor < apiMinorVersion))
+	{
+		TCU_FAIL("Wrong driver conformance version (older than used API version)");
+	}
+
 	for (const VkConformanceVersionKHR* pConformanceVersion  = knownConformanceVersions;
 										pConformanceVersion != DE_ARRAY_END(knownConformanceVersions);
 									  ++pConformanceVersion)
@@ -144,7 +162,7 @@
 			return;
 	}
 
-	TCU_FAIL("Wrong driver conformance version");
+	TCU_FAIL("Wrong driver conformance version (not known)");
 }
 
 tcu::TestStatus testQueryProperties (Context& context, const TestType testType)
@@ -153,7 +171,7 @@
 	const VkPhysicalDevice				physDevice			= context.getPhysicalDevice();
 	const int							memsetPattern		= 0xaa;
 	VkPhysicalDeviceProperties2			deviceProperties2;
-	VkPhysicalDeviceDriverPropertiesKHR	deviceDriverProperties;
+	VkPhysicalDeviceDriverProperties	deviceDriverProperties;
 
 	deMemset(&deviceDriverProperties, memsetPattern, sizeof(deviceDriverProperties));
 	deviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
@@ -168,11 +186,11 @@
 	// Verify the returned values
 	switch (testType)
 	{
-		case TEST_TYPE_DRIVER_ID_MATCH:			testDriverMatch			(deviceDriverProperties);	break;
-		case TEST_TYPE_NAME_IS_NOT_EMPTY:		testNameIsNotEmpty		(deviceDriverProperties);	break;
-		case TEST_TYPE_NAME_ZERO_TERMINATED:	testNameZeroTerminated	(deviceDriverProperties);	break;
-		case TEST_TYPE_INFO_ZERO_TERMINATED:	testInfoZeroTerminated	(deviceDriverProperties);	break;
-		case TEST_TYPE_VERSION:					testVersion				(deviceDriverProperties);	break;
+		case TEST_TYPE_DRIVER_ID_MATCH:			testDriverMatch			(deviceDriverProperties);								break;
+		case TEST_TYPE_NAME_IS_NOT_EMPTY:		testNameIsNotEmpty		(deviceDriverProperties);								break;
+		case TEST_TYPE_NAME_ZERO_TERMINATED:	testNameZeroTerminated	(deviceDriverProperties);								break;
+		case TEST_TYPE_INFO_ZERO_TERMINATED:	testInfoZeroTerminated	(deviceDriverProperties);								break;
+		case TEST_TYPE_VERSION:					testVersion				(deviceDriverProperties, context.getUsedApiVersion());	break;
 		default:								TCU_THROW(InternalError, "Unknown test type specified");
 	}
 
diff --git a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp
index 5425125..06845fd 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp
@@ -817,7 +817,7 @@
 
 			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
 			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
-			DE_NULL
+			(vk::pt::Win32LPCWSTR)DE_NULL
 		};
 		const vk::VkExportSemaphoreCreateInfo			exportCreateInfo=
 		{
@@ -1756,7 +1756,7 @@
 
 			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
 			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
-			DE_NULL
+			(vk::pt::Win32LPCWSTR)DE_NULL
 		};
 		const vk::VkExportFenceCreateInfo			exportCreateInfo=
 		{
@@ -2879,7 +2879,7 @@
 
 		(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
 		DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
-		DE_NULL
+		(vk::pt::Win32LPCWSTR)DE_NULL
 	};
 	const vk::VkExportMemoryAllocateInfo		exportInfo			=
 	{
diff --git a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
index 774d274..bf2afde 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
@@ -510,6 +510,1287 @@
 	return limitsOk;
 }
 
+void validateLimitsCheckSupport (Context& context)
+{
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+}
+
+typedef struct FeatureLimitTableItem_
+{
+	const void*		cond;
+	const char*		condName;
+	const void*		ptr;
+	const char*		name;
+	deUint32		uintVal;			//!< Format is UNSIGNED_INT
+	deInt32			intVal;				//!< Format is SIGNED_INT
+	deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
+	float			floatVal;			//!< Format is FLOAT
+	LimitFormat		format;
+	LimitType		type;
+} FeatureLimitTableItem;
+
+template<typename T>
+bool validateNumericLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log)
+{
+	if (limitType == LIMIT_TYPE_MIN)
+	{
+		if (reportedValue < limitToCheck)
+		{
+			log << TestLog::Message << "Limit validation failed " << limitName
+				<< " reported value is " << reportedValue
+				<< " expected MIN " << limitToCheck
+				<< TestLog::EndMessage;
+
+			return false;
+		}
+
+		log << TestLog::Message << limitName
+			<< "=" << reportedValue
+			<< " (>=" << limitToCheck << ")"
+			<< TestLog::EndMessage;
+	}
+	else if (limitType == LIMIT_TYPE_MAX)
+	{
+		if (reportedValue > limitToCheck)
+		{
+			log << TestLog::Message << "Limit validation failed " << limitName
+				<< " reported value is " << reportedValue
+				<< " expected MAX " << limitToCheck
+				<< TestLog::EndMessage;
+
+			return false;
+		}
+
+		log << TestLog::Message << limitName
+			<< "=" << reportedValue
+			<< " (<=" << limitToCheck << ")"
+			<< TestLog::EndMessage;
+	}
+
+	return true;
+}
+
+template<typename T>
+bool validateBitmaskLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log)
+{
+	if (limitType == LIMIT_TYPE_MIN)
+	{
+		if ((reportedValue & limitToCheck) != limitToCheck)
+		{
+			log << TestLog::Message << "Limit validation failed " << limitName
+				<< " reported value is " << reportedValue
+				<< " expected MIN " << limitToCheck
+				<< TestLog::EndMessage;
+
+			return false;
+		}
+
+		log << TestLog::Message << limitName
+			<< "=" << tcu::toHex(reportedValue)
+			<< " (contains " << tcu::toHex(limitToCheck) << ")"
+			<< TestLog::EndMessage;
+	}
+
+	return true;
+}
+
+bool validateLimit (FeatureLimitTableItem limit, TestLog& log)
+{
+	if (*((VkBool32*)limit.cond) == DE_FALSE)
+	{
+		log << TestLog::Message
+			<< "Limit validation skipped '" << limit.name << "' due to "
+			<< limit.condName << " == false'"
+			<< TestLog::EndMessage;
+
+		return true;
+	}
+
+	switch (limit.format)
+	{
+		case LIMIT_FORMAT_UNSIGNED_INT:
+		{
+			const deUint32	limitToCheck	= limit.uintVal;
+			const deUint32	reportedValue	= *(deUint32*)limit.ptr;
+
+			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
+		}
+
+		case LIMIT_FORMAT_FLOAT:
+		{
+			const float		limitToCheck	= limit.floatVal;
+			const float		reportedValue	= *(float*)limit.ptr;
+
+			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
+		}
+
+		case LIMIT_FORMAT_SIGNED_INT:
+		{
+			const deInt32	limitToCheck	= limit.intVal;
+			const deInt32	reportedValue	= *(deInt32*)limit.ptr;
+
+			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
+		}
+
+		case LIMIT_FORMAT_DEVICE_SIZE:
+		{
+			const deUint64	limitToCheck	= limit.deviceSizeVal;
+			const deUint64	reportedValue	= *(deUint64*)limit.ptr;
+
+			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
+		}
+
+		case LIMIT_FORMAT_BITMASK:
+		{
+			const deUint32	limitToCheck	= limit.uintVal;
+			const deUint32	reportedValue	= *(deUint32*)limit.ptr;
+
+			return validateBitmaskLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
+		}
+
+		default:
+			TCU_THROW(InternalError, "Unknown LimitFormat specified");
+	}
+}
+
+#ifdef PN
+#error PN defined
+#else
+#define PN(_X_)	&(_X_), (const char*)(#_X_)
+#endif
+
+#define LIM_MIN_UINT32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN
+#define LIM_MAX_UINT32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX
+#define LIM_NONE_UINT32		          0,          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE
+#define LIM_MIN_INT32(X)	          0, deInt32(X),               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_MIN
+#define LIM_MAX_INT32(X)	          0, deInt32(X),               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_MAX
+#define LIM_NONE_INT32		          0,          0,               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_NONE
+#define LIM_MIN_DEVSIZE(X)	          0,          0, VkDeviceSize(X),     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_MIN
+#define LIM_MAX_DEVSIZE(X)	          0,          0, VkDeviceSize(X),     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_MAX
+#define LIM_NONE_DEVSIZE	          0,          0,               0,     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_NONE
+#define LIM_MIN_FLOAT(X)	          0,          0,               0, float(X), LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_MIN
+#define LIM_MAX_FLOAT(X)	          0,          0,               0, float(X), LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_MAX
+#define LIM_NONE_FLOAT		          0,          0,               0,     0.0f, LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_NONE
+#define LIM_MIN_BITI32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_MIN
+#define LIM_MAX_BITI32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_MAX
+#define LIM_NONE_BITI32		          0,          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_NONE
+
+tcu::TestStatus validateLimits12 (Context& context)
+{
+	const VkPhysicalDevice						physicalDevice			= context.getPhysicalDevice();
+	const InstanceInterface&					vki						= context.getInstanceInterface();
+	TestLog&									log						= context.getTestContext().getLog();
+	bool										limitsOk				= true;
+
+	const VkPhysicalDeviceFeatures2&			features2				= context.getDeviceFeatures2();
+	const VkPhysicalDeviceFeatures&				features				= features2.features;
+	const VkPhysicalDeviceVulkan12Features		features12				= getPhysicalDeviceVulkan12Features(vki, physicalDevice);
+
+	const VkPhysicalDeviceProperties2&			properties2				= context.getDeviceProperties2();
+	const VkPhysicalDeviceVulkan12Properties	vulkan12Properties		= getPhysicalDeviceVulkan12Properties(vki, physicalDevice);
+	const VkPhysicalDeviceVulkan11Properties	vulkan11Properties		= getPhysicalDeviceVulkan11Properties(vki, physicalDevice);
+	const VkPhysicalDeviceLimits&				limits					= properties2.properties.limits;
+
+	const VkBool32								checkAlways				= VK_TRUE;
+	const VkBool32								checkVulkan12Limit		= VK_TRUE;
+
+	deUint32									shaderStages			= 3;
+	deUint32									maxPerStageResourcesMin	= deMin32(128,	limits.maxPerStageDescriptorUniformBuffers		+
+																						limits.maxPerStageDescriptorStorageBuffers		+
+																						limits.maxPerStageDescriptorSampledImages		+
+																						limits.maxPerStageDescriptorStorageImages		+
+																						limits.maxPerStageDescriptorInputAttachments	+
+																						limits.maxColorAttachments);
+
+	if (features.tessellationShader)
+	{
+		shaderStages += 2;
+	}
+
+	if (features.geometryShader)
+	{
+		shaderStages++;
+	}
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),								PN(limits.maxImageDimension1D),																	LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxImageDimension2D),																	LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxImageDimension3D),																	LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),								PN(limits.maxImageDimensionCube),																LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxImageArrayLayers),																	LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),								PN(limits.maxTexelBufferElements),																LIM_MIN_UINT32(65536) },
+		{ PN(checkAlways),								PN(limits.maxUniformBufferRange),																LIM_MIN_UINT32(16384) },
+		{ PN(checkAlways),								PN(limits.maxStorageBufferRange),																LIM_MIN_UINT32((1<<27)) },
+		{ PN(checkAlways),								PN(limits.maxPushConstantsSize),																LIM_MIN_UINT32(128) },
+		{ PN(checkAlways),								PN(limits.maxMemoryAllocationCount),															LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxSamplerAllocationCount),															LIM_MIN_UINT32(4000) },
+		{ PN(checkAlways),								PN(limits.bufferImageGranularity),																LIM_MIN_DEVSIZE(1) },
+		{ PN(checkAlways),								PN(limits.bufferImageGranularity),																LIM_MAX_DEVSIZE(131072) },
+		{ PN(features.sparseBinding),					PN(limits.sparseAddressSpaceSize),																LIM_MIN_DEVSIZE((1ull<<31)) },
+		{ PN(checkAlways),								PN(limits.maxBoundDescriptorSets),																LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorSamplers),														LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorUniformBuffers),													LIM_MIN_UINT32(12) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorStorageBuffers),													LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorSampledImages),													LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorStorageImages),													LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorInputAttachments),												LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxPerStageResources),																LIM_MIN_UINT32(maxPerStageResourcesMin) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetSamplers),															LIM_MIN_UINT32(shaderStages * 16) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetUniformBuffers),														LIM_MIN_UINT32(shaderStages * 12) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetUniformBuffersDynamic),												LIM_MIN_UINT32(8) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageBuffers),														LIM_MIN_UINT32(shaderStages * 4) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageBuffersDynamic),												LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetSampledImages),														LIM_MIN_UINT32(shaderStages * 16) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageImages),														LIM_MIN_UINT32(shaderStages * 4) },
+		{ PN(checkAlways),								PN(limits.maxDescriptorSetInputAttachments),													LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxVertexInputAttributes),															LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),								PN(limits.maxVertexInputBindings),																LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),								PN(limits.maxVertexInputAttributeOffset),														LIM_MIN_UINT32(2047) },
+		{ PN(checkAlways),								PN(limits.maxVertexInputBindingStride),															LIM_MIN_UINT32(2048) },
+		{ PN(checkAlways),								PN(limits.maxVertexOutputComponents),															LIM_MIN_UINT32(64) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationGenerationLevel),														LIM_MIN_UINT32(64) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationPatchSize),															LIM_MIN_UINT32(32) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerVertexInputComponents),										LIM_MIN_UINT32(64) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerVertexOutputComponents),										LIM_MIN_UINT32(64) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerPatchOutputComponents),										LIM_MIN_UINT32(120) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlTotalOutputComponents),											LIM_MIN_UINT32(2048) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationEvaluationInputComponents),											LIM_MIN_UINT32(64) },
+		{ PN(features.tessellationShader),				PN(limits.maxTessellationEvaluationOutputComponents),											LIM_MIN_UINT32(64) },
+		{ PN(features.geometryShader),					PN(limits.maxGeometryShaderInvocations),														LIM_MIN_UINT32(32) },
+		{ PN(features.geometryShader),					PN(limits.maxGeometryInputComponents),															LIM_MIN_UINT32(64) },
+		{ PN(features.geometryShader),					PN(limits.maxGeometryOutputComponents),															LIM_MIN_UINT32(64) },
+		{ PN(features.geometryShader),					PN(limits.maxGeometryOutputVertices),															LIM_MIN_UINT32(256) },
+		{ PN(features.geometryShader),					PN(limits.maxGeometryTotalOutputComponents),													LIM_MIN_UINT32(1024) },
+		{ PN(checkAlways),								PN(limits.maxFragmentInputComponents),															LIM_MIN_UINT32(64) },
+		{ PN(checkAlways),								PN(limits.maxFragmentOutputAttachments),														LIM_MIN_UINT32(4) },
+		{ PN(features.dualSrcBlend),					PN(limits.maxFragmentDualSrcAttachments),														LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),								PN(limits.maxFragmentCombinedOutputResources),													LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxComputeSharedMemorySize),															LIM_MIN_UINT32(16384) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[0]),															LIM_MIN_UINT32(65535) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[1]),															LIM_MIN_UINT32(65535) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[2]),															LIM_MIN_UINT32(65535) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupInvocations),														LIM_MIN_UINT32(128) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[0]),															LIM_MIN_UINT32(128) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[1]),															LIM_MIN_UINT32(128) },
+		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[2]),															LIM_MIN_UINT32(64) },
+		{ PN(checkAlways),								PN(limits.subPixelPrecisionBits),																LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.subTexelPrecisionBits),																LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.mipmapPrecisionBits),																	LIM_MIN_UINT32(4) },
+		{ PN(features.fullDrawIndexUint32),				PN(limits.maxDrawIndexedIndexValue),															LIM_MIN_UINT32((deUint32)~0) },
+		{ PN(features.multiDrawIndirect),				PN(limits.maxDrawIndirectCount),																LIM_MIN_UINT32(65535) },
+		{ PN(checkAlways),								PN(limits.maxSamplerLodBias),																	LIM_MIN_FLOAT(2.0f) },
+		{ PN(features.samplerAnisotropy),				PN(limits.maxSamplerAnisotropy),																LIM_MIN_FLOAT(16.0f) },
+		{ PN(features.multiViewport),					PN(limits.maxViewports),																		LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),								PN(limits.maxViewportDimensions[0]),															LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxViewportDimensions[1]),															LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.viewportBoundsRange[0]),																LIM_MAX_FLOAT(-8192.0f) },
+		{ PN(checkAlways),								PN(limits.viewportBoundsRange[1]),																LIM_MIN_FLOAT(8191.0f) },
+		{ PN(checkAlways),								PN(limits.viewportSubPixelBits),																LIM_MIN_UINT32(0) },
+		{ PN(checkAlways),								PN(limits.minMemoryMapAlignment),																LIM_MIN_UINT32(64) },
+		{ PN(checkAlways),								PN(limits.minTexelBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
+		{ PN(checkAlways),								PN(limits.minTexelBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
+		{ PN(checkAlways),								PN(limits.minUniformBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
+		{ PN(checkAlways),								PN(limits.minUniformBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
+		{ PN(checkAlways),								PN(limits.minStorageBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
+		{ PN(checkAlways),								PN(limits.minStorageBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
+		{ PN(checkAlways),								PN(limits.minTexelOffset),																		LIM_MAX_INT32(-8) },
+		{ PN(checkAlways),								PN(limits.maxTexelOffset),																		LIM_MIN_INT32(7) },
+		{ PN(features.shaderImageGatherExtended),		PN(limits.minTexelGatherOffset),																LIM_MAX_INT32(-8) },
+		{ PN(features.shaderImageGatherExtended),		PN(limits.maxTexelGatherOffset),																LIM_MIN_INT32(7) },
+		{ PN(features.sampleRateShading),				PN(limits.minInterpolationOffset),																LIM_MAX_FLOAT(-0.5f) },
+		{ PN(features.sampleRateShading),				PN(limits.maxInterpolationOffset),																LIM_MIN_FLOAT(0.5f - (1.0f/deFloatPow(2.0f, (float)limits.subPixelInterpolationOffsetBits))) },
+		{ PN(features.sampleRateShading),				PN(limits.subPixelInterpolationOffsetBits),														LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.maxFramebufferWidth),																	LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxFramebufferHeight),																LIM_MIN_UINT32(4096) },
+		{ PN(checkAlways),								PN(limits.maxFramebufferLayers),																LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),								PN(limits.framebufferColorSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkVulkan12Limit),						PN(vulkan12Properties.framebufferIntegerColorSampleCounts),										LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) },
+		{ PN(checkAlways),								PN(limits.framebufferDepthSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.framebufferStencilSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.framebufferNoAttachmentsSampleCounts),												LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.maxColorAttachments),																	LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),								PN(limits.sampledImageColorSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.sampledImageIntegerSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) },
+		{ PN(checkAlways),								PN(limits.sampledImageDepthSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.sampledImageStencilSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(features.shaderStorageImageMultisample),	PN(limits.storageImageSampleCounts),															LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),								PN(limits.maxSampleMaskWords),																	LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),								PN(limits.timestampComputeAndGraphics),															LIM_NONE_UINT32 },
+		{ PN(checkAlways),								PN(limits.timestampPeriod),																		LIM_NONE_UINT32 },
+		{ PN(features.shaderClipDistance),				PN(limits.maxClipDistances),																	LIM_MIN_UINT32(8) },
+		{ PN(features.shaderClipDistance),				PN(limits.maxCullDistances),																	LIM_MIN_UINT32(8) },
+		{ PN(features.shaderClipDistance),				PN(limits.maxCombinedClipAndCullDistances),														LIM_MIN_UINT32(8) },
+		{ PN(checkAlways),								PN(limits.discreteQueuePriorities),																LIM_MIN_UINT32(2) },
+		{ PN(features.largePoints),						PN(limits.pointSizeRange[0]),																	LIM_MIN_FLOAT(0.0f) },
+		{ PN(features.largePoints),						PN(limits.pointSizeRange[0]),																	LIM_MAX_FLOAT(1.0f) },
+		{ PN(features.largePoints),						PN(limits.pointSizeRange[1]),																	LIM_MIN_FLOAT(64.0f - limits.pointSizeGranularity) },
+		{ PN(features.wideLines),						PN(limits.lineWidthRange[0]),																	LIM_MIN_FLOAT(0.0f) },
+		{ PN(features.wideLines),						PN(limits.lineWidthRange[0]),																	LIM_MAX_FLOAT(1.0f) },
+		{ PN(features.wideLines),						PN(limits.lineWidthRange[1]),																	LIM_MIN_FLOAT(8.0f - limits.lineWidthGranularity) },
+		{ PN(features.largePoints),						PN(limits.pointSizeGranularity),																LIM_MIN_FLOAT(0.0f) },
+		{ PN(features.largePoints),						PN(limits.pointSizeGranularity),																LIM_MAX_FLOAT(1.0f) },
+		{ PN(features.wideLines),						PN(limits.lineWidthGranularity),																LIM_MIN_FLOAT(0.0f) },
+		{ PN(features.wideLines),						PN(limits.lineWidthGranularity),																LIM_MAX_FLOAT(1.0f) },
+		{ PN(checkAlways),								PN(limits.strictLines),																			LIM_NONE_UINT32 },
+		{ PN(checkAlways),								PN(limits.standardSampleLocations),																LIM_NONE_UINT32 },
+		{ PN(checkAlways),								PN(limits.optimalBufferCopyOffsetAlignment),													LIM_NONE_DEVSIZE },
+		{ PN(checkAlways),								PN(limits.optimalBufferCopyRowPitchAlignment),													LIM_NONE_DEVSIZE },
+		{ PN(checkAlways),								PN(limits.nonCoherentAtomSize),																	LIM_MIN_DEVSIZE(1) },
+		{ PN(checkAlways),								PN(limits.nonCoherentAtomSize),																	LIM_MAX_DEVSIZE(256) },
+
+		// VK_KHR_multiview
+		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMultiviewViewCount),													LIM_MIN_UINT32(6) },
+		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMultiviewInstanceIndex),												LIM_MIN_UINT32((1<<27) - 1) },
+
+		// VK_KHR_maintenance3
+		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxPerSetDescriptors),													LIM_MIN_UINT32(1024) },
+		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMemoryAllocationSize),													LIM_MIN_DEVSIZE(1<<30) },
+
+		// VK_EXT_descriptor_indexing
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxUpdateAfterBindDescriptorsInAllPools),									LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers),							LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),						LIM_MIN_UINT32(12) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),						LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages),						LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages),						LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments),					LIM_MIN_UINT32(4) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageUpdateAfterBindResources),										LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers),									LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers),							LIM_MIN_UINT32(shaderStages * 12) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),					LIM_MIN_UINT32(8) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers),							LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),					LIM_MIN_UINT32(4) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages),							LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages),							LIM_MIN_UINT32(500000) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments),							LIM_MIN_UINT32(4) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers),							LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),						LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),						LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages),						LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages),						LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments),					LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageUpdateAfterBindResources),										LIM_MIN_UINT32(limits.maxPerStageResources) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers),									LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers),							LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),					LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers),							LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),					LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages),							LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages),							LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) },
+		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments),							LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) },
+
+		// timelineSemaphore
+		{ PN(checkVulkan12Limit),						PN(vulkan12Properties.maxTimelineSemaphoreValueDifference),										LIM_MIN_DEVSIZE((1ull<<31) - 1) },
+	};
+
+	log << TestLog::Message << limits << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limits.maxFramebufferWidth > limits.maxViewportDimensions[0] ||
+		limits.maxFramebufferHeight > limits.maxViewportDimensions[1])
+	{
+		log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
+			<< "[" << limits.maxFramebufferWidth << ", " << limits.maxFramebufferHeight << "] "
+			<< "is larger than maxViewportDimension of "
+			<< "[" << limits.maxViewportDimensions[0] << ", " << limits.maxViewportDimensions[1] << "]" << TestLog::EndMessage;
+		limitsOk = false;
+	}
+
+	if (limits.viewportBoundsRange[0] > float(-2 * limits.maxViewportDimensions[0]))
+	{
+		log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits.viewportBoundsRange[0]
+			<< "is larger than -2*maxViewportDimension[0] of " << -2*limits.maxViewportDimensions[0] << TestLog::EndMessage;
+		limitsOk = false;
+	}
+
+	if (limits.viewportBoundsRange[1] < float(2 * limits.maxViewportDimensions[1] - 1))
+	{
+		log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits.viewportBoundsRange[1]
+			<< "is less than 2*maxViewportDimension[1] of " << 2*limits.maxViewportDimensions[1] << TestLog::EndMessage;
+		limitsOk = false;
+	}
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportKhrPushDescriptor (Context& context)
+{
+	context.requireDeviceFunctionality("VK_KHR_push_descriptor");
+}
+
+tcu::TestStatus validateLimitsKhrPushDescriptor (Context& context)
+{
+	const VkBool32										checkAlways					= VK_TRUE;
+	const VkPhysicalDevicePushDescriptorPropertiesKHR&	pushDescriptorPropertiesKHR	= context.getPushDescriptorProperties();
+	TestLog&											log							= context.getTestContext().getLog();
+	bool												limitsOk					= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(pushDescriptorPropertiesKHR.maxPushDescriptors),	LIM_MIN_UINT32(32) },
+	};
+
+	log << TestLog::Message << pushDescriptorPropertiesKHR << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportKhrMultiview (Context& context)
+{
+	context.requireDeviceFunctionality("VK_KHR_multiview");
+}
+
+tcu::TestStatus validateLimitsKhrMultiview (Context& context)
+{
+	const VkBool32								checkAlways			= VK_TRUE;
+	const VkPhysicalDeviceMultiviewProperties&	multiviewProperties	= context.getMultiviewProperties();
+	TestLog&									log					= context.getTestContext().getLog();
+	bool										limitsOk			= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		// VK_KHR_multiview
+		{ PN(checkAlways),	PN(multiviewProperties.maxMultiviewViewCount),		LIM_MIN_UINT32(6) },
+		{ PN(checkAlways),	PN(multiviewProperties.maxMultiviewInstanceIndex),	LIM_MIN_UINT32((1<<27) - 1) },
+	};
+
+	log << TestLog::Message << multiviewProperties << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtDiscardRectangles (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
+}
+
+tcu::TestStatus validateLimitsExtDiscardRectangles (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceDiscardRectanglePropertiesEXT&	discardRectanglePropertiesEXT	= context.getDiscardRectanglePropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(discardRectanglePropertiesEXT.maxDiscardRectangles),	LIM_MIN_UINT32(4) },
+	};
+
+	log << TestLog::Message << discardRectanglePropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtSampleLocations (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_sample_locations");
+}
+
+tcu::TestStatus validateLimitsExtSampleLocations (Context& context)
+{
+	const VkBool32										checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceSampleLocationsPropertiesEXT&	sampleLocationsPropertiesEXT	= context.getSampleLocationsPropertiesEXT();
+	TestLog&											log								= context.getTestContext().getLog();
+	bool												limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationSampleCounts),		LIM_MIN_BITI32(VK_SAMPLE_COUNT_4_BIT) },
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.width),	LIM_MIN_FLOAT(0.0f) },
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.height),	LIM_MIN_FLOAT(0.0f) },
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[0]),	LIM_MAX_FLOAT(0.0f) },
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[1]),	LIM_MIN_FLOAT(0.9375f) },
+		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationSubPixelBits),		LIM_MIN_UINT32(4) },
+	};
+
+	log << TestLog::Message << sampleLocationsPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtExternalMemoryHost (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_external_memory_host");
+}
+
+tcu::TestStatus validateLimitsExtExternalMemoryHost (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceExternalMemoryHostPropertiesEXT&	externalMemoryHostPropertiesEXT	= context.getExternalMemoryHostPropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(externalMemoryHostPropertiesEXT.minImportedHostPointerAlignment),	LIM_MAX_DEVSIZE(65536) },
+	};
+
+	log << TestLog::Message << externalMemoryHostPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtBlendOperationAdvanced (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_blend_operation_advanced");
+}
+
+tcu::TestStatus validateLimitsExtBlendOperationAdvanced (Context& context)
+{
+	const VkBool32												checkAlways							= VK_TRUE;
+	const VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT&	blendOperationAdvancedPropertiesEXT	= context.getBlendOperationAdvancedPropertiesEXT();
+	TestLog&													log									= context.getTestContext().getLog();
+	bool														limitsOk							= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(blendOperationAdvancedPropertiesEXT.advancedBlendMaxColorAttachments),	LIM_MIN_UINT32(1) },
+	};
+
+	log << TestLog::Message << blendOperationAdvancedPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportKhrMaintenance3 (Context& context)
+{
+	context.requireDeviceFunctionality("VK_KHR_maintenance3");
+}
+
+tcu::TestStatus validateLimitsKhrMaintenance3 (Context& context)
+{
+	const VkBool32									checkAlways				= VK_TRUE;
+	const VkPhysicalDeviceMaintenance3Properties&	maintenance3Properties	= context.getMaintenance3Properties();
+	TestLog&										log						= context.getTestContext().getLog();
+	bool											limitsOk				= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(maintenance3Properties.maxPerSetDescriptors),	LIM_MIN_UINT32(1024) },
+		{ PN(checkAlways),	PN(maintenance3Properties.maxMemoryAllocationSize),	LIM_MIN_DEVSIZE(1<<30) },
+	};
+
+	log << TestLog::Message << maintenance3Properties << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtConservativeRasterization (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
+}
+
+tcu::TestStatus validateLimitsExtConservativeRasterization (Context& context)
+{
+	const VkBool32													checkAlways								= VK_TRUE;
+	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT&	conservativeRasterizationPropertiesEXT	= context.getConservativeRasterizationPropertiesEXT();
+	TestLog&														log										= context.getTestContext().getLog();
+	bool															limitsOk								= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.primitiveOverestimationSize),					LIM_MIN_FLOAT(0.0f) },
+		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.maxExtraPrimitiveOverestimationSize),			LIM_MIN_FLOAT(0.0f) },
+		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.extraPrimitiveOverestimationSizeGranularity),	LIM_MIN_FLOAT(0.0f) },
+	};
+
+	log << TestLog::Message << conservativeRasterizationPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtDescriptorIndexing (Context& context)
+{
+	const std::string&							requiredDeviceExtension		= "VK_EXT_descriptor_indexing";
+	const VkPhysicalDevice						physicalDevice				= context.getPhysicalDevice();
+	const InstanceInterface&					vki							= context.getInstanceInterface();
+	const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+
+	if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension)))
+		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
+
+	// Extension string is present, then extension is really supported and should have been added into chain in DefaultDevice properties and features
+}
+
+tcu::TestStatus validateLimitsExtDescriptorIndexing (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceProperties2&						properties2						= context.getDeviceProperties2();
+	const VkPhysicalDeviceLimits&							limits							= properties2.properties.limits;
+	const VkPhysicalDeviceDescriptorIndexingPropertiesEXT&	descriptorIndexingPropertiesEXT	= context.getDescriptorIndexingProperties();
+	const VkPhysicalDeviceFeatures&							features						= context.getDeviceFeatures();
+	const deUint32											tessellationShaderCount			= (features.tessellationShader) ? 2 : 0;
+	const deUint32											geometryShaderCount				= (features.geometryShader) ? 1 : 0;
+	const deUint32											shaderStages					= 3 + tessellationShaderCount + geometryShaderCount;
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxUpdateAfterBindDescriptorsInAllPools),				LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSamplers),			LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindUniformBuffers),		LIM_MIN_UINT32(12) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageBuffers),		LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSampledImages),		LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageImages),		LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInputAttachments),	LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageUpdateAfterBindResources),					LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSamplers),				LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffers),			LIM_MIN_UINT32(shaderStages * 12) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),	LIM_MIN_UINT32(8) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffers),			LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),	LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSampledImages),			LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageImages),			LIM_MIN_UINT32(500000) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindInputAttachments),		LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSamplers),			LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindUniformBuffers),		LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageBuffers),		LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSampledImages),		LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageImages),		LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInputAttachments),	LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxPerStageUpdateAfterBindResources),					LIM_MIN_UINT32(limits.maxPerStageResources) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSamplers),				LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffers),			LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),	LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffers),			LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),	LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSampledImages),			LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageImages),			LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) },
+		{ PN(checkAlways),	PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindInputAttachments),		LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) },
+	};
+
+	log << TestLog::Message << descriptorIndexingPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtInlineUniformBlock (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_inline_uniform_block");
+}
+
+tcu::TestStatus validateLimitsExtInlineUniformBlock (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceInlineUniformBlockPropertiesEXT&	inlineUniformBlockPropertiesEXT	= context.getInlineUniformBlockPropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxInlineUniformBlockSize),									LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorInlineUniformBlocks),					LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks),	LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetInlineUniformBlocks),						LIM_MIN_UINT32(4) },
+		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetUpdateAfterBindInlineUniformBlocks),			LIM_MIN_UINT32(4) },
+	};
+
+	log << TestLog::Message << inlineUniformBlockPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtVertexAttributeDivisor (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_vertex_attribute_divisor");
+}
+
+tcu::TestStatus validateLimitsExtVertexAttributeDivisor (Context& context)
+{
+	const VkBool32												checkAlways							= VK_TRUE;
+	const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT&	vertexAttributeDivisorPropertiesEXT	= context.getVertexAttributeDivisorPropertiesEXT();
+	TestLog&													log									= context.getTestContext().getLog();
+	bool														limitsOk							= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(vertexAttributeDivisorPropertiesEXT.maxVertexAttribDivisor),	LIM_MIN_UINT32((1<<16) - 1) },
+	};
+
+	log << TestLog::Message << vertexAttributeDivisorPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportNvMeshShader (Context& context)
+{
+	const std::string&							requiredDeviceExtension		= "VK_NV_mesh_shader";
+	const VkPhysicalDevice						physicalDevice				= context.getPhysicalDevice();
+	const InstanceInterface&					vki							= context.getInstanceInterface();
+	const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+
+	if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension)))
+		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
+}
+
+tcu::TestStatus validateLimitsNvMeshShader (Context& context)
+{
+	const VkBool32							checkAlways				= VK_TRUE;
+	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
+	const InstanceInterface&				vki						= context.getInstanceInterface();
+	TestLog&								log						= context.getTestContext().getLog();
+	bool									limitsOk				= true;
+	VkPhysicalDeviceMeshShaderPropertiesNV	meshShaderPropertiesNV	= initVulkanStructure();
+	VkPhysicalDeviceProperties2				properties2				= initVulkanStructure(&meshShaderPropertiesNV);
+
+	vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxDrawMeshTasksCount),		LIM_MIN_UINT32(deUint32((1ull<<16) - 1)) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupInvocations),	LIM_MIN_UINT32(32) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[0]),		LIM_MIN_UINT32(32) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[1]),		LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[2]),		LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskTotalMemorySize),		LIM_MIN_UINT32(16384) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskOutputCount),			LIM_MIN_UINT32((1<<16) - 1) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupInvocations),	LIM_MIN_UINT32(32) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[0]),		LIM_MIN_UINT32(32) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[1]),		LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[2]),		LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshTotalMemorySize),		LIM_MIN_UINT32(16384) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshOutputVertices),		LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshOutputPrimitives),		LIM_MIN_UINT32(256) },
+		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshMultiviewViewCount),	LIM_MIN_UINT32(1) },
+	};
+
+	log << TestLog::Message << meshShaderPropertiesNV << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtTransformFeedback (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_transform_feedback");
+}
+
+tcu::TestStatus validateLimitsExtTransformFeedback (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceTransformFeedbackPropertiesEXT&	transformFeedbackPropertiesEXT	= context.getTransformFeedbackPropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreams),				LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBuffers),				LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferSize),			LIM_MIN_DEVSIZE(1ull<<27) },
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreamDataSize),		LIM_MIN_UINT32(512) },
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataSize),		LIM_MIN_UINT32(512) },
+		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataStride),	LIM_MIN_UINT32(512) },
+	};
+
+	log << TestLog::Message << transformFeedbackPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtFragmentDensityMap (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
+}
+
+tcu::TestStatus validateLimitsExtFragmentDensityMap (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceFragmentDensityMapPropertiesEXT&	fragmentDensityMapPropertiesEXT	= context.getFragmentDensityMapPropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.width),							LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.height),							LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.width),							LIM_MIN_UINT32(1) },
+		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.height),							LIM_MIN_UINT32(1) },
+	};
+
+	log << TestLog::Message << fragmentDensityMapPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportNvRayTracing (Context& context)
+{
+	const std::string&							requiredDeviceExtension		= "VK_NV_ray_tracing";
+	const VkPhysicalDevice						physicalDevice				= context.getPhysicalDevice();
+	const InstanceInterface&					vki							= context.getInstanceInterface();
+	const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+
+	if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension)))
+		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
+}
+
+tcu::TestStatus validateLimitsNvRayTracing (Context& context)
+{
+	const VkBool32							checkAlways				= VK_TRUE;
+	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
+	const InstanceInterface&				vki						= context.getInstanceInterface();
+	TestLog&								log						= context.getTestContext().getLog();
+	bool									limitsOk				= true;
+	VkPhysicalDeviceRayTracingPropertiesNV	rayTracingPropertiesNV	= initVulkanStructure();
+	VkPhysicalDeviceProperties2				properties2				= initVulkanStructure(&rayTracingPropertiesNV);
+
+	vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.shaderGroupHandleSize),					LIM_MIN_UINT32(16) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxRecursionDepth),						LIM_MIN_UINT32(31) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.shaderGroupBaseAlignment),				LIM_MIN_UINT32(64) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxGeometryCount),						LIM_MIN_UINT32((1<<24) - 1) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxInstanceCount),						LIM_MIN_UINT32((1<<24) - 1) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxTriangleCount),						LIM_MIN_UINT32((1<<29) - 1) },
+		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxDescriptorSetAccelerationStructures),	LIM_MIN_UINT32(16) },
+	};
+
+	log << TestLog::Message << rayTracingPropertiesNV << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportKhrTimelineSemaphore (Context& context)
+{
+	context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+}
+
+tcu::TestStatus validateLimitsKhrTimelineSemaphore (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceTimelineSemaphorePropertiesKHR&	timelineSemaphorePropertiesKHR	= context.getTimelineSemaphoreProperties();
+	bool													limitsOk						= true;
+	TestLog&												log								= context.getTestContext().getLog();
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(timelineSemaphorePropertiesKHR.maxTimelineSemaphoreValueDifference),	LIM_MIN_DEVSIZE((1ull<<31) - 1) },
+	};
+
+	log << TestLog::Message << timelineSemaphorePropertiesKHR << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportExtLineRasterization (Context& context)
+{
+	context.requireDeviceFunctionality("VK_EXT_line_rasterization");
+}
+
+tcu::TestStatus validateLimitsExtLineRasterization (Context& context)
+{
+	const VkBool32											checkAlways						= VK_TRUE;
+	const VkPhysicalDeviceLineRasterizationPropertiesEXT&	lineRasterizationPropertiesEXT	= context.getLineRasterizationPropertiesEXT();
+	TestLog&												log								= context.getTestContext().getLog();
+	bool													limitsOk						= true;
+
+	FeatureLimitTableItem featureLimitTable[] =
+	{
+		{ PN(checkAlways),	PN(lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits),	LIM_MIN_UINT32(4) },
+	};
+
+	log << TestLog::Message << lineRasterizationPropertiesEXT << TestLog::EndMessage;
+
+	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
+		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
+
+	if (limitsOk)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+void checkSupportFeatureBitInfluence (Context& context)
+{
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+}
+
+void createDevice (Context& context, void* pNext, const char* const* ppEnabledExtensionNames, deUint32 enabledExtensionCount)
+{
+	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
+	const Unique<VkInstance>				instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
+	const InstanceDriver					instanceDriver			(platformInterface, instance.get());
+	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
+	const deUint32							queueFamilyIndex		= 0;
+	const deUint32							queueCount				= 1;
+	const deUint32							queueIndex				= 0;
+	const float								queuePriority			= 1.0f;
+	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
+	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
+	{
+		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//  VkStructureType				sType;
+		DE_NULL,									//  const void*					pNext;
+		(VkDeviceQueueCreateFlags)0u,				//  VkDeviceQueueCreateFlags	flags;
+		queueFamilyIndex,							//  deUint32					queueFamilyIndex;
+		queueCount,									//  deUint32					queueCount;
+		&queuePriority,								//  const float*				pQueuePriorities;
+	};
+	const VkDeviceCreateInfo				deviceCreateInfo		=
+	{
+		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		//  VkStructureType					sType;
+		pNext,										//  const void*						pNext;
+		(VkDeviceCreateFlags)0u,					//  VkDeviceCreateFlags				flags;
+		1,											//  deUint32						queueCreateInfoCount;
+		&deviceQueueCreateInfo,						//  const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
+		0,											//  deUint32						enabledLayerCount;
+		DE_NULL,									//  const char* const*				ppEnabledLayerNames;
+		enabledExtensionCount,						//  deUint32						enabledExtensionCount;
+		ppEnabledExtensionNames,					//  const char* const*				ppEnabledExtensionNames;
+		DE_NULL,									//  const VkPhysicalDeviceFeatures*	pEnabledFeatures;
+	};
+	const Unique<VkDevice>					device					(createDevice(platformInterface, *instance, instanceDriver, physicalDevice, &deviceCreateInfo));
+	const DeviceDriver						deviceDriver			(platformInterface, instance.get(), device.get());
+	const VkQueue							queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
+
+	VK_CHECK(deviceDriver.queueWaitIdle(queue));
+}
+
+void cleanVulkanStruct (void* structPtr, size_t structSize)
+{
+	struct StructureBase
+	{
+		VkStructureType		sType;
+		void*				pNext;
+	};
+
+	VkStructureType		sType = ((StructureBase*)structPtr)->sType;
+
+	deMemset(structPtr, 0, structSize);
+
+	((StructureBase*)structPtr)->sType = sType;
+}
+
+tcu::TestStatus featureBitInfluenceOnDeviceCreate (Context& context)
+{
+#define FEATURE_TABLE_ITEM(CORE, EXT, FIELD, STR) { &(CORE), sizeof(CORE), &(CORE.FIELD), #CORE "." #FIELD, &(EXT), sizeof(EXT), &(EXT.FIELD), #EXT "." #FIELD, STR }
+#define DEPENDENCY_DUAL_ITEM(CORE, EXT, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) }, { &(EXT.FIELD), &(EXT.PARENT) }
+#define DEPENDENCY_SINGLE_ITEM(CORE, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) }
+
+	const VkPhysicalDevice								physicalDevice						= context.getPhysicalDevice();
+	const InstanceInterface&							vki									= context.getInstanceInterface();
+	TestLog&											log									= context.getTestContext().getLog();
+	const std::vector<VkExtensionProperties>			deviceExtensionProperties			= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+
+	VkPhysicalDeviceFeatures2							features2							= initVulkanStructure();
+	VkPhysicalDeviceVulkan11Features					vulkan11Features					= initVulkanStructure();
+	VkPhysicalDeviceVulkan12Features					vulkan12Features					= initVulkanStructure();
+	VkPhysicalDevice16BitStorageFeaturesKHR				sixteenBitStorageFeatures			= initVulkanStructure();
+	VkPhysicalDeviceMultiviewFeatures					multiviewFeatures					= initVulkanStructure();
+	VkPhysicalDeviceVariablePointersFeatures			variablePointersFeatures			= initVulkanStructure();
+	VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures				= initVulkanStructure();
+	VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures		= initVulkanStructure();
+	VkPhysicalDeviceShaderDrawParametersFeatures		shaderDrawParametersFeatures		= initVulkanStructure();
+	VkPhysicalDevice8BitStorageFeatures					eightBitStorageFeatures				= initVulkanStructure();
+	VkPhysicalDeviceShaderAtomicInt64Features			shaderAtomicInt64Features			= initVulkanStructure();
+	VkPhysicalDeviceShaderFloat16Int8Features			shaderFloat16Int8Features			= initVulkanStructure();
+	VkPhysicalDeviceDescriptorIndexingFeatures			descriptorIndexingFeatures			= initVulkanStructure();
+	VkPhysicalDeviceScalarBlockLayoutFeatures			scalarBlockLayoutFeatures			= initVulkanStructure();
+	VkPhysicalDeviceImagelessFramebufferFeatures		imagelessFramebufferFeatures		= initVulkanStructure();
+	VkPhysicalDeviceUniformBufferStandardLayoutFeatures	uniformBufferStandardLayoutFeatures	= initVulkanStructure();
+	VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures	shaderSubgroupExtendedTypesFeatures	= initVulkanStructure();
+	VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures	separateDepthStencilLayoutsFeatures	= initVulkanStructure();
+	VkPhysicalDeviceHostQueryResetFeatures				hostQueryResetFeatures				= initVulkanStructure();
+	VkPhysicalDeviceTimelineSemaphoreFeatures			timelineSemaphoreFeatures			= initVulkanStructure();
+	VkPhysicalDeviceBufferDeviceAddressFeatures			bufferDeviceAddressFeatures			= initVulkanStructure();
+	VkPhysicalDeviceVulkanMemoryModelFeatures			vulkanMemoryModelFeatures			= initVulkanStructure();
+
+	struct DummyExtensionFeatures
+	{
+		VkStructureType		sType;
+		void*				pNext;
+		VkBool32			descriptorIndexing;
+		VkBool32			samplerFilterMinmax;
+	} dummyExtensionFeatures;
+
+	struct FeatureTable
+	{
+		void*		coreStructPtr;
+		size_t		coreStructSize;
+		VkBool32*	coreFieldPtr;
+		const char*	coreFieldName;
+		void*		extStructPtr;
+		size_t		extStructSize;
+		VkBool32*	extFieldPtr;
+		const char*	extFieldName;
+		const char*	extString;
+	}
+	featureTable[] =
+	{
+		FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storageBuffer16BitAccess,							"VK_KHR_16bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				uniformAndStorageBuffer16BitAccess,					"VK_KHR_16bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storagePushConstant16,								"VK_KHR_16bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storageInputOutput16,								"VK_KHR_16bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiview,											"VK_KHR_multiview"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiviewGeometryShader,							"VK_KHR_multiview"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiviewTessellationShader,						"VK_KHR_multiview"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	variablePointersFeatures,				variablePointersStorageBuffer,						"VK_KHR_variable_pointers"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	variablePointersFeatures,				variablePointers,									"VK_KHR_variable_pointers"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	protectedMemoryFeatures,				protectedMemory,									DE_NULL),
+		FEATURE_TABLE_ITEM(vulkan11Features,	samplerYcbcrConversionFeatures,			samplerYcbcrConversion,								"VK_KHR_sampler_ycbcr_conversion"),
+		FEATURE_TABLE_ITEM(vulkan11Features,	shaderDrawParametersFeatures,			shaderDrawParameters,								DE_NULL),
+		FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				storageBuffer8BitAccess,							"VK_KHR_8bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				uniformAndStorageBuffer8BitAccess,					"VK_KHR_8bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				storagePushConstant8,								"VK_KHR_8bit_storage"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	shaderAtomicInt64Features,				shaderBufferInt64Atomics,							"VK_KHR_shader_atomic_int64"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	shaderAtomicInt64Features,				shaderSharedInt64Atomics,							"VK_KHR_shader_atomic_int64"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	shaderFloat16Int8Features,				shaderFloat16,										"VK_KHR_shader_float16_int8"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	shaderFloat16Int8Features,				shaderInt8,											"VK_KHR_shader_float16_int8"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	dummyExtensionFeatures,					descriptorIndexing,									DE_NULL),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderInputAttachmentArrayDynamicIndexing,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformTexelBufferArrayDynamicIndexing,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageTexelBufferArrayDynamicIndexing,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformBufferArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderSampledImageArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageBufferArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageImageArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderInputAttachmentArrayNonUniformIndexing,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformTexelBufferArrayNonUniformIndexing,	"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageTexelBufferArrayNonUniformIndexing,	"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUniformBufferUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingSampledImageUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageImageUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageBufferUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUniformTexelBufferUpdateAfterBind,	"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageTexelBufferUpdateAfterBind,	"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUpdateUnusedWhilePending,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingPartiallyBound,					"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingVariableDescriptorCount,			"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				runtimeDescriptorArray,								"VK_EXT_descriptor_indexing"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	dummyExtensionFeatures,					samplerFilterMinmax,								"VK_EXT_sampler_filter_minmax"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	scalarBlockLayoutFeatures,				scalarBlockLayout,									"VK_EXT_scalar_block_layout"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	imagelessFramebufferFeatures,			imagelessFramebuffer,								"VK_KHR_imageless_framebuffer"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	uniformBufferStandardLayoutFeatures,	uniformBufferStandardLayout,						"VK_KHR_uniform_buffer_standard_layout"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	shaderSubgroupExtendedTypesFeatures,	shaderSubgroupExtendedTypes,						"VK_KHR_shader_subgroup_extended_types"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	separateDepthStencilLayoutsFeatures,	separateDepthStencilLayouts,						"VK_KHR_separate_depth_stencil_layouts"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	hostQueryResetFeatures,					hostQueryReset,										"VK_EXT_host_query_reset"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	timelineSemaphoreFeatures,				timelineSemaphore,									"VK_KHR_timeline_semaphore"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddress,								"VK_EXT_buffer_device_address"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddressCaptureReplay,					"VK_EXT_buffer_device_address"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddressMultiDevice,						"VK_EXT_buffer_device_address"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModel,									"VK_KHR_vulkan_memory_model"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModelDeviceScope,						"VK_KHR_vulkan_memory_model"),
+		FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModelAvailabilityVisibilityChains,		"VK_KHR_vulkan_memory_model"),
+	};
+	struct FeatureDependencyTable
+	{
+		VkBool32*	featurePtr;
+		VkBool32*	dependOnPtr;
+	}
+	featureDependencyTable[] =
+	{
+		DEPENDENCY_DUAL_ITEM	(vulkan11Features,	multiviewFeatures,				multiviewGeometryShader,							multiview),
+		DEPENDENCY_DUAL_ITEM	(vulkan11Features,	multiviewFeatures,				multiviewTessellationShader,						multiview),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderInputAttachmentArrayDynamicIndexing,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderUniformTexelBufferArrayDynamicIndexing,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderStorageTexelBufferArrayDynamicIndexing,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderUniformBufferArrayNonUniformIndexing,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderSampledImageArrayNonUniformIndexing,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderStorageBufferArrayNonUniformIndexing,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderStorageImageArrayNonUniformIndexing,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderInputAttachmentArrayNonUniformIndexing,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderUniformTexelBufferArrayNonUniformIndexing,	descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									shaderStorageTexelBufferArrayNonUniformIndexing,	descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingUniformBufferUpdateAfterBind,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingSampledImageUpdateAfterBind,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingStorageImageUpdateAfterBind,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingStorageBufferUpdateAfterBind,		descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingUniformTexelBufferUpdateAfterBind,	descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingStorageTexelBufferUpdateAfterBind,	descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingUpdateUnusedWhilePending,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingPartiallyBound,					descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									descriptorBindingVariableDescriptorCount,			descriptorIndexing),
+		DEPENDENCY_SINGLE_ITEM	(vulkan12Features,									runtimeDescriptorArray,								descriptorIndexing),
+		DEPENDENCY_DUAL_ITEM	(vulkan12Features,	bufferDeviceAddressFeatures,	bufferDeviceAddressCaptureReplay,					bufferDeviceAddress),
+		DEPENDENCY_DUAL_ITEM	(vulkan12Features,	bufferDeviceAddressFeatures,	bufferDeviceAddressMultiDevice,						bufferDeviceAddress),
+		DEPENDENCY_DUAL_ITEM	(vulkan12Features,	vulkanMemoryModelFeatures,		vulkanMemoryModelDeviceScope,						vulkanMemoryModel),
+		DEPENDENCY_DUAL_ITEM	(vulkan12Features,	vulkanMemoryModelFeatures,		vulkanMemoryModelAvailabilityVisibilityChains,		vulkanMemoryModel),
+	};
+
+	deMemset(&dummyExtensionFeatures, 0, sizeof(dummyExtensionFeatures));
+
+	for (size_t featureTableNdx = 0; featureTableNdx < DE_LENGTH_OF_ARRAY(featureTable); ++featureTableNdx)
+	{
+		FeatureTable&	testedFeature	= featureTable[featureTableNdx];
+		VkBool32		coreFeatureState= DE_FALSE;
+		VkBool32		extFeatureState	= DE_FALSE;
+
+		// Core test
+		{
+			void*		structPtr	= testedFeature.coreStructPtr;
+			size_t		structSize	= testedFeature.coreStructSize;
+			VkBool32*	featurePtr	= testedFeature.coreFieldPtr;
+
+			if (structPtr != &dummyExtensionFeatures)
+				features2.pNext	= structPtr;
+
+			vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
+
+			coreFeatureState = featurePtr[0];
+
+			log << TestLog::Message
+				<< "Feature status "
+				<< testedFeature.coreFieldName << "=" << coreFeatureState
+				<< TestLog::EndMessage;
+
+			if (coreFeatureState)
+			{
+				cleanVulkanStruct(structPtr, structSize);
+
+				featurePtr[0] = DE_TRUE;
+
+				for (size_t featureDependencyTableNdx = 0; featureDependencyTableNdx < DE_LENGTH_OF_ARRAY(featureDependencyTable); ++featureDependencyTableNdx)
+					if (featureDependencyTable[featureDependencyTableNdx].featurePtr == featurePtr)
+						featureDependencyTable[featureDependencyTableNdx].dependOnPtr[0] = DE_TRUE;
+
+				createDevice(context, &features2, DE_NULL, 0u);
+			}
+		}
+
+		// ext test
+		{
+			void*		structPtr		= testedFeature.extStructPtr;
+			size_t		structSize		= testedFeature.extStructSize;
+			VkBool32*	featurePtr		= testedFeature.extFieldPtr;
+			const char*	extStringPtr	= testedFeature.extString;
+
+			if (structPtr != &dummyExtensionFeatures)
+				features2.pNext	= structPtr;
+
+			if (extStringPtr == DE_NULL || isExtensionSupported(deviceExtensionProperties, RequiredExtension(extStringPtr)))
+			{
+				vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
+
+				extFeatureState = *featurePtr;
+
+				log << TestLog::Message
+					<< "Feature status "
+					<< testedFeature.extFieldName << "=" << extFeatureState
+					<< TestLog::EndMessage;
+
+				if (extFeatureState)
+				{
+					cleanVulkanStruct(structPtr, structSize);
+
+					featurePtr[0] = DE_TRUE;
+
+					for (size_t featureDependencyTableNdx = 0; featureDependencyTableNdx < DE_LENGTH_OF_ARRAY(featureDependencyTable); ++featureDependencyTableNdx)
+						if (featureDependencyTable[featureDependencyTableNdx].featurePtr == featurePtr)
+							featureDependencyTable[featureDependencyTableNdx].dependOnPtr[0] = DE_TRUE;
+
+					createDevice(context, &features2, &extStringPtr, (extStringPtr == DE_NULL) ? 0u : 1u );
+				}
+			}
+		}
+	}
+
+	return tcu::TestStatus::pass("pass");
+}
+
 template<typename T>
 class CheckIncompleteResult
 {
@@ -1235,7 +2516,7 @@
 
 	{
 		const ApiVersion deviceVersion = unpackVersion(props->apiVersion);
-		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_1);
+		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_2);
 
 		if (deviceVersion.majorNum != deqpVersion.majorNum)
 		{
@@ -1680,7 +2961,7 @@
 		{
 			if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterMinMaxFormats), DE_ARRAY_END(s_requiredSampledImageFilterMinMaxFormats), format))
 			{
-				VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT	physicalDeviceSamplerMinMaxProperties =
+				VkPhysicalDeviceSamplerFilterMinmaxProperties		physicalDeviceSamplerMinMaxProperties =
 				{
 					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT,
 					DE_NULL,
@@ -2662,7 +3943,7 @@
 {
 	for (size_t ndx = 0; ndx < properties.size(); ++ndx)
 	{
-		if (strcmp(properties[ndx].extensionName, extension) == 0)
+		if (strncmp(properties[ndx].extensionName, extension, VK_MAX_EXTENSION_NAME_SIZE) == 0)
 			return true;
 	}
 	return false;
@@ -2695,99 +3976,140 @@
 
 	log << TestLog::Message << extFeatures << TestLog::EndMessage;
 
-	vector<VkExtensionProperties>	properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
-	const bool khr_8bit_storage				= checkExtension(properties,"VK_KHR_8bit_storage");
-	const bool ext_conditional_rendering	= checkExtension(properties,"VK_EXT_conditional_rendering");
-	const bool scalar_block_layout			= checkExtension(properties,"VK_EXT_scalar_block_layout");
-	const bool khr_performance_counter		= checkExtension(properties,"VK_KHR_performance_query");
-	bool khr_16bit_storage					= true;
-	bool khr_multiview						= true;
-	bool deviceProtectedMemory				= true;
-	bool sampler_ycbcr_conversion			= true;
-	bool variable_pointers					= true;
-	if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1)
-	{
-		khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
-		khr_multiview = checkExtension(properties,"VK_KHR_multiview");
-		deviceProtectedMemory = false;
-		sampler_ycbcr_conversion = checkExtension(properties,"VK_KHR_sampler_ycbcr_conversion");
-		variable_pointers = checkExtension(properties,"VK_KHR_variable_pointers");
-	}
+	vector<VkExtensionProperties> properties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+	const bool ext_conditional_rendering		= checkExtension(properties, "VK_EXT_conditional_rendering");
+	const bool ext_scalar_block_layout			= checkExtension(properties, "VK_EXT_scalar_block_layout");
+	const bool khr_performance_counter			= checkExtension(properties, "VK_KHR_performance_query");
+	const bool khr_16bit_storage				= checkExtension(properties, "VK_KHR_16bit_storage")			||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_multiview					= checkExtension(properties, "VK_KHR_multiview")				||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_device_protected_memory		=																	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_sampler_ycbcr_conversion		= checkExtension(properties, "VK_KHR_sampler_ycbcr_conversion")	||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_variable_pointers			= checkExtension(properties, "VK_KHR_variable_pointers")		||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_8bit_storage					= checkExtension(properties, "VK_KHR_8bit_storage")				||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_shader_atomic_int64			= checkExtension(properties, "VK_KHR_shader_atomic_int64")		||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_shader_float16_int8			= checkExtension(properties, "VK_KHR_shader_float16_int8")		||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_buffer_device_address		= checkExtension(properties, "VK_KHR_buffer_device_address")	||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool ext_descriptor_indexing			= checkExtension(properties, "VK_EXT_descriptor_indexing")		||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool ext_buffer_device_address		= checkExtension(properties, "VK_EXT_buffer_device_address");
 
 	const int count = 2u;
-	VkPhysicalDevice8BitStorageFeaturesKHR				device8BitStorageFeatures[count];
-	VkPhysicalDeviceConditionalRenderingFeaturesEXT		deviceConditionalRenderingFeatures[count];
-	VkPhysicalDevice16BitStorageFeatures				device16BitStorageFeatures[count];
-	VkPhysicalDeviceMultiviewFeatures					deviceMultiviewFeatures[count];
-	VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures[count];
-	VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures[count];
-	VkPhysicalDeviceVariablePointersFeatures			variablePointerFeatures[count];
-	VkPhysicalDeviceScalarBlockLayoutFeaturesEXT		scalarBlockLayoutFeatures[count];
-	VkPhysicalDeviceTimelineSemaphoreFeaturesKHR		timelineSemaphoreFeatures[count];
-	VkPhysicalDevicePerformanceQueryFeaturesKHR			performanceQueryFeatures[count];
+	VkPhysicalDeviceConditionalRenderingFeaturesEXT	deviceConditionalRenderingFeatures[count];
+	VkPhysicalDeviceScalarBlockLayoutFeatures		scalarBlockLayoutFeatures[count];
+	VkPhysicalDevicePerformanceQueryFeaturesKHR		performanceQueryFeatures[count];
+	VkPhysicalDevice16BitStorageFeatures			device16BitStorageFeatures[count];
+	VkPhysicalDeviceMultiviewFeatures				deviceMultiviewFeatures[count];
+	VkPhysicalDeviceProtectedMemoryFeatures			protectedMemoryFeatures[count];
+	VkPhysicalDeviceSamplerYcbcrConversionFeatures	samplerYcbcrConversionFeatures[count];
+	VkPhysicalDeviceVariablePointersFeatures		variablePointerFeatures[count];
+	VkPhysicalDevice8BitStorageFeatures				device8BitStorageFeatures[count];
+	VkPhysicalDeviceShaderAtomicInt64Features		deviceShaderAtomicInt64Features[count];
+	VkPhysicalDeviceShaderFloat16Int8Features		deviceShaderFloat16Int8Features[count];
+	VkPhysicalDeviceBufferDeviceAddressFeaturesEXT	deviceBufferDeviceAddressFeaturesEXT[count];
+	VkPhysicalDeviceBufferDeviceAddressFeatures		deviceBufferDeviceAddressFeatures[count];
+	VkPhysicalDeviceDescriptorIndexingFeatures		deviceDescriptorIndexingFeatures[count];
+	VkPhysicalDeviceTimelineSemaphoreFeatures		timelineSemaphoreFeatures[count];
 
 	for (int ndx = 0; ndx < count; ++ndx)
 	{
-		deMemset(&device8BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
-		deMemset(&deviceConditionalRenderingFeatures[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT));
-		deMemset(&device16BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
-		deMemset(&deviceMultiviewFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
-		deMemset(&protectedMemoryFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
-		deMemset(&samplerYcbcrConversionFeatures[ndx],		0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
-		deMemset(&variablePointerFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointersFeatures));
-		deMemset(&scalarBlockLayoutFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT));
-		deMemset(&performanceQueryFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePerformanceQueryFeaturesKHR));
+		deMemset(&deviceConditionalRenderingFeatures[ndx],	0xFF * ndx, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT));
+		deMemset(&scalarBlockLayoutFeatures[ndx],			0xFF * ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeatures));
+		deMemset(&performanceQueryFeatures[ndx],			0xFF * ndx, sizeof(VkPhysicalDevicePerformanceQueryFeaturesKHR));
+		deMemset(&device16BitStorageFeatures[ndx],			0xFF * ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
+		deMemset(&deviceMultiviewFeatures[ndx],				0xFF * ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
+		deMemset(&protectedMemoryFeatures[ndx],				0xFF * ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
+		deMemset(&samplerYcbcrConversionFeatures[ndx],		0xFF * ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
+		deMemset(&variablePointerFeatures[ndx],				0xFF * ndx, sizeof(VkPhysicalDeviceVariablePointersFeatures));
+		deMemset(&device8BitStorageFeatures[ndx],			0xFF * ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
+		deMemset(&deviceShaderAtomicInt64Features[ndx],		0xFF * ndx, sizeof(VkPhysicalDeviceShaderAtomicInt64Features));
+		deMemset(&deviceShaderFloat16Int8Features[ndx],		0xFF * ndx, sizeof(VkPhysicalDeviceShaderFloat16Int8Features));
+		deMemset(&deviceBufferDeviceAddressFeatures[ndx],	0xFF * ndx, sizeof(VkPhysicalDeviceBufferDeviceAddressFeatures));
+		deMemset(&deviceBufferDeviceAddressFeaturesEXT[ndx],0xFF * ndx, sizeof(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT));
+		deMemset(&deviceDescriptorIndexingFeatures[ndx],	0xFF * ndx, sizeof(VkPhysicalDeviceDescriptorIndexingFeatures));
 
-		device8BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
-		device8BitStorageFeatures[ndx].pNext = &deviceConditionalRenderingFeatures[ndx];
+		deviceConditionalRenderingFeatures[ndx].sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
+		deviceConditionalRenderingFeatures[ndx].pNext	= &scalarBlockLayoutFeatures[ndx];
 
-		deviceConditionalRenderingFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
-		deviceConditionalRenderingFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];
+		scalarBlockLayoutFeatures[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
+		scalarBlockLayoutFeatures[ndx].pNext			= &performanceQueryFeatures[ndx];
 
-		device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
-		device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];
+		performanceQueryFeatures[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR;
+		performanceQueryFeatures[ndx].pNext				= &device16BitStorageFeatures[ndx];
 
-		deviceMultiviewFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
-		deviceMultiviewFeatures[ndx].pNext = &protectedMemoryFeatures[ndx];
+		device16BitStorageFeatures[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+		device16BitStorageFeatures[ndx].pNext			= &deviceMultiviewFeatures[ndx];
 
-		protectedMemoryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
-		protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];
+		deviceMultiviewFeatures[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
+		deviceMultiviewFeatures[ndx].pNext				= &protectedMemoryFeatures[ndx];
 
-		samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
-		samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx];
+		protectedMemoryFeatures[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
+		protectedMemoryFeatures[ndx].pNext				= &samplerYcbcrConversionFeatures[ndx];
 
-		variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
-		variablePointerFeatures[ndx].pNext = &scalarBlockLayoutFeatures[ndx];
+		samplerYcbcrConversionFeatures[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
+		samplerYcbcrConversionFeatures[ndx].pNext		= &variablePointerFeatures[ndx];
 
-		scalarBlockLayoutFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
-		scalarBlockLayoutFeatures[ndx].pNext = &timelineSemaphoreFeatures[ndx];
+		variablePointerFeatures[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
+		variablePointerFeatures[ndx].pNext				= &device8BitStorageFeatures[ndx];
 
-		timelineSemaphoreFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
-		timelineSemaphoreFeatures[ndx].pNext = &performanceQueryFeatures[ndx];
+		device8BitStorageFeatures[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
+		device8BitStorageFeatures[ndx].pNext			= &deviceShaderAtomicInt64Features[ndx];
 
-		performanceQueryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR;
-		performanceQueryFeatures[ndx].pNext = DE_NULL;
+		deviceShaderAtomicInt64Features[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;
+		deviceShaderAtomicInt64Features[ndx].pNext		= &deviceShaderFloat16Int8Features[ndx];
+
+		deviceShaderFloat16Int8Features[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
+		deviceShaderFloat16Int8Features[ndx].pNext		= &deviceBufferDeviceAddressFeatures[ndx];
+
+		deviceBufferDeviceAddressFeatures[ndx].sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
+		deviceBufferDeviceAddressFeatures[ndx].pNext	= &deviceBufferDeviceAddressFeaturesEXT[ndx];
+
+		deviceBufferDeviceAddressFeaturesEXT[ndx].sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT;
+		deviceBufferDeviceAddressFeaturesEXT[ndx].pNext	= &deviceDescriptorIndexingFeatures[ndx];
+
+		deviceDescriptorIndexingFeatures[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
+		deviceDescriptorIndexingFeatures[ndx].pNext		= &timelineSemaphoreFeatures[ndx];
+
+		timelineSemaphoreFeatures[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;
+		timelineSemaphoreFeatures[ndx].pNext			= DE_NULL;
 
 		deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
 		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
-		extFeatures.pNext = &device8BitStorageFeatures[ndx];
+		extFeatures.pNext = &deviceConditionalRenderingFeatures[ndx];
 
 		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
 	}
 
-	if ( khr_8bit_storage &&
-		(device8BitStorageFeatures[0].storageBuffer8BitAccess				!= device8BitStorageFeatures[1].storageBuffer8BitAccess ||
-		device8BitStorageFeatures[0].uniformAndStorageBuffer8BitAccess		!= device8BitStorageFeatures[1].uniformAndStorageBuffer8BitAccess ||
-		device8BitStorageFeatures[0].storagePushConstant8					!= device8BitStorageFeatures[1].storagePushConstant8 )
-		)
-	{
-		TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
-	}
+	if (ext_conditional_rendering)
+		log << TestLog::Message << deviceConditionalRenderingFeatures[0] << TestLog::EndMessage;
+	if (ext_scalar_block_layout)
+		log << TestLog::Message << scalarBlockLayoutFeatures[0] << TestLog::EndMessage;
+	if (khr_performance_counter)
+		log << TestLog::Message << performanceQueryFeatures[0] << TestLog::EndMessage;
+	if (khr_16bit_storage)
+		log << TestLog::Message << device16BitStorageFeatures[0] << TestLog::EndMessage;
+	if (khr_multiview)
+		log << TestLog::Message << deviceMultiviewFeatures[0] << TestLog::EndMessage;
+	if (khr_device_protected_memory)
+		log << TestLog::Message << protectedMemoryFeatures[0] << TestLog::EndMessage;
+	if (khr_sampler_ycbcr_conversion)
+		log << TestLog::Message << samplerYcbcrConversionFeatures[0] << TestLog::EndMessage;
+	if (khr_variable_pointers)
+		log << TestLog::Message << variablePointerFeatures[0] << TestLog::EndMessage;
+	if (khr_8bit_storage)
+		log << TestLog::Message << device8BitStorageFeatures[0] << TestLog::EndMessage;
+	if (khr_shader_atomic_int64)
+		log << TestLog::Message << deviceShaderAtomicInt64Features[0] << TestLog::EndMessage;
+	if (khr_shader_float16_int8)
+		log << TestLog::Message << deviceShaderFloat16Int8Features[0] << TestLog::EndMessage;
+	if (khr_buffer_device_address)
+		log << TestLog::Message << deviceBufferDeviceAddressFeatures[0] << TestLog::EndMessage;
+	if (ext_buffer_device_address)
+		log << TestLog::Message << deviceBufferDeviceAddressFeaturesEXT[0] << TestLog::EndMessage;
+	if (ext_descriptor_indexing)
+		log << TestLog::Message << deviceDescriptorIndexingFeatures[0] << TestLog::EndMessage;
 
 	if ( ext_conditional_rendering &&
-		(deviceConditionalRenderingFeatures[0].conditionalRendering				!= deviceConditionalRenderingFeatures[1].conditionalRendering ||
-		deviceConditionalRenderingFeatures[0].inheritedConditionalRendering		!= deviceConditionalRenderingFeatures[1].inheritedConditionalRendering )
-		)
+		(	deviceConditionalRenderingFeatures[0].conditionalRendering				!= deviceConditionalRenderingFeatures[1].conditionalRendering ||
+			deviceConditionalRenderingFeatures[0].inheritedConditionalRendering		!= deviceConditionalRenderingFeatures[1].inheritedConditionalRendering ))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceConditionalRenderingFeaturesEXT");
 	}
@@ -2798,66 +4120,115 @@
 		TCU_FAIL("Mismatch between VkPhysicalDevicePerformancQueryFeaturesKHR");
 	}
 
+	if ( ext_scalar_block_layout &&
+		(	scalarBlockLayoutFeatures[0].scalarBlockLayout != scalarBlockLayoutFeatures[1].scalarBlockLayout ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeatures");
+	}
+
+	if ( khr_performance_counter &&
+		(	performanceQueryFeatures[0].performanceCounterQueryPools			!= performanceQueryFeatures[1].performanceCounterQueryPools ||
+			performanceQueryFeatures[0].performanceCounterMultipleQueryPools	!= performanceQueryFeatures[1].performanceCounterMultipleQueryPools ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDevicePerformancQueryFeaturesKHR");
+	}
+
 	if ( khr_16bit_storage &&
-		(device16BitStorageFeatures[0].storageBuffer16BitAccess				!= device16BitStorageFeatures[1].storageBuffer16BitAccess ||
-		device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess	!= device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
-		device16BitStorageFeatures[0].storagePushConstant16					!= device16BitStorageFeatures[1].storagePushConstant16 ||
-		device16BitStorageFeatures[0].storageInputOutput16					!= device16BitStorageFeatures[1].storageInputOutput16)
-		)
+		(	device16BitStorageFeatures[0].storageBuffer16BitAccess				!= device16BitStorageFeatures[1].storageBuffer16BitAccess ||
+			device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess	!= device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
+			device16BitStorageFeatures[0].storagePushConstant16					!= device16BitStorageFeatures[1].storagePushConstant16 ||
+			device16BitStorageFeatures[0].storageInputOutput16					!= device16BitStorageFeatures[1].storageInputOutput16 ))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures");
 	}
 
-	if (khr_multiview &&
-		(deviceMultiviewFeatures[0].multiview					!= deviceMultiviewFeatures[1].multiview ||
-		deviceMultiviewFeatures[0].multiviewGeometryShader		!= deviceMultiviewFeatures[1].multiviewGeometryShader ||
-		deviceMultiviewFeatures[0].multiviewTessellationShader	!= deviceMultiviewFeatures[1].multiviewTessellationShader)
-		)
+	if ( khr_multiview &&
+		(	deviceMultiviewFeatures[0].multiview					!= deviceMultiviewFeatures[1].multiview ||
+			deviceMultiviewFeatures[0].multiviewGeometryShader		!= deviceMultiviewFeatures[1].multiviewGeometryShader ||
+			deviceMultiviewFeatures[0].multiviewTessellationShader	!= deviceMultiviewFeatures[1].multiviewTessellationShader ))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures");
 	}
 
-	if (deviceProtectedMemory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory)
+	if ( khr_device_protected_memory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory )
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures");
 	}
 
-	if (sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion)
+	if ( khr_sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion )
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures");
 	}
 
-	if (variable_pointers &&
-		(variablePointerFeatures[0].variablePointersStorageBuffer	!= variablePointerFeatures[1].variablePointersStorageBuffer ||
-		variablePointerFeatures[0].variablePointers					!= variablePointerFeatures[1].variablePointers)
-		)
+	if ( khr_variable_pointers &&
+		(	variablePointerFeatures[0].variablePointersStorageBuffer	!= variablePointerFeatures[1].variablePointersStorageBuffer ||
+			variablePointerFeatures[0].variablePointers					!= variablePointerFeatures[1].variablePointers))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointersFeatures");
 	}
-	if (scalar_block_layout &&
-		(scalarBlockLayoutFeatures[0].scalarBlockLayout	!= scalarBlockLayoutFeatures[1].scalarBlockLayout))
+
+	if ( khr_8bit_storage &&
+		(	device8BitStorageFeatures[0].storageBuffer8BitAccess			!= device8BitStorageFeatures[1].storageBuffer8BitAccess ||
+			device8BitStorageFeatures[0].uniformAndStorageBuffer8BitAccess	!= device8BitStorageFeatures[1].uniformAndStorageBuffer8BitAccess ||
+			device8BitStorageFeatures[0].storagePushConstant8				!= device8BitStorageFeatures[1].storagePushConstant8 ))
 	{
-		TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeaturesEXT");
+		TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
 	}
 
-	if (khr_8bit_storage)
-		log << TestLog::Message << device8BitStorageFeatures[0]		<< TestLog::EndMessage;
-	if (ext_conditional_rendering)
-		log << TestLog::Message << deviceConditionalRenderingFeatures[0]		<< TestLog::EndMessage;
-	if (khr_16bit_storage)
-		log << TestLog::Message << device16BitStorageFeatures[0]		<< TestLog::EndMessage;
-	if (khr_multiview)
-		log << TestLog::Message << deviceMultiviewFeatures[0]			<< TestLog::EndMessage;
-	if (deviceProtectedMemory)
-		log << TestLog::Message << protectedMemoryFeatures[0]			<< TestLog::EndMessage;
-	if (sampler_ycbcr_conversion)
-		log << TestLog::Message << samplerYcbcrConversionFeatures[0]	<< TestLog::EndMessage;
-	if (variable_pointers)
-		log << TestLog::Message << variablePointerFeatures[0]			<< TestLog::EndMessage;
-	if (scalar_block_layout)
-		log << TestLog::Message << scalarBlockLayoutFeatures[0]			<< TestLog::EndMessage;
-	if (khr_performance_counter)
-		log << TestLog::Message << performanceQueryFeatures[0]		<< TestLog::EndMessage;
+	if ( khr_shader_atomic_int64 &&
+		(	deviceShaderAtomicInt64Features[0].shaderBufferInt64Atomics != deviceShaderAtomicInt64Features[1].shaderBufferInt64Atomics ||
+			deviceShaderAtomicInt64Features[0].shaderSharedInt64Atomics != deviceShaderAtomicInt64Features[1].shaderSharedInt64Atomics ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceShaderAtomicInt64Features");
+	}
+
+	if ( khr_shader_float16_int8 &&
+		(	deviceShaderFloat16Int8Features[0].shaderFloat16	!= deviceShaderFloat16Int8Features[1].shaderFloat16 ||
+			deviceShaderFloat16Int8Features[0].shaderInt8		!= deviceShaderFloat16Int8Features[1].shaderInt8 ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceShaderFloat16Int8Features");
+	}
+
+	if ( khr_buffer_device_address &&
+		(	deviceBufferDeviceAddressFeatures[0].bufferDeviceAddress				!= deviceBufferDeviceAddressFeatures[1].bufferDeviceAddress ||
+			deviceBufferDeviceAddressFeatures[0].bufferDeviceAddressCaptureReplay	!= deviceBufferDeviceAddressFeatures[1].bufferDeviceAddressCaptureReplay ||
+			deviceBufferDeviceAddressFeatures[0].bufferDeviceAddressMultiDevice		!= deviceBufferDeviceAddressFeatures[1].bufferDeviceAddressMultiDevice ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceBufferDeviceAddressFeatures");
+	}
+
+	if ( ext_buffer_device_address &&
+		(	deviceBufferDeviceAddressFeaturesEXT[0].bufferDeviceAddress					!= deviceBufferDeviceAddressFeaturesEXT[1].bufferDeviceAddress ||
+			deviceBufferDeviceAddressFeaturesEXT[0].bufferDeviceAddressCaptureReplay	!= deviceBufferDeviceAddressFeaturesEXT[1].bufferDeviceAddressCaptureReplay ||
+			deviceBufferDeviceAddressFeaturesEXT[0].bufferDeviceAddressMultiDevice		!= deviceBufferDeviceAddressFeaturesEXT[1].bufferDeviceAddressMultiDevice ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceBufferDeviceAddressFeaturesEXT");
+	}
+
+	if ( ext_descriptor_indexing &&
+		(	deviceDescriptorIndexingFeatures[0].shaderInputAttachmentArrayDynamicIndexing			!= deviceDescriptorIndexingFeatures[1].shaderInputAttachmentArrayDynamicIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderUniformTexelBufferArrayDynamicIndexing		!= deviceDescriptorIndexingFeatures[1].shaderUniformTexelBufferArrayDynamicIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderStorageTexelBufferArrayDynamicIndexing		!= deviceDescriptorIndexingFeatures[1].shaderStorageTexelBufferArrayDynamicIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderUniformBufferArrayNonUniformIndexing			!= deviceDescriptorIndexingFeatures[1].shaderUniformBufferArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderSampledImageArrayNonUniformIndexing			!= deviceDescriptorIndexingFeatures[1].shaderSampledImageArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderStorageBufferArrayNonUniformIndexing			!= deviceDescriptorIndexingFeatures[1].shaderStorageBufferArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderStorageImageArrayNonUniformIndexing			!= deviceDescriptorIndexingFeatures[1].shaderStorageImageArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderInputAttachmentArrayNonUniformIndexing		!= deviceDescriptorIndexingFeatures[1].shaderInputAttachmentArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderUniformTexelBufferArrayNonUniformIndexing		!= deviceDescriptorIndexingFeatures[1].shaderUniformTexelBufferArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].shaderStorageTexelBufferArrayNonUniformIndexing		!= deviceDescriptorIndexingFeatures[1].shaderStorageTexelBufferArrayNonUniformIndexing ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingUniformBufferUpdateAfterBind		!= deviceDescriptorIndexingFeatures[1].descriptorBindingUniformBufferUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingSampledImageUpdateAfterBind		!= deviceDescriptorIndexingFeatures[1].descriptorBindingSampledImageUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingStorageImageUpdateAfterBind		!= deviceDescriptorIndexingFeatures[1].descriptorBindingStorageImageUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingStorageBufferUpdateAfterBind		!= deviceDescriptorIndexingFeatures[1].descriptorBindingStorageBufferUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingUniformTexelBufferUpdateAfterBind	!= deviceDescriptorIndexingFeatures[1].descriptorBindingUniformTexelBufferUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingStorageTexelBufferUpdateAfterBind	!= deviceDescriptorIndexingFeatures[1].descriptorBindingStorageTexelBufferUpdateAfterBind ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingUpdateUnusedWhilePending			!= deviceDescriptorIndexingFeatures[1].descriptorBindingUpdateUnusedWhilePending ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingPartiallyBound						!= deviceDescriptorIndexingFeatures[1].descriptorBindingPartiallyBound ||
+			deviceDescriptorIndexingFeatures[0].descriptorBindingVariableDescriptorCount			!= deviceDescriptorIndexingFeatures[1].descriptorBindingVariableDescriptorCount ||
+			deviceDescriptorIndexingFeatures[0].runtimeDescriptorArray								!= deviceDescriptorIndexingFeatures[1].runtimeDescriptorArray ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingFeatures");
+	}
 
 	return tcu::TestStatus::pass("Querying device features succeeded");
 }
@@ -2899,142 +4270,238 @@
 
 	const int count = 2u;
 
-	bool khr_external_memory_capabilities		= true;
-	bool khr_multiview							= true;
-	bool khr_maintenance2						= true;
-	bool khr_maintenance3						= true;
-	bool apiVersionSmallerThen_1_1				= (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1);
-	if (apiVersionSmallerThen_1_1)
-	{
-		vector<VkExtensionProperties> properties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
-		khr_external_memory_capabilities			= checkExtension(properties,"VK_KHR_external_memory_capabilities");
-		khr_multiview								= checkExtension(properties,"VK_KHR_multiview");
-		khr_maintenance2							= checkExtension(properties,"VK_KHR_maintenance2");
-		khr_maintenance3							= checkExtension(properties,"VK_KHR_maintenance3");
-	}
+	vector<VkExtensionProperties> properties		= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+	const bool khr_external_fence_capabilities		= checkExtension(properties, "VK_KHR_external_fence_capabilities")		||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_external_memory_capabilities		= checkExtension(properties, "VK_KHR_external_memory_capabilities")		||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_external_semaphore_capabilities	= checkExtension(properties, "VK_KHR_external_semaphore_capabilities")	||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_multiview						= checkExtension(properties, "VK_KHR_multiview")						||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_device_protected_memory			=																			context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_device_subgroup					=																			context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_maintenance2						= checkExtension(properties, "VK_KHR_maintenance2")						||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_maintenance3						= checkExtension(properties, "VK_KHR_maintenance3")						||	context.contextSupports(vk::ApiVersion(1, 1, 0));
+	const bool khr_depth_stencil_resolve			= checkExtension(properties, "VK_KHR_depth_stencil_resolve")			||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_driver_properties				= checkExtension(properties, "VK_KHR_driver_properties")				||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_shader_float_controls			= checkExtension(properties, "VK_KHR_shader_float_controls")			||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_descriptor_indexing				= checkExtension(properties, "VK_EXT_descriptor_indexing")				||	context.contextSupports(vk::ApiVersion(1, 2, 0));
+	const bool khr_sampler_filter_minmax			= checkExtension(properties, "VK_EXT_sampler_filter_minmax")			||	context.contextSupports(vk::ApiVersion(1, 2, 0));
 
-	VkPhysicalDeviceIDProperties				IDProperties[count];
-	VkPhysicalDeviceMaintenance3Properties		maintenance3Properties[count];
-	VkPhysicalDeviceMultiviewProperties			multiviewProperties[count];
-	VkPhysicalDevicePointClippingProperties		pointClippingProperties[count];
-	VkPhysicalDeviceProtectedMemoryProperties	protectedMemoryPropertiesKHR[count];
-	VkPhysicalDeviceSubgroupProperties			subgroupProperties[count];
+	VkPhysicalDeviceIDProperties					idProperties[count];
+	VkPhysicalDeviceMultiviewProperties				multiviewProperties[count];
+	VkPhysicalDeviceProtectedMemoryProperties		protectedMemoryPropertiesKHR[count];
+	VkPhysicalDeviceSubgroupProperties				subgroupProperties[count];
+	VkPhysicalDevicePointClippingProperties			pointClippingProperties[count];
+	VkPhysicalDeviceMaintenance3Properties			maintenance3Properties[count];
+	VkPhysicalDeviceDepthStencilResolveProperties	depthStencilResolveProperties[count];
+	VkPhysicalDeviceDriverProperties				driverProperties[count];
+	VkPhysicalDeviceFloatControlsProperties			floatControlsProperties[count];
+	VkPhysicalDeviceDescriptorIndexingProperties	descriptorIndexingProperties[count];
+	VkPhysicalDeviceSamplerFilterMinmaxProperties	samplerFilterMinmaxProperties[count];
 
 	for (int ndx = 0; ndx < count; ++ndx)
 	{
-		deMemset(&IDProperties[ndx],					0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties				));
-		deMemset(&maintenance3Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties		));
-		deMemset(&multiviewProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties		));
-		deMemset(&pointClippingProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties	));
-		deMemset(&protectedMemoryPropertiesKHR[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties	));
-		deMemset(&subgroupProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties			));
+		deMemset(&idProperties[ndx],					0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties					));
+		deMemset(&multiviewProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties			));
+		deMemset(&protectedMemoryPropertiesKHR[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties		));
+		deMemset(&subgroupProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties				));
+		deMemset(&pointClippingProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties		));
+		deMemset(&maintenance3Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties			));
+		deMemset(&depthStencilResolveProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceDepthStencilResolveProperties	));
+		deMemset(&driverProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceDriverProperties				));
+		deMemset(&floatControlsProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceFloatControlsProperties		));
+		deMemset(&descriptorIndexingProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceDescriptorIndexingProperties	));
+		deMemset(&samplerFilterMinmaxProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceSamplerFilterMinmaxProperties	));
 
-		IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
-		IDProperties[ndx].pNext = &maintenance3Properties[ndx];
+		idProperties[ndx].sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
+		idProperties[ndx].pNext						= &multiviewProperties[ndx];
 
-		maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
-		maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
+		multiviewProperties[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
+		multiviewProperties[ndx].pNext				= &protectedMemoryPropertiesKHR[ndx];
 
-		multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
-		multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
+		protectedMemoryPropertiesKHR[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
+		protectedMemoryPropertiesKHR[ndx].pNext		= &subgroupProperties[ndx];
 
-		pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
-		pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
+		subgroupProperties[ndx].sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
+		subgroupProperties[ndx].pNext				= &pointClippingProperties[ndx];
 
-		protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
-		protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
+		pointClippingProperties[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
+		pointClippingProperties[ndx].pNext			= &maintenance3Properties[ndx];
 
-		subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
-		subgroupProperties[ndx].pNext = DE_NULL;
+		maintenance3Properties[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
+		maintenance3Properties[ndx].pNext			= &depthStencilResolveProperties[ndx];
 
-		extProperties.pNext = &IDProperties[ndx];
+		depthStencilResolveProperties[ndx].sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
+		depthStencilResolveProperties[ndx].pNext	= &driverProperties[ndx];
+
+		driverProperties[ndx].sType					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+		driverProperties[ndx].pNext					= &floatControlsProperties[ndx];
+
+		floatControlsProperties[ndx].sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
+		floatControlsProperties[ndx].pNext			= &descriptorIndexingProperties[ndx];
+
+		descriptorIndexingProperties[ndx].sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
+		descriptorIndexingProperties[ndx].pNext		= &samplerFilterMinmaxProperties[ndx];
+
+		samplerFilterMinmaxProperties[ndx].sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
+		samplerFilterMinmaxProperties[ndx].pNext	= DE_NULL;
+
+		extProperties.pNext							= &idProperties[ndx];
 
 		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
-
-		IDProperties[ndx].pNext						= DE_NULL;
-		maintenance3Properties[ndx].pNext			= DE_NULL;
-		multiviewProperties[ndx].pNext				= DE_NULL;
-		pointClippingProperties[ndx].pNext			= DE_NULL;
-		protectedMemoryPropertiesKHR[ndx].pNext		= DE_NULL;
-		subgroupProperties[ndx].pNext				= DE_NULL;
 	}
 
-	if (khr_external_memory_capabilities)
+	if ( khr_external_fence_capabilities || khr_external_memory_capabilities || khr_external_semaphore_capabilities )
+		log << TestLog::Message << idProperties[0]					<< TestLog::EndMessage;
+	if (khr_multiview)
+		log << TestLog::Message << multiviewProperties[0]			<< TestLog::EndMessage;
+	if (khr_device_protected_memory)
+		log << TestLog::Message << protectedMemoryPropertiesKHR[0]	<< TestLog::EndMessage;
+	if (khr_device_subgroup)
+		log << TestLog::Message << subgroupProperties[0]			<< TestLog::EndMessage;
+	if (khr_maintenance2)
+		log << TestLog::Message << pointClippingProperties[0]		<< TestLog::EndMessage;
+	if (khr_maintenance3)
+		log << TestLog::Message << maintenance3Properties[0]		<< TestLog::EndMessage;
+	if (khr_depth_stencil_resolve)
+		log << TestLog::Message << depthStencilResolveProperties[0] << TestLog::EndMessage;
+	if (khr_driver_properties)
+		log << TestLog::Message << driverProperties[0]				<< TestLog::EndMessage;
+	if (khr_shader_float_controls)
+		log << TestLog::Message << floatControlsProperties[0]		<< TestLog::EndMessage;
+	if (khr_descriptor_indexing)
+		log << TestLog::Message << descriptorIndexingProperties[0] << TestLog::EndMessage;
+	if (khr_sampler_filter_minmax)
+		log << TestLog::Message << samplerFilterMinmaxProperties[0] << TestLog::EndMessage;
+
+	if ( khr_external_fence_capabilities || khr_external_memory_capabilities || khr_external_semaphore_capabilities )
 	{
-		if ((deMemCmp(IDProperties[0].deviceUUID, IDProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
-			(deMemCmp(IDProperties[0].driverUUID, IDProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
-			(IDProperties[0].deviceLUIDValid	!= IDProperties[1].deviceLUIDValid))
+		if ((deMemCmp(idProperties[0].deviceUUID, idProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
+			(deMemCmp(idProperties[0].driverUUID, idProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
+			(idProperties[0].deviceLUIDValid	!= idProperties[1].deviceLUIDValid))
 		{
 			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
 		}
-		else if (IDProperties[0].deviceLUIDValid)
+		else if (idProperties[0].deviceLUIDValid)
 		{
 			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
 			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
-			if ((deMemCmp(IDProperties[0].deviceLUID, IDProperties[1].deviceLUID, VK_UUID_SIZE) != 0) ||
-				(IDProperties[0].deviceNodeMask		!= IDProperties[1].deviceNodeMask))
+			if ((deMemCmp(idProperties[0].deviceLUID, idProperties[1].deviceLUID, VK_UUID_SIZE) != 0) ||
+				(idProperties[0].deviceNodeMask		!= idProperties[1].deviceNodeMask))
 			{
 				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
 			}
 		}
 	}
-	if (khr_maintenance3 &&
-		((maintenance3Properties[0].maxPerSetDescriptors	!= maintenance3Properties[1].maxPerSetDescriptors) ||
-		(maintenance3Properties[0].maxMemoryAllocationSize	!= maintenance3Properties[1].maxMemoryAllocationSize))
-		)
-	{
-		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
-	}
 	if (khr_multiview &&
-		((multiviewProperties[0].maxMultiviewViewCount		!= multiviewProperties[1].maxMultiviewViewCount) ||
-		(multiviewProperties[0].maxMultiviewInstanceIndex	!= multiviewProperties[1].maxMultiviewInstanceIndex))
-		)
+		(multiviewProperties[0].maxMultiviewViewCount		!= multiviewProperties[1].maxMultiviewViewCount ||
+		 multiviewProperties[0].maxMultiviewInstanceIndex	!= multiviewProperties[1].maxMultiviewInstanceIndex))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties");
 	}
+	if (khr_device_protected_memory &&
+		(protectedMemoryPropertiesKHR[0].protectedNoFault	!= protectedMemoryPropertiesKHR[1].protectedNoFault))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
+	}
+	if (khr_device_subgroup &&
+		(subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize ||
+		 subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages ||
+		 subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations ||
+		 subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
+	}
 	if (khr_maintenance2 &&
-		(pointClippingProperties[0].pointClippingBehavior != pointClippingProperties[1].pointClippingBehavior))
+		(pointClippingProperties[0].pointClippingBehavior	!= pointClippingProperties[1].pointClippingBehavior))
 	{
 		TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties");
 	}
-	if (!apiVersionSmallerThen_1_1)
+	if (khr_maintenance3 &&
+		(maintenance3Properties[0].maxPerSetDescriptors		!= maintenance3Properties[1].maxPerSetDescriptors ||
+		 maintenance3Properties[0].maxMemoryAllocationSize	!= maintenance3Properties[1].maxMemoryAllocationSize))
 	{
-		if(protectedMemoryPropertiesKHR[0].protectedNoFault != protectedMemoryPropertiesKHR[1].protectedNoFault)
-		{
-			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
-		}
-		if ((subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize) ||
-			(subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages) ||
-			(subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations) ||
-			(subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages))
-		{
-			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
-		}
+		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
+	}
+	if (khr_depth_stencil_resolve &&
+		(depthStencilResolveProperties[0].supportedDepthResolveModes	!= depthStencilResolveProperties[1].supportedDepthResolveModes ||
+		 depthStencilResolveProperties[0].supportedStencilResolveModes	!= depthStencilResolveProperties[1].supportedStencilResolveModes ||
+		 depthStencilResolveProperties[0].independentResolveNone		!= depthStencilResolveProperties[1].independentResolveNone ||
+		 depthStencilResolveProperties[0].independentResolve			!= depthStencilResolveProperties[1].independentResolve))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceDepthStencilResolveProperties");
+	}
+	if (khr_driver_properties &&
+		(driverProperties[0].driverID												!= driverProperties[1].driverID ||
+		 strncmp(driverProperties[0].driverName, driverProperties[1].driverName, VK_MAX_DRIVER_NAME_SIZE)	!= 0 ||
+		 strncmp(driverProperties[0].driverInfo, driverProperties[1].driverInfo, VK_MAX_DRIVER_INFO_SIZE)		!= 0 ||
+		 driverProperties[0].conformanceVersion.major								!= driverProperties[1].conformanceVersion.major ||
+		 driverProperties[0].conformanceVersion.minor								!= driverProperties[1].conformanceVersion.minor ||
+		 driverProperties[0].conformanceVersion.subminor							!= driverProperties[1].conformanceVersion.subminor ||
+		 driverProperties[0].conformanceVersion.patch								!= driverProperties[1].conformanceVersion.patch))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceDriverProperties");
+	}
+	if (khr_shader_float_controls &&
+		(floatControlsProperties[0].denormBehaviorIndependence				!= floatControlsProperties[1].denormBehaviorIndependence ||
+		 floatControlsProperties[0].roundingModeIndependence				!= floatControlsProperties[1].roundingModeIndependence ||
+		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat16	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat16 ||
+		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat32	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat32 ||
+		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat64	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat64 ||
+		 floatControlsProperties[0].shaderDenormPreserveFloat16				!= floatControlsProperties[1].shaderDenormPreserveFloat16 ||
+		 floatControlsProperties[0].shaderDenormPreserveFloat32				!= floatControlsProperties[1].shaderDenormPreserveFloat32 ||
+		 floatControlsProperties[0].shaderDenormPreserveFloat64				!= floatControlsProperties[1].shaderDenormPreserveFloat64 ||
+		 floatControlsProperties[0].shaderDenormFlushToZeroFloat16			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat16 ||
+		 floatControlsProperties[0].shaderDenormFlushToZeroFloat32			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat32 ||
+		 floatControlsProperties[0].shaderDenormFlushToZeroFloat64			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat64 ||
+		 floatControlsProperties[0].shaderRoundingModeRTEFloat16			!= floatControlsProperties[1].shaderRoundingModeRTEFloat16 ||
+		 floatControlsProperties[0].shaderRoundingModeRTEFloat32			!= floatControlsProperties[1].shaderRoundingModeRTEFloat32 ||
+		 floatControlsProperties[0].shaderRoundingModeRTEFloat64			!= floatControlsProperties[1].shaderRoundingModeRTEFloat64 ||
+		 floatControlsProperties[0].shaderRoundingModeRTZFloat16			!= floatControlsProperties[1].shaderRoundingModeRTZFloat16 ||
+		 floatControlsProperties[0].shaderRoundingModeRTZFloat32			!= floatControlsProperties[1].shaderRoundingModeRTZFloat32 ||
+		 floatControlsProperties[0].shaderRoundingModeRTZFloat64			!= floatControlsProperties[1].shaderRoundingModeRTZFloat64 ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceFloatControlsProperties");
+	}
+	if (khr_descriptor_indexing &&
+		(descriptorIndexingProperties[0].maxUpdateAfterBindDescriptorsInAllPools				!= descriptorIndexingProperties[1].maxUpdateAfterBindDescriptorsInAllPools ||
+		 descriptorIndexingProperties[0].shaderUniformBufferArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderUniformBufferArrayNonUniformIndexingNative ||
+		 descriptorIndexingProperties[0].shaderSampledImageArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderSampledImageArrayNonUniformIndexingNative ||
+		 descriptorIndexingProperties[0].shaderStorageBufferArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderStorageBufferArrayNonUniformIndexingNative ||
+		 descriptorIndexingProperties[0].shaderStorageImageArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderStorageImageArrayNonUniformIndexingNative ||
+		 descriptorIndexingProperties[0].shaderInputAttachmentArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderInputAttachmentArrayNonUniformIndexingNative ||
+		 descriptorIndexingProperties[0].robustBufferAccessUpdateAfterBind						!= descriptorIndexingProperties[1].robustBufferAccessUpdateAfterBind ||
+		 descriptorIndexingProperties[0].quadDivergentImplicitLod								!= descriptorIndexingProperties[1].quadDivergentImplicitLod ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindSamplers			!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindSamplers ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindUniformBuffers		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindUniformBuffers ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindStorageBuffers		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindStorageBuffers ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindSampledImages		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindSampledImages ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindStorageImages		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindStorageImages ||
+		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindInputAttachments	!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindInputAttachments ||
+		 descriptorIndexingProperties[0].maxPerStageUpdateAfterBindResources					!= descriptorIndexingProperties[1].maxPerStageUpdateAfterBindResources ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindSamplers				!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindSamplers ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindUniformBuffers			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindUniformBuffers ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindUniformBuffersDynamic	!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindUniformBuffersDynamic ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageBuffers			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageBuffers ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageBuffersDynamic	!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageBuffersDynamic ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindSampledImages			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindSampledImages ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageImages			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageImages ||
+		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindInputAttachments		!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindInputAttachments ))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingProperties");
+	}
+	if (khr_sampler_filter_minmax &&
+		(samplerFilterMinmaxProperties[0].filterMinmaxSingleComponentFormats	!= samplerFilterMinmaxProperties[1].filterMinmaxSingleComponentFormats ||
+		 samplerFilterMinmaxProperties[0].filterMinmaxImageComponentMapping		!= samplerFilterMinmaxProperties[1].filterMinmaxImageComponentMapping))
+	{
+		TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerFilterMinmaxProperties");
 	}
 
-	if (khr_external_memory_capabilities)
-		log << TestLog::Message << IDProperties[0]					<< TestLog::EndMessage;
-	if (khr_maintenance3)
-		log << TestLog::Message << maintenance3Properties[0]			<< TestLog::EndMessage;
-	if (khr_multiview)
-		log << TestLog::Message << multiviewProperties[0]				<< TestLog::EndMessage;
-	if (khr_maintenance2)
-		log << TestLog::Message << pointClippingProperties[0]			<< TestLog::EndMessage;
-	if (!apiVersionSmallerThen_1_1)
-	{
-		log << TestLog::Message << protectedMemoryPropertiesKHR[0]	<< TestLog::EndMessage
-			<< TestLog::Message << subgroupProperties[0]				<< TestLog::EndMessage;
-	}
-
-	const vector<VkExtensionProperties>	extensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
-
-	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_push_descriptor")))
+	if (isExtensionSupported(properties, RequiredExtension("VK_KHR_push_descriptor")))
 	{
 		VkPhysicalDevicePushDescriptorPropertiesKHR		pushDescriptorProperties[count];
 
 		for (int ndx = 0; ndx < count; ++ndx)
 		{
-			deMemset(&pushDescriptorProperties[ndx], 0, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
+			deMemset(&pushDescriptorProperties[ndx], 0xFF * ndx, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
 
 			pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
 			pushDescriptorProperties[ndx].pNext	= DE_NULL;
@@ -3046,112 +4513,19 @@
 			pushDescriptorProperties[ndx].pNext = DE_NULL;
 		}
 
-		if (deMemCmp(&pushDescriptorProperties[0], &pushDescriptorProperties[1], sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)) != 0)
-		{
-			TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2 in VkPhysicalDevicePushDescriptorPropertiesKHR ");
-		}
-
 		log << TestLog::Message << pushDescriptorProperties[0] << TestLog::EndMessage;
 
+		if ( pushDescriptorProperties[0].maxPushDescriptors != pushDescriptorProperties[1].maxPushDescriptors )
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDevicePushDescriptorPropertiesKHR ");
+		}
 		if (pushDescriptorProperties[0].maxPushDescriptors < 32)
 		{
 			TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
 		}
 	}
-	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_shader_float_controls")))
-	{
-		VkPhysicalDeviceFloatControlsPropertiesKHR floatControlsProperties[count];
 
-		for (int ndx = 0; ndx < count; ++ndx)
-		{
-			deMemset(&floatControlsProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
-			floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
-			floatControlsProperties[ndx].pNext = DE_NULL;
-
-			extProperties.pNext = &floatControlsProperties[ndx];
-
-			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
-		}
-
-		if (deMemCmp(&floatControlsProperties[0], &floatControlsProperties[1], sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)) != 0)
-		{
-			TCU_FAIL("Mismatch in VkPhysicalDeviceFloatControlsPropertiesKHR");
-		}
-
-		log << TestLog::Message << floatControlsProperties[0] << TestLog::EndMessage;
-	}
-
-	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_depth_stencil_resolve")))
-	{
-		VkPhysicalDeviceDepthStencilResolvePropertiesKHR  dsResolveProperties[count];
-
-		for (int ndx = 0; ndx < count; ++ndx)
-		{
-			deMemset(&dsResolveProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
-			dsResolveProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
-			dsResolveProperties[ndx].pNext = DE_NULL;
-
-			extProperties.pNext = &dsResolveProperties[ndx];
-
-			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
-		}
-
-		if (deMemCmp(&dsResolveProperties[0], &dsResolveProperties[1], sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)) != 0)
-		{
-			TCU_FAIL("Mismatch in VkPhysicalDeviceDepthStencilResolvePropertiesKHR");
-		}
-
-		log << TestLog::Message << dsResolveProperties[0] << TestLog::EndMessage;
-	}
-
-	if (isExtensionSupported(extensions, RequiredExtension("VK_EXT_pci_bus_info", 2, 2)))
-	{
-		VkPhysicalDevicePCIBusInfoPropertiesEXT pciBusInfoProperties[count];
-
-		for (int ndx = 0; ndx < count; ++ndx)
-		{
-			// Each PCI device is identified by an 8-bit domain number, 5-bit
-			// device number and 3-bit function number[1][2].
-			//
-			// In addition, because PCI systems can be interconnected and
-			// divided in segments, Linux assigns a 16-bit number to the device
-			// as the "domain". In Windows, the segment or domain is stored in
-			// the higher 24-bit section of the bus number.
-			//
-			// This means the maximum unsigned 32-bit integer for these members
-			// are invalid values and should change after querying properties.
-			//
-			// [1] https://en.wikipedia.org/wiki/PCI_configuration_space
-			// [2] PCI Express Base Specification Revision 3.0, section 2.2.4.2.
-			deMemset(pciBusInfoProperties + ndx, 0, sizeof(pciBusInfoProperties[ndx]));
-			pciBusInfoProperties[ndx].pciDomain   = DEUINT32_MAX;
-			pciBusInfoProperties[ndx].pciBus      = DEUINT32_MAX;
-			pciBusInfoProperties[ndx].pciDevice   = DEUINT32_MAX;
-			pciBusInfoProperties[ndx].pciFunction = DEUINT32_MAX;
-
-			pciBusInfoProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
-			pciBusInfoProperties[ndx].pNext = DE_NULL;
-
-			extProperties.pNext = pciBusInfoProperties + ndx;
-			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
-		}
-
-		if (deMemCmp(pciBusInfoProperties + 0, pciBusInfoProperties + 1, sizeof(pciBusInfoProperties[0])) != 0)
-		{
-			TCU_FAIL("Mismatch in VkPhysicalDevicePCIBusInfoPropertiesEXT");
-		}
-
-		log << TestLog::Message << toString(pciBusInfoProperties[0]) << TestLog::EndMessage;
-
-		if (pciBusInfoProperties[0].pciDomain   == DEUINT32_MAX ||
-		    pciBusInfoProperties[0].pciBus      == DEUINT32_MAX ||
-		    pciBusInfoProperties[0].pciDevice   == DEUINT32_MAX ||
-		    pciBusInfoProperties[0].pciFunction == DEUINT32_MAX)
-		{
-			TCU_FAIL("Invalid information in VkPhysicalDevicePCIBusInfoPropertiesEXT");
-		}
-	}
-	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_performance_query")))
+	if (isExtensionSupported(properties, RequiredExtension("VK_KHR_performance_query")))
 	{
 		VkPhysicalDevicePerformanceQueryPropertiesKHR performanceQueryProperties[count];
 
@@ -3174,6 +4548,56 @@
 		}
 	}
 
+	if (isExtensionSupported(properties, RequiredExtension("VK_EXT_pci_bus_info", 2, 2)))
+	{
+		VkPhysicalDevicePCIBusInfoPropertiesEXT pciBusInfoProperties[count];
+
+		for (int ndx = 0; ndx < count; ++ndx)
+		{
+			// Each PCI device is identified by an 8-bit domain number, 5-bit
+			// device number and 3-bit function number[1][2].
+			//
+			// In addition, because PCI systems can be interconnected and
+			// divided in segments, Linux assigns a 16-bit number to the device
+			// as the "domain". In Windows, the segment or domain is stored in
+			// the higher 24-bit section of the bus number.
+			//
+			// This means the maximum unsigned 32-bit integer for these members
+			// are invalid values and should change after querying properties.
+			//
+			// [1] https://en.wikipedia.org/wiki/PCI_configuration_space
+			// [2] PCI Express Base Specification Revision 3.0, section 2.2.4.2.
+			deMemset(pciBusInfoProperties + ndx, 0xFF * ndx, sizeof(pciBusInfoProperties[ndx]));
+			pciBusInfoProperties[ndx].pciDomain   = DEUINT32_MAX;
+			pciBusInfoProperties[ndx].pciBus      = DEUINT32_MAX;
+			pciBusInfoProperties[ndx].pciDevice   = DEUINT32_MAX;
+			pciBusInfoProperties[ndx].pciFunction = DEUINT32_MAX;
+
+			pciBusInfoProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
+			pciBusInfoProperties[ndx].pNext = DE_NULL;
+
+			extProperties.pNext = pciBusInfoProperties + ndx;
+			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+		}
+
+		log << TestLog::Message << toString(pciBusInfoProperties[0]) << TestLog::EndMessage;
+
+		if (pciBusInfoProperties[0].pciDomain	!= pciBusInfoProperties[1].pciDomain ||
+			pciBusInfoProperties[0].pciBus		!= pciBusInfoProperties[1].pciBus ||
+			pciBusInfoProperties[0].pciDevice	!= pciBusInfoProperties[1].pciDevice ||
+			pciBusInfoProperties[0].pciFunction	!= pciBusInfoProperties[1].pciFunction)
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDevicePCIBusInfoPropertiesEXT");
+		}
+		if (pciBusInfoProperties[0].pciDomain   == DEUINT32_MAX ||
+		    pciBusInfoProperties[0].pciBus      == DEUINT32_MAX ||
+		    pciBusInfoProperties[0].pciDevice   == DEUINT32_MAX ||
+		    pciBusInfoProperties[0].pciFunction == DEUINT32_MAX)
+		{
+			TCU_FAIL("Invalid information in VkPhysicalDevicePCIBusInfoPropertiesEXT");
+		}
+	}
+
 	return tcu::TestStatus::pass("Querying device properties succeeded");
 }
 
@@ -3305,6 +4729,722 @@
 	return tcu::TestStatus::pass("Querying device memory properties succeeded");
 }
 
+tcu::TestStatus deviceFeaturesVulkan12 (Context& context)
+{
+	using namespace ValidateQueryBits;
+
+	const QueryMemberTableEntry			feature11OffsetTable[] =
+	{
+		// VkPhysicalDevice16BitStorageFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storageBuffer16BitAccess),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, uniformAndStorageBuffer16BitAccess),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storagePushConstant16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storageInputOutput16),
+
+		// VkPhysicalDeviceMultiviewFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiview),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader),
+
+		// VkPhysicalDeviceVariablePointersFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, variablePointers),
+
+		// VkPhysicalDeviceProtectedMemoryFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, protectedMemory),
+
+		// VkPhysicalDeviceSamplerYcbcrConversionFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, samplerYcbcrConversion),
+
+		// VkPhysicalDeviceShaderDrawParametersFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, shaderDrawParameters),
+		{ 0, 0 }
+	};
+	const QueryMemberTableEntry			feature12OffsetTable[] =
+	{
+		// None
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, samplerMirrorClampToEdge),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, drawIndirectCount),
+
+		// VkPhysicalDevice8BitStorageFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, storageBuffer8BitAccess),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, uniformAndStorageBuffer8BitAccess),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, storagePushConstant8),
+
+		// VkPhysicalDeviceShaderAtomicInt64Features
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderBufferInt64Atomics),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSharedInt64Atomics),
+
+		// VkPhysicalDeviceShaderFloat16Int8Features
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInt8),
+
+		// VkPhysicalDeviceDescriptorIndexingFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayDynamicIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayDynamicIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayDynamicIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformBufferArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSampledImageArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageBufferArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageImageArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayNonUniformIndexing),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformBufferUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingSampledImageUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageImageUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageBufferUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformTexelBufferUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageTexelBufferUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUpdateUnusedWhilePending),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingPartiallyBound),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingVariableDescriptorCount),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, runtimeDescriptorArray),
+
+		// None
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, samplerFilterMinmax),
+
+		// VkPhysicalDeviceScalarBlockLayoutFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, scalarBlockLayout),
+
+		// VkPhysicalDeviceImagelessFramebufferFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, imagelessFramebuffer),
+
+		// VkPhysicalDeviceUniformBufferStandardLayoutFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, uniformBufferStandardLayout),
+
+		// VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSubgroupExtendedTypes),
+
+		// VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, separateDepthStencilLayouts),
+
+		// VkPhysicalDeviceHostQueryResetFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, hostQueryReset),
+
+		// VkPhysicalDeviceTimelineSemaphoreFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, timelineSemaphore),
+
+		// VkPhysicalDeviceBufferDeviceAddressFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddress),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressCaptureReplay),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressMultiDevice),
+
+		// VkPhysicalDeviceVulkanMemoryModelFeatures
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModel),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelDeviceScope),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelAvailabilityVisibilityChains),
+
+		// None
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderOutputViewportIndex),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderOutputLayer),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, subgroupBroadcastDynamicId),
+		{ 0, 0 }
+	};
+	TestLog&											log										= context.getTestContext().getLog();
+	const VkPhysicalDevice								physicalDevice							= context.getPhysicalDevice();
+	const CustomInstance								instance								(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
+	const InstanceDriver&								vki										= instance.getDriver();
+	const deUint32										vulkan11FeaturesBufferSize				= sizeof(VkPhysicalDeviceVulkan11Features) + GUARD_SIZE;
+	const deUint32										vulkan12FeaturesBufferSize				= sizeof(VkPhysicalDeviceVulkan12Features) + GUARD_SIZE;
+	VkPhysicalDeviceFeatures2							extFeatures;
+	deUint8												buffer11a[vulkan11FeaturesBufferSize];
+	deUint8												buffer11b[vulkan11FeaturesBufferSize];
+	deUint8												buffer12a[vulkan12FeaturesBufferSize];
+	deUint8												buffer12b[vulkan12FeaturesBufferSize];
+	const int											count									= 2u;
+	VkPhysicalDeviceVulkan11Features*					vulkan11Features[count]					= { (VkPhysicalDeviceVulkan11Features*)(buffer11a), (VkPhysicalDeviceVulkan11Features*)(buffer11b)};
+	VkPhysicalDeviceVulkan12Features*					vulkan12Features[count]					= { (VkPhysicalDeviceVulkan12Features*)(buffer12a), (VkPhysicalDeviceVulkan12Features*)(buffer12b)};
+
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+
+	deMemset(buffer11b, GUARD_VALUE, sizeof(buffer11b));
+	deMemset(buffer12a, GUARD_VALUE, sizeof(buffer12a));
+	deMemset(buffer12b, GUARD_VALUE, sizeof(buffer12b));
+	deMemset(buffer11a, GUARD_VALUE, sizeof(buffer11a));
+
+	// Validate all fields initialized
+	for (int ndx = 0; ndx < count; ++ndx)
+	{
+		deMemset(&extFeatures.features, 0x00, sizeof(extFeatures.features));
+		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+		extFeatures.pNext = vulkan11Features[ndx];
+
+		deMemset(vulkan11Features[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan11Features));
+		vulkan11Features[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+		vulkan11Features[ndx]->pNext = vulkan12Features[ndx];
+
+		deMemset(vulkan12Features[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan12Features));
+		vulkan12Features[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+		vulkan12Features[ndx]->pNext = DE_NULL;
+
+		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
+	}
+
+	log << TestLog::Message << *vulkan11Features[0] << TestLog::EndMessage;
+	log << TestLog::Message << *vulkan12Features[0] << TestLog::EndMessage;
+
+	if (!validateStructsWithGuard(feature11OffsetTable, vulkan11Features, GUARD_VALUE, GUARD_SIZE))
+	{
+		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceVulkan11Features initialization failure" << TestLog::EndMessage;
+
+		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan11Features initialization failure");
+	}
+
+	if (!validateStructsWithGuard(feature12OffsetTable, vulkan12Features, GUARD_VALUE, GUARD_SIZE))
+	{
+		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceVulkan12Features initialization failure" << TestLog::EndMessage;
+
+		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan12Features initialization failure");
+	}
+
+	return tcu::TestStatus::pass("Querying Vulkan 1.2 device features succeeded");
+}
+
+tcu::TestStatus devicePropertiesVulkan12 (Context& context)
+{
+	using namespace ValidateQueryBits;
+
+	const QueryMemberTableEntry			properties11OffsetTable[] =
+	{
+		// VkPhysicalDeviceIDProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceUUID),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, driverUUID),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceLUID),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceNodeMask),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceLUIDValid),
+
+		// VkPhysicalDeviceSubgroupProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSize),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSupportedStages),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSupportedOperations),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupQuadOperationsInAllStages),
+
+		// VkPhysicalDevicePointClippingProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, pointClippingBehavior),
+
+		// VkPhysicalDeviceMultiviewProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMultiviewViewCount),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMultiviewInstanceIndex),
+
+		// VkPhysicalDeviceProtectedMemoryProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, protectedNoFault),
+
+		// VkPhysicalDeviceMaintenance3Properties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxPerSetDescriptors),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMemoryAllocationSize),
+		{ 0, 0 }
+	};
+	const QueryMemberTableEntry			properties12OffsetTable[] =
+	{
+		// VkPhysicalDeviceDriverProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, driverID),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, conformanceVersion),
+
+		// VkPhysicalDeviceFloatControlsProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, denormBehaviorIndependence),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, roundingModeIndependence),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat32),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat64),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat32),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat64),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat32),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat64),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat32),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat64),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat16),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat32),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat64),
+
+		// VkPhysicalDeviceDescriptorIndexingProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxUpdateAfterBindDescriptorsInAllPools),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderUniformBufferArrayNonUniformIndexingNative),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSampledImageArrayNonUniformIndexingNative),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderStorageBufferArrayNonUniformIndexingNative),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderStorageImageArrayNonUniformIndexingNative),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderInputAttachmentArrayNonUniformIndexingNative),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, robustBufferAccessUpdateAfterBind),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, quadDivergentImplicitLod),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindSamplers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindUniformBuffers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindStorageBuffers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindSampledImages),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindStorageImages),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindInputAttachments),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageUpdateAfterBindResources),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindSamplers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindUniformBuffers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageBuffers),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindSampledImages),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageImages),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindInputAttachments),
+
+		// VkPhysicalDeviceDepthStencilResolveProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, supportedDepthResolveModes),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, supportedStencilResolveModes),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, independentResolveNone),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, independentResolve),
+
+		// VkPhysicalDeviceSamplerFilterMinmaxProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, filterMinmaxSingleComponentFormats),
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, filterMinmaxImageComponentMapping),
+
+		// VkPhysicalDeviceTimelineSemaphoreProperties
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxTimelineSemaphoreValueDifference),
+
+		// None
+		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, framebufferIntegerColorSampleCounts),
+		{ 0, 0 }
+	};
+	TestLog&										log											= context.getTestContext().getLog();
+	const VkPhysicalDevice							physicalDevice								= context.getPhysicalDevice();
+	const CustomInstance							instance									(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
+	const InstanceDriver&							vki											= instance.getDriver();
+	const deUint32									vulkan11PropertiesBufferSize				= sizeof(VkPhysicalDeviceVulkan11Properties) + GUARD_SIZE;
+	const deUint32									vulkan12PropertiesBufferSize				= sizeof(VkPhysicalDeviceVulkan12Properties) + GUARD_SIZE;
+	VkPhysicalDeviceProperties2						extProperties;
+	deUint8											buffer11a[vulkan11PropertiesBufferSize];
+	deUint8											buffer11b[vulkan11PropertiesBufferSize];
+	deUint8											buffer12a[vulkan12PropertiesBufferSize];
+	deUint8											buffer12b[vulkan12PropertiesBufferSize];
+	const int										count										= 2u;
+	VkPhysicalDeviceVulkan11Properties*				vulkan11Properties[count]					= { (VkPhysicalDeviceVulkan11Properties*)(buffer11a), (VkPhysicalDeviceVulkan11Properties*)(buffer11b)};
+	VkPhysicalDeviceVulkan12Properties*				vulkan12Properties[count]					= { (VkPhysicalDeviceVulkan12Properties*)(buffer12a), (VkPhysicalDeviceVulkan12Properties*)(buffer12b)};
+
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+
+	deMemset(buffer11a, GUARD_VALUE, sizeof(buffer11a));
+	deMemset(buffer11b, GUARD_VALUE, sizeof(buffer11b));
+	deMemset(buffer12a, GUARD_VALUE, sizeof(buffer12a));
+	deMemset(buffer12b, GUARD_VALUE, sizeof(buffer12b));
+
+	for (int ndx = 0; ndx < count; ++ndx)
+	{
+		deMemset(&extProperties.properties, 0x00, sizeof(extProperties.properties));
+		extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+		extProperties.pNext = vulkan11Properties[ndx];
+
+		deMemset(vulkan11Properties[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan11Properties));
+		vulkan11Properties[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+		vulkan11Properties[ndx]->pNext = vulkan12Properties[ndx];
+
+		deMemset(vulkan12Properties[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan12Properties));
+		vulkan12Properties[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
+		vulkan12Properties[ndx]->pNext = DE_NULL;
+
+		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+	}
+
+	log << TestLog::Message << *vulkan11Properties[0] << TestLog::EndMessage;
+	log << TestLog::Message << *vulkan12Properties[0] << TestLog::EndMessage;
+
+	if (!validateStructsWithGuard(properties11OffsetTable, vulkan11Properties, GUARD_VALUE, GUARD_SIZE))
+	{
+		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceVulkan11Properties initialization failure" << TestLog::EndMessage;
+
+		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan11Properties initialization failure");
+	}
+
+	if (!validateStructsWithGuard(properties12OffsetTable, vulkan12Properties, GUARD_VALUE, GUARD_SIZE) ||
+		strncmp(vulkan12Properties[0]->driverName, vulkan12Properties[1]->driverName, VK_MAX_DRIVER_NAME_SIZE) != 0 ||
+		strncmp(vulkan12Properties[0]->driverInfo, vulkan12Properties[1]->driverInfo, VK_MAX_DRIVER_INFO_SIZE) != 0 )
+	{
+		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceVulkan12Properties initialization failure" << TestLog::EndMessage;
+
+		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan12Properties initialization failure");
+	}
+
+	return tcu::TestStatus::pass("Querying Vulkan 1.2 device properties succeeded");
+}
+
+tcu::TestStatus deviceFeatureExtensionsConsistencyVulkan12(Context& context)
+{
+	TestLog&											log										= context.getTestContext().getLog();
+	const VkPhysicalDevice								physicalDevice							= context.getPhysicalDevice();
+	const CustomInstance								instance								(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
+	const InstanceDriver&								vki										= instance.getDriver();
+
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+
+	VkPhysicalDeviceVulkan12Features					vulkan12Features						= initVulkanStructure();
+	VkPhysicalDeviceVulkan11Features					vulkan11Features						= initVulkanStructure(&vulkan12Features);
+	VkPhysicalDeviceFeatures2							extFeatures								= initVulkanStructure(&vulkan11Features);
+
+	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
+
+	log << TestLog::Message << vulkan11Features << TestLog::EndMessage;
+	log << TestLog::Message << vulkan12Features << TestLog::EndMessage;
+
+	// Validate if proper VkPhysicalDeviceVulkanXXFeatures fields are set when corresponding extensions are present
+	std::pair<std::pair<const char*,const char*>, VkBool32> extensions2validate[] =
+	{
+		{ { "VK_KHR_sampler_mirror_clamp_to_edge",	"VkPhysicalDeviceVulkan12Features.samplerMirrorClampToEdge" },	vulkan12Features.samplerMirrorClampToEdge },
+		{ { "VK_KHR_draw_indirect_count",			"VkPhysicalDeviceVulkan12Features.drawIndirectCount" },			vulkan12Features.drawIndirectCount },
+		{ { "VK_EXT_descriptor_indexing",			"VkPhysicalDeviceVulkan12Features.descriptorIndexing" },		vulkan12Features.descriptorIndexing },
+		{ { "VK_EXT_sampler_filter_minmax",			"VkPhysicalDeviceVulkan12Features.samplerFilterMinmax" },		vulkan12Features.samplerFilterMinmax },
+		{ { "VK_EXT_shader_viewport_index_layer",	"VkPhysicalDeviceVulkan12Features.shaderOutputViewportIndex" },	vulkan12Features.shaderOutputViewportIndex },
+		{ { "VK_EXT_shader_viewport_index_layer",	"VkPhysicalDeviceVulkan12Features.shaderOutputLayer" },			vulkan12Features.shaderOutputLayer }
+	};
+	vector<VkExtensionProperties> extensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+	for (const auto& ext : extensions2validate)
+		if (checkExtension(extensionProperties, ext.first.first) && !ext.second)
+			TCU_FAIL(string("Mismatch between extension ") + ext.first.first + " and " + ext.first.second);
+
+	// collect all extension features
+	{
+		VkPhysicalDevice16BitStorageFeatures				device16BitStorageFeatures				= initVulkanStructure();
+		VkPhysicalDeviceMultiviewFeatures					deviceMultiviewFeatures					= initVulkanStructure(&device16BitStorageFeatures);
+		VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures					= initVulkanStructure(&deviceMultiviewFeatures);
+		VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures			= initVulkanStructure(&protectedMemoryFeatures);
+		VkPhysicalDeviceShaderDrawParametersFeatures		shaderDrawParametersFeatures			= initVulkanStructure(&samplerYcbcrConversionFeatures);
+		VkPhysicalDeviceVariablePointersFeatures			variablePointerFeatures					= initVulkanStructure(&shaderDrawParametersFeatures);
+		VkPhysicalDevice8BitStorageFeatures					device8BitStorageFeatures				= initVulkanStructure(&variablePointerFeatures);
+		VkPhysicalDeviceShaderAtomicInt64Features			shaderAtomicInt64Features				= initVulkanStructure(&device8BitStorageFeatures);
+		VkPhysicalDeviceShaderFloat16Int8Features			shaderFloat16Int8Features				= initVulkanStructure(&shaderAtomicInt64Features);
+		VkPhysicalDeviceDescriptorIndexingFeatures			descriptorIndexingFeatures				= initVulkanStructure(&shaderFloat16Int8Features);
+		VkPhysicalDeviceScalarBlockLayoutFeatures			scalarBlockLayoutFeatures				= initVulkanStructure(&descriptorIndexingFeatures);
+		VkPhysicalDeviceImagelessFramebufferFeatures		imagelessFramebufferFeatures			= initVulkanStructure(&scalarBlockLayoutFeatures);
+		VkPhysicalDeviceUniformBufferStandardLayoutFeatures	uniformBufferStandardLayoutFeatures		= initVulkanStructure(&imagelessFramebufferFeatures);
+		VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures	shaderSubgroupExtendedTypesFeatures		= initVulkanStructure(&uniformBufferStandardLayoutFeatures);
+		VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures	separateDepthStencilLayoutsFeatures		= initVulkanStructure(&shaderSubgroupExtendedTypesFeatures);
+		VkPhysicalDeviceHostQueryResetFeatures				hostQueryResetFeatures					= initVulkanStructure(&separateDepthStencilLayoutsFeatures);
+		VkPhysicalDeviceTimelineSemaphoreFeatures			timelineSemaphoreFeatures				= initVulkanStructure(&hostQueryResetFeatures);
+		VkPhysicalDeviceBufferDeviceAddressFeatures			bufferDeviceAddressFeatures				= initVulkanStructure(&timelineSemaphoreFeatures);
+		VkPhysicalDeviceVulkanMemoryModelFeatures			vulkanMemoryModelFeatures				= initVulkanStructure(&bufferDeviceAddressFeatures);
+		extFeatures = initVulkanStructure(&vulkanMemoryModelFeatures);
+
+		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
+
+		log << TestLog::Message << extFeatures << TestLog::EndMessage;
+		log << TestLog::Message << device16BitStorageFeatures << TestLog::EndMessage;
+		log << TestLog::Message << deviceMultiviewFeatures << TestLog::EndMessage;
+		log << TestLog::Message << protectedMemoryFeatures << TestLog::EndMessage;
+		log << TestLog::Message << samplerYcbcrConversionFeatures << TestLog::EndMessage;
+		log << TestLog::Message << shaderDrawParametersFeatures << TestLog::EndMessage;
+		log << TestLog::Message << variablePointerFeatures << TestLog::EndMessage;
+		log << TestLog::Message << device8BitStorageFeatures << TestLog::EndMessage;
+		log << TestLog::Message << shaderAtomicInt64Features << TestLog::EndMessage;
+		log << TestLog::Message << shaderFloat16Int8Features << TestLog::EndMessage;
+		log << TestLog::Message << descriptorIndexingFeatures << TestLog::EndMessage;
+		log << TestLog::Message << scalarBlockLayoutFeatures << TestLog::EndMessage;
+		log << TestLog::Message << imagelessFramebufferFeatures << TestLog::EndMessage;
+		log << TestLog::Message << uniformBufferStandardLayoutFeatures << TestLog::EndMessage;
+		log << TestLog::Message << shaderSubgroupExtendedTypesFeatures << TestLog::EndMessage;
+		log << TestLog::Message << separateDepthStencilLayoutsFeatures << TestLog::EndMessage;
+		log << TestLog::Message << hostQueryResetFeatures << TestLog::EndMessage;
+		log << TestLog::Message << timelineSemaphoreFeatures << TestLog::EndMessage;
+		log << TestLog::Message << bufferDeviceAddressFeatures << TestLog::EndMessage;
+		log << TestLog::Message << vulkanMemoryModelFeatures << TestLog::EndMessage;
+
+		if ((	device16BitStorageFeatures.storageBuffer16BitAccess				!= vulkan11Features.storageBuffer16BitAccess ||
+				device16BitStorageFeatures.uniformAndStorageBuffer16BitAccess	!= vulkan11Features.uniformAndStorageBuffer16BitAccess ||
+				device16BitStorageFeatures.storagePushConstant16				!= vulkan11Features.storagePushConstant16 ||
+				device16BitStorageFeatures.storageInputOutput16					!= vulkan11Features.storageInputOutput16 ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if ((	deviceMultiviewFeatures.multiview					!= vulkan11Features.multiview ||
+				deviceMultiviewFeatures.multiviewGeometryShader		!= vulkan11Features.multiviewGeometryShader ||
+				deviceMultiviewFeatures.multiviewTessellationShader	!= vulkan11Features.multiviewTessellationShader ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if (	(protectedMemoryFeatures.protectedMemory	!= vulkan11Features.protectedMemory ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if (	(samplerYcbcrConversionFeatures.samplerYcbcrConversion	!= vulkan11Features.samplerYcbcrConversion ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if (	(shaderDrawParametersFeatures.shaderDrawParameters	!= vulkan11Features.shaderDrawParameters ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderDrawParametersFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if ((	variablePointerFeatures.variablePointersStorageBuffer	!= vulkan11Features.variablePointersStorageBuffer ||
+				variablePointerFeatures.variablePointers				!= vulkan11Features.variablePointers))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointersFeatures and VkPhysicalDeviceVulkan11Features");
+		}
+
+		if ((	device8BitStorageFeatures.storageBuffer8BitAccess			!= vulkan12Features.storageBuffer8BitAccess ||
+				device8BitStorageFeatures.uniformAndStorageBuffer8BitAccess	!= vulkan12Features.uniformAndStorageBuffer8BitAccess ||
+				device8BitStorageFeatures.storagePushConstant8				!= vulkan12Features.storagePushConstant8 ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	shaderAtomicInt64Features.shaderBufferInt64Atomics != vulkan12Features.shaderBufferInt64Atomics ||
+				shaderAtomicInt64Features.shaderSharedInt64Atomics != vulkan12Features.shaderSharedInt64Atomics ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderAtomicInt64Features and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	shaderFloat16Int8Features.shaderFloat16	!= vulkan12Features.shaderFloat16 ||
+				shaderFloat16Int8Features.shaderInt8		!= vulkan12Features.shaderInt8 ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderFloat16Int8Features and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((vulkan12Features.descriptorIndexing) &&
+			(	descriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing			!= vulkan12Features.shaderInputAttachmentArrayDynamicIndexing ||
+				descriptorIndexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing			!= vulkan12Features.shaderUniformTexelBufferArrayDynamicIndexing ||
+				descriptorIndexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing			!= vulkan12Features.shaderStorageTexelBufferArrayDynamicIndexing ||
+				descriptorIndexingFeatures.shaderUniformBufferArrayNonUniformIndexing			!= vulkan12Features.shaderUniformBufferArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing			!= vulkan12Features.shaderSampledImageArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderStorageBufferArrayNonUniformIndexing			!= vulkan12Features.shaderStorageBufferArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderStorageImageArrayNonUniformIndexing			!= vulkan12Features.shaderStorageImageArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderInputAttachmentArrayNonUniformIndexing			!= vulkan12Features.shaderInputAttachmentArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing		!= vulkan12Features.shaderUniformTexelBufferArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.shaderStorageTexelBufferArrayNonUniformIndexing		!= vulkan12Features.shaderStorageTexelBufferArrayNonUniformIndexing ||
+				descriptorIndexingFeatures.descriptorBindingUniformBufferUpdateAfterBind		!= vulkan12Features.descriptorBindingUniformBufferUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingSampledImageUpdateAfterBind			!= vulkan12Features.descriptorBindingSampledImageUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingStorageImageUpdateAfterBind			!= vulkan12Features.descriptorBindingStorageImageUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingStorageBufferUpdateAfterBind		!= vulkan12Features.descriptorBindingStorageBufferUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind	!= vulkan12Features.descriptorBindingUniformTexelBufferUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind	!= vulkan12Features.descriptorBindingStorageTexelBufferUpdateAfterBind ||
+				descriptorIndexingFeatures.descriptorBindingUpdateUnusedWhilePending			!= vulkan12Features.descriptorBindingUpdateUnusedWhilePending ||
+				descriptorIndexingFeatures.descriptorBindingPartiallyBound						!= vulkan12Features.descriptorBindingPartiallyBound ||
+				descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount				!= vulkan12Features.descriptorBindingVariableDescriptorCount ||
+				descriptorIndexingFeatures.runtimeDescriptorArray								!= vulkan12Features.runtimeDescriptorArray ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	scalarBlockLayoutFeatures.scalarBlockLayout != vulkan12Features.scalarBlockLayout ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	imagelessFramebufferFeatures.imagelessFramebuffer != vulkan12Features.imagelessFramebuffer ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceImagelessFramebufferFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	uniformBufferStandardLayoutFeatures.uniformBufferStandardLayout != vulkan12Features.uniformBufferStandardLayout ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceUniformBufferStandardLayoutFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	shaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes != vulkan12Features.shaderSubgroupExtendedTypes ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	separateDepthStencilLayoutsFeatures.separateDepthStencilLayouts != vulkan12Features.separateDepthStencilLayouts ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	hostQueryResetFeatures.hostQueryReset != vulkan12Features.hostQueryReset ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceHostQueryResetFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	timelineSemaphoreFeatures.timelineSemaphore != vulkan12Features.timelineSemaphore ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceTimelineSemaphoreFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	bufferDeviceAddressFeatures.bufferDeviceAddress					!= vulkan12Features.bufferDeviceAddress ||
+				bufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay	!= vulkan12Features.bufferDeviceAddressCaptureReplay ||
+				bufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice		!= vulkan12Features.bufferDeviceAddressMultiDevice ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceBufferDeviceAddressFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+
+		if ((	vulkanMemoryModelFeatures.vulkanMemoryModel								!= vulkan12Features.vulkanMemoryModel ||
+				vulkanMemoryModelFeatures.vulkanMemoryModelDeviceScope					!= vulkan12Features.vulkanMemoryModelDeviceScope ||
+				vulkanMemoryModelFeatures.vulkanMemoryModelAvailabilityVisibilityChains	!= vulkan12Features.vulkanMemoryModelAvailabilityVisibilityChains ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceVulkanMemoryModelFeatures and VkPhysicalDeviceVulkan12Features");
+		}
+	}
+
+	return tcu::TestStatus::pass("Vulkan 1.2 device features are consistent with extensions");
+}
+
+tcu::TestStatus devicePropertyExtensionsConsistencyVulkan12(Context& context)
+{
+	TestLog&										log											= context.getTestContext().getLog();
+	const VkPhysicalDevice							physicalDevice								= context.getPhysicalDevice();
+	const CustomInstance							instance									(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
+	const InstanceDriver&							vki											= instance.getDriver();
+
+	if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
+
+	VkPhysicalDeviceVulkan12Properties				vulkan12Properties							= initVulkanStructure();
+	VkPhysicalDeviceVulkan11Properties				vulkan11Properties							= initVulkanStructure(&vulkan12Properties);
+	VkPhysicalDeviceProperties2						extProperties								= initVulkanStructure(&vulkan11Properties);
+
+	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+
+	log << TestLog::Message << vulkan11Properties << TestLog::EndMessage;
+	log << TestLog::Message << vulkan12Properties << TestLog::EndMessage;
+
+	// Validate all fields initialized matching to extension structures
+	{
+		VkPhysicalDeviceIDProperties					idProperties								= initVulkanStructure();
+		VkPhysicalDeviceSubgroupProperties				subgroupProperties							= initVulkanStructure(&idProperties);
+		VkPhysicalDevicePointClippingProperties			pointClippingProperties						= initVulkanStructure(&subgroupProperties);
+		VkPhysicalDeviceMultiviewProperties				multiviewProperties							= initVulkanStructure(&pointClippingProperties);
+		VkPhysicalDeviceProtectedMemoryProperties		protectedMemoryPropertiesKHR				= initVulkanStructure(&multiviewProperties);
+		VkPhysicalDeviceMaintenance3Properties			maintenance3Properties						= initVulkanStructure(&protectedMemoryPropertiesKHR);
+		VkPhysicalDeviceDriverProperties				driverProperties							= initVulkanStructure(&maintenance3Properties);
+		VkPhysicalDeviceFloatControlsProperties			floatControlsProperties						= initVulkanStructure(&driverProperties);
+		VkPhysicalDeviceDescriptorIndexingProperties	descriptorIndexingProperties				= initVulkanStructure(&floatControlsProperties);
+		VkPhysicalDeviceDepthStencilResolveProperties	depthStencilResolveProperties				= initVulkanStructure(&descriptorIndexingProperties);
+		VkPhysicalDeviceSamplerFilterMinmaxProperties	samplerFilterMinmaxProperties				= initVulkanStructure(&depthStencilResolveProperties);
+		VkPhysicalDeviceTimelineSemaphoreProperties		timelineSemaphoreProperties					= initVulkanStructure(&samplerFilterMinmaxProperties);
+		extProperties = initVulkanStructure(&timelineSemaphoreProperties);
+
+		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+
+		if ((deMemCmp(idProperties.deviceUUID, vulkan11Properties.deviceUUID, VK_UUID_SIZE) != 0) ||
+			(deMemCmp(idProperties.driverUUID, vulkan11Properties.driverUUID, VK_UUID_SIZE) != 0) ||
+			(idProperties.deviceLUIDValid != vulkan11Properties.deviceLUIDValid))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties and VkPhysicalDeviceVulkan11Properties");
+		}
+		else if (idProperties.deviceLUIDValid)
+		{
+			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
+			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
+			if ((deMemCmp(idProperties.deviceLUID, vulkan11Properties.deviceLUID, VK_UUID_SIZE) != 0) ||
+				(idProperties.deviceNodeMask != vulkan11Properties.deviceNodeMask))
+			{
+				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties and VkPhysicalDeviceVulkan11Properties");
+			}
+		}
+
+		if ((subgroupProperties.subgroupSize				!= vulkan11Properties.subgroupSize ||
+			 subgroupProperties.supportedStages				!= vulkan11Properties.subgroupSupportedStages ||
+			 subgroupProperties.supportedOperations			!= vulkan11Properties.subgroupSupportedOperations ||
+			 subgroupProperties.quadOperationsInAllStages	!= vulkan11Properties.subgroupQuadOperationsInAllStages))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties and VkPhysicalDeviceVulkan11Properties");
+		}
+
+		if ((pointClippingProperties.pointClippingBehavior	!= vulkan11Properties.pointClippingBehavior))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties and VkPhysicalDeviceVulkan11Properties");
+		}
+
+		if ((multiviewProperties.maxMultiviewViewCount		!= vulkan11Properties.maxMultiviewViewCount ||
+			 multiviewProperties.maxMultiviewInstanceIndex	!= vulkan11Properties.maxMultiviewInstanceIndex))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties and VkPhysicalDeviceVulkan11Properties");
+		}
+
+		if ((protectedMemoryPropertiesKHR.protectedNoFault	!= vulkan11Properties.protectedNoFault))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties and VkPhysicalDeviceVulkan11Properties");
+		}
+
+		if ((maintenance3Properties.maxPerSetDescriptors	!= vulkan11Properties.maxPerSetDescriptors ||
+			 maintenance3Properties.maxMemoryAllocationSize	!= vulkan11Properties.maxMemoryAllocationSize))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties and VkPhysicalDeviceVulkan11Properties");
+		}
+
+		if ((driverProperties.driverID												!= vulkan12Properties.driverID ||
+			 strncmp(driverProperties.driverName, vulkan12Properties.driverName, VK_MAX_DRIVER_NAME_SIZE)	!= 0 ||
+			 strncmp(driverProperties.driverInfo, vulkan12Properties.driverInfo, VK_MAX_DRIVER_INFO_SIZE)	!= 0 ||
+			 driverProperties.conformanceVersion.major								!= vulkan12Properties.conformanceVersion.major ||
+			 driverProperties.conformanceVersion.minor								!= vulkan12Properties.conformanceVersion.minor ||
+			 driverProperties.conformanceVersion.subminor							!= vulkan12Properties.conformanceVersion.subminor ||
+			 driverProperties.conformanceVersion.patch								!= vulkan12Properties.conformanceVersion.patch))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceDriverProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+
+		if ((floatControlsProperties.denormBehaviorIndependence				!= vulkan12Properties.denormBehaviorIndependence ||
+			 floatControlsProperties.roundingModeIndependence				!= vulkan12Properties.roundingModeIndependence ||
+			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat16	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat16 ||
+			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat32	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat32 ||
+			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat64	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat64 ||
+			 floatControlsProperties.shaderDenormPreserveFloat16			!= vulkan12Properties.shaderDenormPreserveFloat16 ||
+			 floatControlsProperties.shaderDenormPreserveFloat32			!= vulkan12Properties.shaderDenormPreserveFloat32 ||
+			 floatControlsProperties.shaderDenormPreserveFloat64			!= vulkan12Properties.shaderDenormPreserveFloat64 ||
+			 floatControlsProperties.shaderDenormFlushToZeroFloat16			!= vulkan12Properties.shaderDenormFlushToZeroFloat16 ||
+			 floatControlsProperties.shaderDenormFlushToZeroFloat32			!= vulkan12Properties.shaderDenormFlushToZeroFloat32 ||
+			 floatControlsProperties.shaderDenormFlushToZeroFloat64			!= vulkan12Properties.shaderDenormFlushToZeroFloat64 ||
+			 floatControlsProperties.shaderRoundingModeRTEFloat16			!= vulkan12Properties.shaderRoundingModeRTEFloat16 ||
+			 floatControlsProperties.shaderRoundingModeRTEFloat32			!= vulkan12Properties.shaderRoundingModeRTEFloat32 ||
+			 floatControlsProperties.shaderRoundingModeRTEFloat64			!= vulkan12Properties.shaderRoundingModeRTEFloat64 ||
+			 floatControlsProperties.shaderRoundingModeRTZFloat16			!= vulkan12Properties.shaderRoundingModeRTZFloat16 ||
+			 floatControlsProperties.shaderRoundingModeRTZFloat32			!= vulkan12Properties.shaderRoundingModeRTZFloat32 ||
+			 floatControlsProperties.shaderRoundingModeRTZFloat64			!= vulkan12Properties.shaderRoundingModeRTZFloat64 ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceFloatControlsProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+
+		if ((descriptorIndexingProperties.maxUpdateAfterBindDescriptorsInAllPools				!= vulkan12Properties.maxUpdateAfterBindDescriptorsInAllPools ||
+			 descriptorIndexingProperties.shaderUniformBufferArrayNonUniformIndexingNative		!= vulkan12Properties.shaderUniformBufferArrayNonUniformIndexingNative ||
+			 descriptorIndexingProperties.shaderSampledImageArrayNonUniformIndexingNative		!= vulkan12Properties.shaderSampledImageArrayNonUniformIndexingNative ||
+			 descriptorIndexingProperties.shaderStorageBufferArrayNonUniformIndexingNative		!= vulkan12Properties.shaderStorageBufferArrayNonUniformIndexingNative ||
+			 descriptorIndexingProperties.shaderStorageImageArrayNonUniformIndexingNative		!= vulkan12Properties.shaderStorageImageArrayNonUniformIndexingNative ||
+			 descriptorIndexingProperties.shaderInputAttachmentArrayNonUniformIndexingNative	!= vulkan12Properties.shaderInputAttachmentArrayNonUniformIndexingNative ||
+			 descriptorIndexingProperties.robustBufferAccessUpdateAfterBind						!= vulkan12Properties.robustBufferAccessUpdateAfterBind ||
+			 descriptorIndexingProperties.quadDivergentImplicitLod								!= vulkan12Properties.quadDivergentImplicitLod ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSamplers			!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindUniformBuffers	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageBuffers	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSampledImages		!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageImages		!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages ||
+			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindInputAttachments	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments ||
+			 descriptorIndexingProperties.maxPerStageUpdateAfterBindResources					!= vulkan12Properties.maxPerStageUpdateAfterBindResources ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSamplers				!= vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffers			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic	!= vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffers			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic	!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSampledImages			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageImages			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages ||
+			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindInputAttachments		!= vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments ))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+
+		if ((depthStencilResolveProperties.supportedDepthResolveModes	!= vulkan12Properties.supportedDepthResolveModes ||
+			 depthStencilResolveProperties.supportedStencilResolveModes	!= vulkan12Properties.supportedStencilResolveModes ||
+			 depthStencilResolveProperties.independentResolveNone		!= vulkan12Properties.independentResolveNone ||
+			 depthStencilResolveProperties.independentResolve			!= vulkan12Properties.independentResolve))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceDepthStencilResolveProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+
+		if ((samplerFilterMinmaxProperties.filterMinmaxSingleComponentFormats	!= vulkan12Properties.filterMinmaxSingleComponentFormats ||
+			 samplerFilterMinmaxProperties.filterMinmaxImageComponentMapping	!= vulkan12Properties.filterMinmaxImageComponentMapping))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerFilterMinmaxProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+
+		if ((timelineSemaphoreProperties.maxTimelineSemaphoreValueDifference	!= vulkan12Properties.maxTimelineSemaphoreValueDifference))
+		{
+			TCU_FAIL("Mismatch between VkPhysicalDeviceTimelineSemaphoreProperties and VkPhysicalDeviceVulkan12Properties");
+		}
+	}
+
+	return tcu::TestStatus::pass("Vulkan 1.2 device properties are consistent with extension properties");
+}
+
 tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
 {
 	if (isYCbCrFormat(format))
@@ -3642,11 +5782,10 @@
 
 	// Instance extensions
 	{
-		static const string					mandatoryExtensions[]	=
+		static const string mandatoryExtensions[]	=
 		{
 			"VK_KHR_get_physical_device_properties2",
 		};
-		const vector<VkExtensionProperties>	extensions				= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
 
 		for (const auto ext : mandatoryExtensions)
 		{
@@ -3657,11 +5796,10 @@
 
 	// Device extensions
 	{
-		static const string					mandatoryExtensions[]	=
+		static const string mandatoryExtensions[] =
 		{
 			"VK_KHR_maintenance1",
 		};
-		const vector<VkExtensionProperties>	extensions				= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
 
 		for (const auto ext : mandatoryExtensions)
 		{
@@ -3696,6 +5834,43 @@
 		infoTests->addChild(extendedPropertiesTests.release());
 	}
 
+	{
+		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "vulkan1p2", "Vulkan 1.2 related tests"));
+
+		addFunctionCase(extendedPropertiesTests.get(), "features",							"Extended Vulkan 1.2 Device Features",						deviceFeaturesVulkan12);
+		addFunctionCase(extendedPropertiesTests.get(), "properties",						"Extended Vulkan 1.2 Device Properties",					devicePropertiesVulkan12);
+		addFunctionCase(extendedPropertiesTests.get(), "feature_extensions_consistency",	"Vulkan 1.2 consistency between Features and Extensions",	deviceFeatureExtensionsConsistencyVulkan12);
+		addFunctionCase(extendedPropertiesTests.get(), "property_extensions_consistency",	"Vulkan 1.2 consistency between Properties and Extensions", devicePropertyExtensionsConsistencyVulkan12);
+		addFunctionCase(extendedPropertiesTests.get(), "feature_bits_influence",			"Validate feature bits influence on feature activation",	checkSupportFeatureBitInfluence, featureBitInfluenceOnDeviceCreate);
+
+		infoTests->addChild(extendedPropertiesTests.release());
+	}
+
+	{
+		de::MovePtr<tcu::TestCaseGroup> limitsValidationTests (new tcu::TestCaseGroup(testCtx, "vulkan1p2_limits_validation", "Vulkan 1.2 and core extensions limits validation"));
+
+		addFunctionCase(limitsValidationTests.get(), "general",							"Vulkan 1.2 Limit validation",							validateLimitsCheckSupport,					validateLimits12);
+		addFunctionCase(limitsValidationTests.get(), "khr_push_descriptor",				"VK_KHR_push_descriptor limit validation",				checkSupportKhrPushDescriptor,				validateLimitsKhrPushDescriptor);
+		addFunctionCase(limitsValidationTests.get(), "khr_multiview",					"VK_KHR_multiview limit validation",					checkSupportKhrMultiview,					validateLimitsKhrMultiview);
+		addFunctionCase(limitsValidationTests.get(), "ext_discard_rectangles",			"VK_EXT_discard_rectangles limit validation",			checkSupportExtDiscardRectangles,			validateLimitsExtDiscardRectangles);
+		addFunctionCase(limitsValidationTests.get(), "ext_sample_locations",			"VK_EXT_sample_locations limit validation",				checkSupportExtSampleLocations,				validateLimitsExtSampleLocations);
+		addFunctionCase(limitsValidationTests.get(), "ext_external_memory_host",		"VK_EXT_external_memory_host limit validation",			checkSupportExtExternalMemoryHost,			validateLimitsExtExternalMemoryHost);
+		addFunctionCase(limitsValidationTests.get(), "ext_blend_operation_advanced",	"VK_EXT_blend_operation_advanced limit validation",		checkSupportExtBlendOperationAdvanced,		validateLimitsExtBlendOperationAdvanced);
+		addFunctionCase(limitsValidationTests.get(), "khr_maintenance_3",				"VK_KHR_maintenance3 limit validation",					checkSupportKhrMaintenance3,				validateLimitsKhrMaintenance3);
+		addFunctionCase(limitsValidationTests.get(), "ext_conservative_rasterization",	"VK_EXT_conservative_rasterization limit validation",	checkSupportExtConservativeRasterization,	validateLimitsExtConservativeRasterization);
+		addFunctionCase(limitsValidationTests.get(), "ext_descriptor_indexing",			"VK_EXT_descriptor_indexing limit validation",			checkSupportExtDescriptorIndexing,			validateLimitsExtDescriptorIndexing);
+		addFunctionCase(limitsValidationTests.get(), "ext_inline_uniform_block",		"VK_EXT_inline_uniform_block limit validation",			checkSupportExtInlineUniformBlock,			validateLimitsExtInlineUniformBlock);
+		addFunctionCase(limitsValidationTests.get(), "ext_vertex_attribute_divisor",	"VK_EXT_vertex_attribute_divisor limit validation",		checkSupportExtVertexAttributeDivisor,		validateLimitsExtVertexAttributeDivisor);
+		addFunctionCase(limitsValidationTests.get(), "nv_mesh_shader",					"VK_NV_mesh_shader limit validation",					checkSupportNvMeshShader,					validateLimitsNvMeshShader);
+		addFunctionCase(limitsValidationTests.get(), "ext_transform_feedback",			"VK_EXT_transform_feedback limit validation",			checkSupportExtTransformFeedback,			validateLimitsExtTransformFeedback);
+		addFunctionCase(limitsValidationTests.get(), "fragment_density_map",			"VK_EXT_fragment_density_map limit validation",			checkSupportExtFragmentDensityMap,			validateLimitsExtFragmentDensityMap);
+		addFunctionCase(limitsValidationTests.get(), "nv_ray_tracing",					"VK_NV_ray_tracing limit validation",					checkSupportNvRayTracing,					validateLimitsNvRayTracing);
+		addFunctionCase(limitsValidationTests.get(), "timeline_semaphore",				"VK_KHR_timeline_semaphore limit validation",			checkSupportKhrTimelineSemaphore,			validateLimitsKhrTimelineSemaphore);
+		addFunctionCase(limitsValidationTests.get(), "ext_line_rasterization",			"VK_EXT_line_rasterization limit validation",			checkSupportExtLineRasterization,			validateLimitsExtLineRasterization);
+
+		infoTests->addChild(limitsValidationTests.release());
+	}
+
 	infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",		"VkGetPhysicalDeviceImageFormatProperties2() Tests",		createImageFormatTests, imageFormatProperties2));
 	infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2",	"VkGetPhysicalDeviceSparseImageFormatProperties2() Tests",	createImageFormatTests, sparseImageFormatProperties2));
 
diff --git a/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
index 26aed40..d785c3d 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
@@ -879,7 +879,7 @@
 		VkImageLayout								imageLayout;
 		VkAttachmentReferenceStencilLayoutKHR		stencilLayoutRef		=
 		{
-			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR,
+			VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR,
 			DE_NULL,
 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
 		};
@@ -897,7 +897,7 @@
 		{
 			initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 			finalLayout = VK_IMAGE_LAYOUT_GENERAL;
-			stencilLayouts.stencilInitialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+			stencilLayouts.stencilInitialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
 			stencilLayouts.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
 			imageLayout = VK_IMAGE_LAYOUT_GENERAL;
 			stencilLayoutRef.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
@@ -959,7 +959,7 @@
 			DE_NULL,											// const deUint32*					pCorrelatedViewMasks;
 		};
 
-		return vk::createRenderPass2KHR(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
+		return vk::createRenderPass2(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
 	}
 }
 
diff --git a/external/vulkancts/modules/vulkan/api/vktApiMemoryRequirementInvarianceTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiMemoryRequirementInvarianceTests.cpp
index b35fa96..d4c1068 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiMemoryRequirementInvarianceTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiMemoryRequirementInvarianceTests.cpp
@@ -254,10 +254,8 @@
 	size_t									refSizes[testCycles];
 	unsigned int							order[testCycles];
 	bool									success							= true;
-	const deBool							isDedicatedAllocationSupported	=
-		m_context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation");
-	const deBool							isYcbcrSupported =
-		m_context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion");
+	const deBool							isDedicatedAllocationSupported	= m_context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation");
+	const deBool							isYcbcrSupported				= m_context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion");
 	std::vector<int>						optimalFormats;
 	std::vector<int>						linearFormats;
 	std::vector<int>						memoryTypes;
diff --git a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
index c307ead..e19a14d 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
@@ -28,6 +28,7 @@
 #include "vktApiDeviceInitializationTests.hpp"
 #include "vktApiDriverPropertiesTests.hpp"
 #include "vktApiObjectManagementTests.hpp"
+#include "vktApiBufferMarkerTests.hpp"
 #include "vktApiBufferTests.hpp"
 #include "vktApiBufferViewCreateTests.hpp"
 #include "vktApiBufferViewAccessTests.hpp"
@@ -74,6 +75,7 @@
 	apiTests->addChild(createDeviceInitializationTests			(testCtx));
 	apiTests->addChild(createObjectManagementTests				(testCtx));
 	apiTests->addChild(createBufferTests						(testCtx));
+	apiTests->addChild(createBufferMarkerTests					(testCtx));
 	apiTests->addChild(createTestGroup							(testCtx, "buffer_view",	"BufferView tests",		createBufferViewTests));
 	apiTests->addChild(createCommandBuffersTests				(testCtx));
 	apiTests->addChild(createCopiesAndBlittingTests				(testCtx));
diff --git a/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp b/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
index 8ad11e3..80a96c2 100644
--- a/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
+++ b/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
@@ -93,8 +93,12 @@
 typedef enum
 {
 	CONVERT_NONE = 0,
-	CONVERT_UTOPTR,
+	CONVERT_UINT64,
 	CONVERT_UVEC2,
+	CONVERT_U64CMP,
+	CONVERT_UVEC2CMP,
+	CONVERT_UVEC2TOU64,
+	CONVERT_U64TOUVEC2,
 } Convert;
 
 struct CaseDef
@@ -173,9 +177,6 @@
 	if (m_data.set >= context.getDeviceProperties().limits.maxBoundDescriptorSets)
 		TCU_THROW(NotSupportedError, "descriptor set number not supported");
 
-	if (m_data.convertUToPtr == VK_TRUE && !context.getDeviceFeatures().shaderInt64)
-		TCU_THROW(NotSupportedError, "64-bit integers in shader not supported");
-
 	bool isBufferDeviceAddressWithCaptureReplaySupported =
 			(context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") && context.getBufferDeviceAddressFeatures().bufferDeviceAddressCaptureReplay) ||
 			(context.isDeviceFunctionalitySupported("VK_EXT_buffer_device_address") && context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddressCaptureReplay);
@@ -193,9 +194,19 @@
 	}
 #endif
 
-	if (m_data.convertUToPtr == CONVERT_UTOPTR && !context.getDeviceFeatures().shaderInt64)
+	const bool needsInt64	= (	m_data.convertUToPtr == CONVERT_UINT64		||
+								m_data.convertUToPtr == CONVERT_U64CMP		||
+								m_data.convertUToPtr == CONVERT_U64TOUVEC2	||
+								m_data.convertUToPtr == CONVERT_UVEC2TOU64	);
+
+	const bool needsKHR		= (	m_data.convertUToPtr == CONVERT_UVEC2		||
+								m_data.convertUToPtr == CONVERT_UVEC2CMP	||
+								m_data.convertUToPtr == CONVERT_U64TOUVEC2	||
+								m_data.convertUToPtr == CONVERT_UVEC2TOU64	);
+
+	if (needsInt64 && !context.getDeviceFeatures().shaderInt64)
 		TCU_THROW(NotSupportedError, "Int64 not supported");
-	if (m_data.convertUToPtr == CONVERT_UVEC2 && !context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
+	if (needsKHR && !context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
 		TCU_THROW(NotSupportedError, "VK_KHR_buffer_device_address not supported");
 }
 
@@ -204,9 +215,9 @@
 	string newPrefix = prefix;
 	if (curDepth > 0)
 	{
-		if (m_data.convertUToPtr == CONVERT_UTOPTR)
+		if (m_data.convertUToPtr == CONVERT_UINT64 || m_data.convertUToPtr == CONVERT_UVEC2TOU64)
 			newPrefix = "T1(uint64_t(T1(" + newPrefix + ")))";
-		else if (m_data.convertUToPtr == CONVERT_UVEC2)
+		else if (m_data.convertUToPtr == CONVERT_UVEC2 || m_data.convertUToPtr == CONVERT_U64TOUVEC2)
 			newPrefix = "T1(uvec2(T1(" + newPrefix + ")))";
 	}
 
@@ -233,17 +244,72 @@
 		checks << "   accum |= f.z - " << bufNum*3+9 << ";\n";
 	}
 
+	const std::string localPrefix = "l" + de::toString(bufNum);
+
+	if (m_data.convertUToPtr == CONVERT_U64CMP || m_data.convertUToPtr == CONVERT_UVEC2CMP)
+	{
+		const std::string type = ((m_data.convertUToPtr == CONVERT_U64CMP) ? "uint64_t" : "uvec2");
+
+		checks << "   " << type << " " << localPrefix << "c0 = " << type << "(" << newPrefix << ".c[0]);\n";
+		checks << "   " << type << " " << localPrefix << "c1 = " << type << "(" << newPrefix << ".c[pc.identity[1]]);\n";
+		checks << "   " << type << " " << localPrefix << "d  = " << type << "(" << newPrefix << ".d);\n";
+	}
+
 	if (curDepth != m_data.depth)
 	{
+		// Check non-null pointers and inequality among them.
+		if (m_data.convertUToPtr == CONVERT_U64CMP)
+		{
+			checks << "   if (" << localPrefix << "c0 == zero ||\n"
+				   << "       " << localPrefix << "c1 == zero ||\n"
+				   << "       " << localPrefix << "d  == zero ||\n"
+				   << "       " << localPrefix << "c0 == " << localPrefix << "c1 ||\n"
+				   << "       " << localPrefix << "c1 == " << localPrefix << "d  ||\n"
+				   << "       " << localPrefix << "c0 == " << localPrefix << "d  ) {\n"
+				   << "     accum |= 1;\n"
+				   << "   }\n";
+		}
+		else if (m_data.convertUToPtr == CONVERT_UVEC2CMP)
+		{
+			checks << "   if (all(equal(" << localPrefix << "c0, zero)) ||\n"
+				   << "       all(equal(" << localPrefix << "c1, zero)) ||\n"
+				   << "       all(equal(" << localPrefix << "d , zero)) ||\n"
+				   << "       all(equal(" << localPrefix << "c0, " << localPrefix << "c1)) ||\n"
+				   << "       all(equal(" << localPrefix << "c1, " << localPrefix << "d )) ||\n"
+				   << "       all(equal(" << localPrefix << "c0, " << localPrefix << "d )) ) {\n"
+				   << "     accum |= 1;\n"
+				   << "   }\n";
+		}
+
 		checkBuffer(checks, bufNum*3+1, curDepth+1, newPrefix + ".c[0]");
 		checkBuffer(checks, bufNum*3+2, curDepth+1, newPrefix + ".c[pc.identity[1]]");
 		checkBuffer(checks, bufNum*3+3, curDepth+1, newPrefix + ".d");
 	}
+	else
+	{
+		// Check null pointers nonexplicitly.
+		if (m_data.convertUToPtr == CONVERT_U64CMP)
+		{
+			checks << "   if (!(" << localPrefix << "c0 == " << localPrefix << "c1 &&\n"
+				   << "         " << localPrefix << "c1 == " << localPrefix << "d  &&\n"
+				   << "         " << localPrefix << "c0 == " << localPrefix << "d  )) {\n"
+				   << "     accum |= 1;\n"
+				   << "   }\n";
+		}
+		else if (m_data.convertUToPtr == CONVERT_UVEC2CMP)
+		{
+			checks << "   if (!(all(equal(" << localPrefix << "c0, " << localPrefix << "c1)) &&\n"
+				   << "         all(equal(" << localPrefix << "c1, " << localPrefix << "d )) &&\n"
+				   << "         all(equal(" << localPrefix << "c0, " << localPrefix << "d )) )) {\n"
+				   << "     accum |= 1;\n"
+				   << "   }\n";
+		}
+	}
 }
 
 void BufferAddressTestInstance::fillBuffer (const std::vector<deUint8 *>& cpuAddrs,
-										  const std::vector<deUint64>& gpuAddrs,
-										  deUint32 bufNum, deUint32 curDepth) const
+											const std::vector<deUint64>& gpuAddrs,
+											deUint32 bufNum, deUint32 curDepth) const
 {
 	deUint8 *buf = cpuAddrs[bufNum];
 
@@ -281,19 +347,45 @@
 		fillBuffer(cpuAddrs, gpuAddrs, bufNum*3+2, curDepth+1);
 		fillBuffer(cpuAddrs, gpuAddrs, bufNum*3+3, curDepth+1);
 	}
+	else
+	{
+		// c
+		((deUint64 *)(buf+48))[0] = 0ull;
+		((deUint64 *)(buf+48))[cStride] = 0ull;
+		// d
+		((deUint64 *)(buf+80))[0] = 0ull;
+	}
 }
 
 
 void BufferAddressTestCase::initPrograms (SourceCollections& programCollection) const
 {
-	std::stringstream decls, checks;
+	std::stringstream decls, checks, localDecls;
 
 	std::string baseStorage = m_data.base == BASE_UBO ? "uniform" : "buffer";
 	std::string memberStorage = "buffer";
 
 	decls << "layout(r32ui, set = " << m_data.set << ", binding = 0) uniform uimage2D image0_0;\n";
 	decls << "layout(buffer_reference) " << memberStorage << " T1;\n";
-	std::string refType = m_data.convertUToPtr == CONVERT_UTOPTR ? "uint64_t" : m_data.convertUToPtr == CONVERT_UVEC2 ? "uvec2" : "T1";
+
+	std::string refType;
+	switch (m_data.convertUToPtr)
+	{
+	case CONVERT_UINT64:
+	case CONVERT_U64TOUVEC2:
+		refType = "uint64_t";
+		break;
+
+	case CONVERT_UVEC2:
+	case CONVERT_UVEC2TOU64:
+		refType = "uvec2";
+		break;
+
+	default:
+		refType = "T1";
+		break;
+	}
+
 	std::string layout = m_data.layout == LAYOUT_SCALAR ? "scalar" : "std140";
 	decls <<
 			"layout(set = " << m_data.set << ", binding = 1, " << layout << ") " << baseStorage << " T2 {\n"
@@ -314,6 +406,11 @@
 			"   layout(offset = 96, row_major) mat2 e; // tightly packed for scalar, 16 byte matrix stride for std140\n"
 			"};\n";
 
+	if (m_data.convertUToPtr == CONVERT_U64CMP)
+		localDecls << "  uint64_t zero = uint64_t(0);\n";
+	else if (m_data.convertUToPtr == CONVERT_UVEC2CMP)
+		localDecls << "  uvec2 zero = uvec2(0, 0);\n";
+
 	checkBuffer(checks, 0, 0, "x");
 
 	std::stringstream pushdecl;
@@ -323,6 +420,9 @@
 	if (m_data.layout == LAYOUT_SCALAR)
 		flags = vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS;
 
+	// The conversion and comparison in uvec2 form test needs SPIR-V 1.5 for OpBitcast.
+	const vk::SpirvVersion spirvVersion = ((m_data.convertUToPtr == CONVERT_UVEC2CMP) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_0);
+
 	switch (m_data.stage)
 	{
 	default: DE_ASSERT(0); // Fallthrough
@@ -342,13 +442,14 @@
 				"{\n"
 				"  int accum = 0, temp;\n"
 				"  ivec3 f;\n"
+				<< localDecls.str()
 				<< checks.str() <<
 				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
 				"  imageStore(image0_0, ivec2(gl_GlobalInvocationID.xy), color);\n"
 				"}\n";
 
 			programCollection.glslSources.add("test") << glu::ComputeSource(css.str())
-				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
+				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, spirvVersion, flags);
 			break;
 		}
 #if ENABLE_RAYTRACING
@@ -368,13 +469,14 @@
 				"{\n"
 				"  int accum = 0, temp;\n"
 				"  ivec3 f;\n"
+				<< localDecls.str()
 				<< checks.str() <<
 				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
 				"  imageStore(image0_0, ivec2(gl_LaunchIDNV.xy), color);\n"
 				"}\n";
 
 			programCollection.glslSources.add("test") << glu::RaygenSource(css.str())
-				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
+				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, spirvVersion, flags);
 			break;
 		}
 #endif
@@ -393,6 +495,7 @@
 				"{\n"
 				"  int accum = 0, temp;\n"
 				"  ivec3 f;\n"
+				<< localDecls.str()
 				<< checks.str() <<
 				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
 				"  imageStore(image0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n"
@@ -400,7 +503,7 @@
 				"}\n";
 
 			programCollection.glslSources.add("test") << glu::VertexSource(vss.str())
-				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
+				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, spirvVersion, flags);
 			break;
 		}
 	case STAGE_FRAGMENT:
@@ -429,13 +532,14 @@
 				"{\n"
 				"  int accum = 0, temp;\n"
 				"  ivec3 f;\n"
+				<< localDecls.str()
 				<< checks.str() <<
 				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
 				"  imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n"
 				"}\n";
 
 			programCollection.glslSources.add("test") << glu::FragmentSource(fss.str())
-				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
+				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, spirvVersion, flags);
 			break;
 		}
 	}
@@ -576,9 +680,9 @@
 		0x000000000ULL,												// VkDeviceSize		 deviceAddress
 	};
 
-	VkBufferOpaqueCaptureAddressCreateInfoKHR bufferOpaqueCaptureAddressCreateInfo =
+	VkBufferOpaqueCaptureAddressCreateInfo bufferOpaqueCaptureAddressCreateInfo =
 	{
-		VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR,// VkStructureType	 sType;
+		VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,	// VkStructureType	 sType;
 		DE_NULL,														// const void*		 pNext;
 		0x000000000ULL,													// VkDeviceSize		 opaqueCaptureAddress
 	};
@@ -588,16 +692,16 @@
 	std::vector<deUint64> opaqueBufferAddrs(numBindings);
 	std::vector<deUint64> opaqueMemoryAddrs(numBindings);
 
-	VkBufferDeviceAddressInfoKHR bufferDeviceAddressInfo =
+	VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
 	{
-		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,// VkStructureType	 sType;
+		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,	// VkStructureType	 sType;
 		DE_NULL,										// const void*		 pNext;
 		0,												// VkBuffer			 buffer
 	};
 
-	VkDeviceMemoryOpaqueCaptureAddressInfoKHR deviceMemoryOpaqueCaptureAddressInfo =
+	VkDeviceMemoryOpaqueCaptureAddressInfo deviceMemoryOpaqueCaptureAddressInfo =
 	{
-		VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR,// VkStructureType	 sType;
+		VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,	// VkStructureType	 sType;
 		DE_NULL,														// const void*		 pNext;
 		0,																// VkDeviceMemory	 memory;
 	};
@@ -612,8 +716,8 @@
 	VkBufferCreateInfo			bufferCreateInfo = makeBufferCreateInfo(DE_NULL, bufferSize,
 														VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
 														VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
-														VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,
-														m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR : 0);
+														VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+														m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT : 0);
 
 	// VkMemoryAllocateFlags to be filled out later
 	VkMemoryAllocateFlagsInfo	allocFlagsInfo =
@@ -624,19 +728,19 @@
 		0,												//	uint32_t                 deviceMask
 	};
 
-	VkMemoryOpaqueCaptureAddressAllocateInfoKHR memoryOpaqueCaptureAddressAllocateInfo =
+	VkMemoryOpaqueCaptureAddressAllocateInfo memoryOpaqueCaptureAddressAllocateInfo =
 	{
-		VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR,// VkStructureType    sType;
+		VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,	// VkStructureType    sType;
 		DE_NULL,														// const void*        pNext;
 		0,																// uint64_t           opaqueCaptureAddress;
 	};
 
 	if (useKHR)
-		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
+		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
 
 	if (useKHR && m_data.bufType == BT_REPLAY)
 	{
-		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR;
+		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
 		allocFlagsInfo.pNext = &memoryOpaqueCaptureAddressAllocateInfo;
 	}
 
@@ -647,14 +751,14 @@
 		// query opaque capture address before binding memory
 		if (useKHR) {
 			bufferDeviceAddressInfo.buffer = **buffers[i];
-			opaqueBufferAddrs[i] = vk.getBufferOpaqueCaptureAddressKHR(device, &bufferDeviceAddressInfo);
+			opaqueBufferAddrs[i] = vk.getBufferOpaqueCaptureAddress(device, &bufferDeviceAddressInfo);
 		}
 
 		allocations[i] = AllocationSp(allocateExtended(vki, vk, physDevice, device, getBufferMemoryRequirements(vk, device, **buffers[i]), MemoryRequirement::HostVisible, &allocFlagsInfo));
 
 		if (useKHR) {
 			deviceMemoryOpaqueCaptureAddressInfo.memory = allocations[i]->getMemory();
-			opaqueMemoryAddrs[i] = vk.getDeviceMemoryOpaqueCaptureAddressKHR(device, &deviceMemoryOpaqueCaptureAddressInfo);
+			opaqueMemoryAddrs[i] = vk.getDeviceMemoryOpaqueCaptureAddress(device, &deviceMemoryOpaqueCaptureAddressInfo);
 		}
 
 		VK_CHECK(vk.bindBufferMemory(device, **buffers[i], allocations[i]->getMemory(), 0));
@@ -666,7 +770,7 @@
 		{
 			bufferDeviceAddressInfo.buffer = **buffers[i];
 			if (useKHR)
-				gpuAddrs[i] = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
+				gpuAddrs[i] = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo);
 			else
 				gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
 		}
@@ -690,7 +794,7 @@
 			bufferDeviceAddressInfo.buffer = **buffers[i];
 			VkDeviceSize newAddr;
 			if (useKHR)
-				newAddr = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
+				newAddr = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo);
 			else
 				newAddr = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
 			if (newAddr != gpuAddrs[i])
@@ -704,7 +808,7 @@
 		bufferDeviceAddressInfo.buffer = **buffers[multiBuffer ? i : 0];
 
 		if (useKHR)
-			gpuAddrs[i] = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
+			gpuAddrs[i] = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo);
 		else
 			gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
 		cpuAddrs[i] = (deUint8 *)allocations[multiBuffer ? i : 0]->getHostPtr();
@@ -1256,9 +1360,13 @@
 
 	TestGroupCase cvtCases[] =
 	{
-		{ CONVERT_NONE,		"load",			"load reference"						},
-		{ CONVERT_UTOPTR,	"convert",		"load and convert reference"			},
-		{ CONVERT_UVEC2,	"convertuvec2",	"load and convert reference to uvec2"	},
+		{ CONVERT_NONE,			"load",				"load reference"										},
+		{ CONVERT_UINT64,		"convert",			"load and convert reference"							},
+		{ CONVERT_UVEC2,		"convertuvec2",		"load and convert reference to uvec2"					},
+		{ CONVERT_U64CMP,		"convertchecku64",	"load, convert and compare references as uint64_t"		},
+		{ CONVERT_UVEC2CMP,		"convertcheckuv2",	"load, convert and compare references as uvec2"			},
+		{ CONVERT_UVEC2TOU64,	"crossconvertu2p",	"load reference as uint64_t and convert it to uvec2"	},
+		{ CONVERT_U64TOUVEC2,	"crossconvertp2u",	"load reference as uvec2 and convert it to uint64_t"	},
 	};
 
 	TestGroupCase storeCases[] =
diff --git a/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorCopyTests.cpp b/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorCopyTests.cpp
index 332fa80..e9c250b 100644
--- a/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorCopyTests.cpp
+++ b/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorCopyTests.cpp
@@ -149,6 +149,44 @@
 	vector<VkBufferView>			m_bufferViewHandles;
 };
 
+// Inline uniform block descriptor.
+class InlineUniformBlockDescriptor : public Descriptor
+{
+public:
+									InlineUniformBlockDescriptor		(deUint32 arraySize, deUint32 writeStart, deUint32 elementsToWrite, deUint32 numDynamicAreas = 1u);
+	virtual							~InlineUniformBlockDescriptor		(void);
+	void							init								(Context& context, PipelineType pipelineType);
+
+	VkWriteDescriptorSet			getDescriptorWrite					(void);
+	virtual string					getShaderDeclaration				(void) const;
+	virtual string					getShaderVerifyCode					(void) const;
+	virtual bool					usesBufferView						(void) { return false; }
+	deUint32						getElementSizeInBytes				(void) const { return static_cast<deUint32>(sizeof(decltype(m_blockData)::value_type)); }
+	deUint32						getSizeInBytes						(void) const { return m_blockElements * getElementSizeInBytes(); }
+
+private:
+	// Inline uniform blocks cannot form arrays, so we will reuse the array size to create a data array inside the uniform block as
+	// an array of integers. However, with std140, each of those ints will be padded to 16 bytes in the shader. The struct below
+	// allows memory to match between the host and the shader.
+	struct PaddedUint
+	{
+					PaddedUint	() : value(0) { deMemset(padding, 0, sizeof(padding)); }
+					PaddedUint	(deUint32 value_) : value(value_) { deMemset(padding, 0, sizeof(padding)); }
+		PaddedUint&	operator=	(deUint32 value_) { value = value_; return *this; }
+
+		deUint32	value;
+		deUint32	padding[3];
+	};
+
+	vector<PaddedUint>							m_blockData;
+	VkWriteDescriptorSetInlineUniformBlockEXT	m_inlineWrite;
+	deUint32									m_blockElements;
+	deUint32									m_writeStart;
+	deUint32									m_elementsToWrite;
+	deUint32									m_writeStartByteOffset;
+	deUint32									m_bytesToWrite;
+};
+
 class UniformBufferDescriptor : public BufferDescriptor
 {
 public:
@@ -625,6 +663,89 @@
 	return data;
 }
 
+// Inline Uniform Block descriptor. These are similar to uniform buffers, but they can't form arrays for spec reasons.
+// The array size is reused, instead, as the size of a data array inside the uniform block.
+InlineUniformBlockDescriptor::InlineUniformBlockDescriptor (deUint32	arraySize,
+															deUint32	writeStart,
+															deUint32	elementsToWrite,
+															deUint32	numDynamicAreas)
+: Descriptor(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, arraySize, writeStart, elementsToWrite, 1u)
+, m_blockElements(arraySize)
+, m_writeStart(writeStart)
+, m_elementsToWrite(elementsToWrite)
+, m_writeStartByteOffset(m_writeStart * getElementSizeInBytes())
+, m_bytesToWrite(m_elementsToWrite * getElementSizeInBytes())
+{
+	DE_UNREF(numDynamicAreas);
+}
+
+InlineUniformBlockDescriptor::~InlineUniformBlockDescriptor (void)
+{
+}
+
+void InlineUniformBlockDescriptor::init (Context&		context,
+										 PipelineType	pipelineType)
+{
+	DE_UNREF(context);
+	DE_UNREF(pipelineType);
+
+	// Initialize host memory.
+	m_blockData.resize(m_blockElements);
+	for (deUint32 i = 0; i < m_blockElements; ++i)
+		m_blockData[i] = m_id + i;
+
+	// Initialize descriptor write extension structure.
+	m_inlineWrite.sType		= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
+	m_inlineWrite.pNext		= DE_NULL;
+	m_inlineWrite.dataSize	= m_bytesToWrite;
+	m_inlineWrite.pData		= &m_blockData[m_writeStart];
+}
+
+VkWriteDescriptorSet InlineUniformBlockDescriptor::getDescriptorWrite (void)
+{
+	// Set and binding will be overwritten later
+	const VkWriteDescriptorSet	descriptorWrite	=
+	{
+		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType
+		&m_inlineWrite,								// const void*						pNext
+		(VkDescriptorSet)0u,						// VkDescriptorSet					dstSet
+		0u,											// deUint32							dstBinding
+		m_writeStartByteOffset,						// deUint32							dstArrayElement
+		m_bytesToWrite,								// deUint32							descriptorCount
+		getType(),									// VkDescriptorType					descriptorType
+		DE_NULL,									// const VkDescriptorImageInfo		pImageInfo
+		DE_NULL,									// const VkDescriptorBufferInfo*	pBufferInfo
+		DE_NULL										// const VkBufferView*				pTexelBufferView
+	};
+
+	return descriptorWrite;
+}
+
+string InlineUniformBlockDescriptor::getShaderDeclaration (void) const
+{
+	const string idStr = de::toString(m_id);
+	return string(") uniform InlineUniformBlock" + idStr + "\n"
+		"{\n"
+		"	int data" + getArrayString(m_arraySize) + ";\n"
+		"} inlineUniformBlock" + idStr + ";\n");
+}
+
+string InlineUniformBlockDescriptor::getShaderVerifyCode (void) const
+{
+	const string idStr = de::toString(m_id);
+	string ret;
+
+	for (deUint32 i = 0; i < m_arraySize; i++)
+	{
+		if (m_data[i].written || m_data[i].copiedInto)
+		{
+			ret += string("if (inlineUniformBlock") + idStr + ".data" + getArrayString(i) + " != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
+		}
+	}
+
+	return ret;
+}
+
 UniformBufferDescriptor::UniformBufferDescriptor (deUint32	arraySize,
 												  deUint32	writeStart,
 												  deUint32	elementsToWrite,
@@ -1293,11 +1414,13 @@
 
 	m_descriptorSets[descriptorSet]->addBinding(descriptor);
 
-	// Keep track of how many descriptors of each type is needed
+	// Keep track of how many descriptors of each type is needed. Inline uniform blocks cannot form arrays. We reuse the array size
+	// as size of the data array for them, within a single descriptor.
+	const deUint32 count = ((type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 1u : descriptor->getArraySize());
 	if (m_descriptorCounts.find(type) != m_descriptorCounts.end())
-		m_descriptorCounts[type] += descriptor->getArraySize();
+		m_descriptorCounts[type] += count;
 	else
-		m_descriptorCounts[type] = descriptor->getArraySize();
+		m_descriptorCounts[type] = count;
 
 	// Keep descriptors also in a flat list for easier iteration
 	m_descriptors.push_back(descriptor);
@@ -1311,7 +1434,20 @@
 										 deUint32	dstArrayElement,
 										 deUint32	descriptorCount)
 {
-	const DescriptorCopy descriptorCopy = { srcSet, srcBinding, srcArrayElement, dstSet, dstBinding, dstArrayElement, descriptorCount };
+	// For inline uniform blocks, (src|dst)ArrayElement are data array indices and descriptorCount is the number of integers to copy.
+	DescriptorCopy descriptorCopy = { srcSet, srcBinding, srcArrayElement, dstSet, dstBinding, dstArrayElement, descriptorCount };
+
+	if (m_descriptorSets[srcSet]->getBindings()[srcBinding]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
+	{
+		// For inline uniform blocks, these members of VkCopyDescriptorSet are offsets and sizes in bytes.
+		const InlineUniformBlockDescriptor* iub	=	static_cast<InlineUniformBlockDescriptor*>(m_descriptorSets[srcSet]->getBindings()[srcBinding].get());
+		const deUint32 elementSize				=	iub->getElementSizeInBytes();
+
+		descriptorCopy.srcArrayElement *= elementSize;
+		descriptorCopy.dstArrayElement *= elementSize;
+		descriptorCopy.descriptorCount *= elementSize;
+	}
+
 	m_descriptorCopies.push_back(descriptorCopy);
 	m_descriptorSets[descriptorCopy.dstSet]->getBindings()[descriptorCopy.dstBinding]->copyValue(*m_descriptorSets[descriptorCopy.srcSet]->getBindings()[descriptorCopy.srcBinding], srcArrayElement, dstArrayElement, descriptorCount);
 }
@@ -1394,10 +1530,12 @@
 
 tcu::TestStatus DescriptorCommands::run (Context& context)
 {
+	const InstanceInterface&				vki					= context.getInstanceInterface();
 	const DeviceInterface&					vk					= context.getDeviceInterface();
     const VkDevice							device				= context.getDevice();
 	const VkQueue							queue				= context.getUniversalQueue();
-	const VkPhysicalDeviceLimits			limits				= getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
+	const VkPhysicalDevice					physicalDevice		= context.getPhysicalDevice();
+	const VkPhysicalDeviceLimits			limits				= getPhysicalDeviceProperties(vki, physicalDevice).limits;
 	const deUint32							queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
     Allocator&								allocator			= context.getDefaultAllocator();
 	tcu::TestLog&							log					= context.getTestContext().getLog();
@@ -1405,6 +1543,8 @@
 	const Unique<VkCommandBuffer>			commandBuffer		(allocateCommandBuffer(vk, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 	const VkShaderStageFlags				shaderStage			= m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
 	const VkFormat							resultFormat		= VK_FORMAT_R8G8B8A8_UNORM;
+	deUint32								numTotalIUBs		= 0;
+	deUint32								iubTotalBytes		= 0;
 	de::MovePtr<ImageWithMemory>			resultImage;
 	de::MovePtr<BufferWithMemory>			resultImageBuffer;
 	Move<VkImageView>						resultImageView;
@@ -1419,9 +1559,39 @@
 	vector<VkAttachmentDescription>			attachmentDescriptions;
 	vector<VkImageView>						imageViews;
 
-	if(limits.maxBoundDescriptorSets <= m_descriptorSets.size())
+	if (limits.maxBoundDescriptorSets <= m_descriptorSets.size())
 		TCU_THROW(NotSupportedError, "Maximum bound descriptor sets limit exceeded.");
 
+	// Check if inline uniform blocks are supported.
+	VkPhysicalDeviceInlineUniformBlockFeaturesEXT	iubFeatures =
+	{
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT,
+		DE_NULL,
+		VK_FALSE, VK_FALSE
+	};
+	VkPhysicalDeviceInlineUniformBlockPropertiesEXT	iubProperties =
+	{
+		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT,
+		DE_NULL,
+		0u, 0u, 0u, 0u, 0u
+	};
+	{
+		if (context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block"))
+		{
+			VkPhysicalDeviceFeatures2 features2;
+			deMemset(&features2, 0, sizeof(features2));
+			features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+			features2.pNext = &iubFeatures;
+			vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
+
+			VkPhysicalDeviceProperties2 properties2;
+			deMemset(&properties2, 0, sizeof(properties2));
+			properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+			properties2.pNext = &iubProperties;
+			vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
+		}
+	}
+
 	// Check physical device limits of per stage and per desriptor set descriptor count
 	{
 		deUint32	numPerStageSamplers			= 0;
@@ -1442,6 +1612,7 @@
 			deUint32					numSampledImages			= 0;
 			deUint32					numStorageImages			= 0;
 			deUint32					numInputAttachments			= 0;
+			deUint32					numIUBs						= 0;
 			deUint32					numTotalResources			= m_pipelineType == PIPELINE_TYPE_GRAPHICS ? 1u : 0u; // Color buffer counts as a resource.
 
 			const vector<DescriptorSp>&	bindings					= m_descriptorSets[descriptorSetIdx]->getBindings();
@@ -1450,7 +1621,28 @@
 			{
 				const deUint32 arraySize = bindings[bindingIdx]->getArraySize();
 
-				numTotalResources += arraySize;
+				// Inline uniform blocks cannot form arrays. The array size is the size of the data array in the descriptor.
+				if (bindings[bindingIdx]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
+				{
+					const InlineUniformBlockDescriptor* iub		= static_cast<InlineUniformBlockDescriptor*>(bindings[bindingIdx].get());
+					const deUint32						bytes	= iub->getSizeInBytes();
+
+					// Check inline uniform block size.
+					if (bytes > iubProperties.maxInlineUniformBlockSize)
+					{
+						std::ostringstream msg;
+						msg << "Maximum size for an inline uniform block exceeded by binding "
+							<< bindingIdx << " from set " << descriptorSetIdx;
+						TCU_THROW(NotSupportedError, msg.str().c_str());
+					}
+
+					iubTotalBytes += bytes;
+					++numTotalResources;
+				}
+				else
+				{
+					numTotalResources += arraySize;
+				}
 
 				switch (bindings[bindingIdx]->getType())
 				{
@@ -1495,6 +1687,10 @@
 						numSamplers += arraySize;
 						break;
 
+					case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
+						++numIUBs;
+						break;
+
 					default:
 						DE_FATAL("Unexpected descriptor type");
 						break;
@@ -1532,6 +1728,7 @@
 			numPerStageStorageImages	+= numStorageImages;
 			numPerStageInputAttachments	+= numInputAttachments;
 			numPerStageTotalResources	+= numTotalResources;
+			numTotalIUBs				+= numIUBs;
 		}
 
 		if (numPerStageTotalResources > limits.maxPerStageResources)
@@ -1554,6 +1751,12 @@
 
 		if (numPerStageInputAttachments > limits.maxPerStageDescriptorInputAttachments)
 			TCU_THROW(NotSupportedError, "Maximum per stage input attachment limit exceeded.");
+
+		if (numTotalIUBs > iubProperties.maxDescriptorSetInlineUniformBlocks ||
+			numTotalIUBs > iubProperties.maxPerStageDescriptorInlineUniformBlocks)
+		{
+			TCU_THROW(NotSupportedError, "Number of per stage inline uniform blocks exceeds limits.");
+		}
 	}
 
 	// Initialize all descriptors
@@ -1562,20 +1765,24 @@
 
 	// Create descriptor pool
 	{
-		vector<VkDescriptorPoolSize>		poolSizes;
+		vector<VkDescriptorPoolSize> poolSizes;
 
 		for (map<VkDescriptorType, deUint32>::iterator i = m_descriptorCounts.begin(); i != m_descriptorCounts.end(); i++)
 		{
-			const VkDescriptorPoolSize	poolSize	=
+			VkDescriptorPoolSize poolSize =
 			{
 				i->first,	// VkDescriptorType	type
 				i->second	// deUint32			descriptorCount
 			};
 
+			// Inline uniform blocks have a special meaning for descriptorCount.
+			if (poolSize.type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
+				poolSize.descriptorCount = iubTotalBytes;
+
 			poolSizes.push_back(poolSize);
 		}
 
-		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
+		VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
 		{
 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
 			DE_NULL,											// const void*					pNext
@@ -1585,6 +1792,16 @@
 			poolSizes.data(),									// const VkDescriptorPoolSize*	pPoolSizes
 		};
 
+		// Include information about inline uniform blocks if needed.
+		VkDescriptorPoolInlineUniformBlockCreateInfoEXT iubPoolCreateInfo =
+		{
+			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT,
+			DE_NULL,
+			numTotalIUBs
+		};
+		if (numTotalIUBs > 0)
+			descriptorPoolCreateInfo.pNext = &iubPoolCreateInfo;
+
 		descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo);
 	}
 
@@ -1593,11 +1810,11 @@
 		for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
 		{
 			vector<VkDescriptorSetLayoutBinding>	layoutBindings;
-			const vector<DescriptorSp>&				bindings	= m_descriptorSets[descriptorSetIdx]->getBindings();
+			const vector<DescriptorSp>&				bindings		= m_descriptorSets[descriptorSetIdx]->getBindings();
 
 			for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
 			{
-				const VkDescriptorSetLayoutBinding	layoutBinding	=
+				VkDescriptorSetLayoutBinding layoutBinding =
 				{
 					(deUint32)bindingIdx,					// deUint32				binding
 					bindings[bindingIdx]->getType(),		// VkDescriptorType		descriptorType
@@ -1606,6 +1823,13 @@
 					DE_NULL									// const VkSampler*		pImmutableSamplers
 				};
 
+				// Inline uniform blocks have a special meaning for descriptorCount.
+				if (layoutBinding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
+				{
+					const InlineUniformBlockDescriptor* iub = static_cast<InlineUniformBlockDescriptor*>(bindings[bindingIdx].get());
+					layoutBinding.descriptorCount = iub->getSizeInBytes();
+				}
+
 				layoutBindings.push_back(layoutBinding);
 			}
 
@@ -1996,7 +2220,8 @@
 		m_resultBuffer->invalidate(context);
 
 		// Verify result data
-		if (m_resultBuffer->getData()[0] == 1)
+		const auto data = m_resultBuffer->getData();
+		if (data[0] == 1)
 			return tcu::TestStatus::pass("Pass");
 		else
 			return tcu::TestStatus::fail("Data validation failed");
@@ -2622,6 +2847,51 @@
 		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_2", "", commands));
 	}
 
+	if (pipelineType == PIPELINE_TYPE_GRAPHICS)
+	{
+		// Similar to the previous one, but adding inline uniform blocks to the mix.
+		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
+		InlineUniformBlockDescriptor*	iub0					(new InlineUniformBlockDescriptor(4u, 0u, 4u));
+		InlineUniformBlockDescriptor*	iub1					(new InlineUniformBlockDescriptor(4u, 0u, 1u));
+		InputAttachmentDescriptor*		inputAttachment0		(new InputAttachmentDescriptor());
+		InputAttachmentDescriptor*		inputAttachment1		(new InputAttachmentDescriptor());
+		CombinedImageSamplerDescriptor*	combinedImageSampler0	(new CombinedImageSamplerDescriptor());
+		CombinedImageSamplerDescriptor*	combinedImageSampler1	(new CombinedImageSamplerDescriptor());
+		UniformTexelBufferDescriptor*	uniformTexelBuffer0		(new UniformTexelBufferDescriptor(5u, 0u, 5u));
+		UniformTexelBufferDescriptor*	uniformTexelBuffer1		(new UniformTexelBufferDescriptor(3u, 1u, 1u));
+
+		commands->addDescriptor(DescriptorSp(iub0), 0u);					// Set 0, binding 0
+		commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u);	// Set 0, binding 1
+		commands->addDescriptor(DescriptorSp(inputAttachment0), 0u);		// Set 0, binding 2
+		commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u);		// Set 0, binding 3
+		commands->addDescriptor(DescriptorSp(iub1), 1u);					// Set 1, binding 0
+		commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u);	// Set 1, binding 1
+		commands->addDescriptor(DescriptorSp(inputAttachment1), 1u);		// Set 1, binding 2
+		commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u);		// Set 1, binding 3
+
+		// iub0.data[0..2] to iub1.data[1..3]
+		commands->copyDescriptor(0u, 0u, 0u,	// from
+								 1u, 0u, 1u,	// to
+								 3u);			// num descriptors
+
+		// uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
+		commands->copyDescriptor(0u, 3u, 1u,	// from
+								 1u, 3u, 0u,	// to
+								 3u);			// num descriptors
+
+		// inputAttachment0 to inputAttachment1
+		commands->copyDescriptor(0u, 2u,	// from
+								 1u, 2u);	// to
+
+		// combinedImageSampler0 to combinedImageSampler1
+		commands->copyDescriptor(0u, 1u,	// from
+								 1u, 1u);	// to
+
+		commands->addResultBuffer();
+
+		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_3", "", commands));
+	}
+
 	// Mixture of descriptors using descriptor arrays
 	{
 		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
@@ -2660,6 +2930,54 @@
 
 		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array0", "", commands));
 	}
+
+	// Similar to the previous one but including inline uniform blocks.
+	{
+		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
+		InlineUniformBlockDescriptor*	iub0					(new InlineUniformBlockDescriptor(4u, 0u, 1u));
+		InlineUniformBlockDescriptor*	iub1					(new InlineUniformBlockDescriptor(4u, 0u, 4u));
+		CombinedImageSamplerDescriptor*	combinedImageSampler0	(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
+		CombinedImageSamplerDescriptor*	combinedImageSampler1	(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
+		CombinedImageSamplerDescriptor*	combinedImageSampler2	(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
+		StorageImageDescriptor*			storageImage0			(new StorageImageDescriptor(5u, 0u, 5u));
+		StorageImageDescriptor*			storageImage1			(new StorageImageDescriptor(3u, 0u, 0u));
+		StorageBufferDescriptor*		storageBuffer0			(new StorageBufferDescriptor(2u, 0u, 1u));
+		StorageBufferDescriptor*		storageBuffer1			(new StorageBufferDescriptor(3u, 0u, 3u));
+
+		commands->addDescriptor(DescriptorSp(iub0), 0u);					// Set 0, binding 0
+		commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u);	// Set 0, binding 1
+		commands->addDescriptor(DescriptorSp(storageImage0), 0u);			// Set 0, binding 2
+		commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u);	// Set 0, binding 3
+		commands->addDescriptor(DescriptorSp(storageBuffer0), 0u);			// Set 0, binding 4
+		commands->addDescriptor(DescriptorSp(storageBuffer1), 0u);			// Set 0, binding 5
+		commands->addDescriptor(DescriptorSp(combinedImageSampler2), 0u);	// Set 0, binding 6
+		commands->addDescriptor(DescriptorSp(iub1), 1u);					// Set 1, binding 0
+		commands->addDescriptor(DescriptorSp(storageImage1), 1u);			// Set 1, binding 1
+
+		// iub1.data[0..2] to iub0.data[1..3]
+		commands->copyDescriptor(1u, 0u, 0u,	// from
+								 0u, 0u, 1u,	// to
+								 3u);			// num descriptors
+
+		// combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
+		commands->copyDescriptor(0u, 1u, 1u,	// from
+								 0u, 3u, 2u,	// to
+								 2u);			// num descriptors
+
+		// storageImage0[2..4] to storageImage1[0..2]
+		commands->copyDescriptor(0u, 2u, 2u,	// from
+								 1u, 1u, 0u,	// to
+								 3u);			// num descriptors
+
+		// storageBuffer1[1..2] to storageBuffer0[0..1]
+		commands->copyDescriptor(0u, 5u, 1u,	// from
+								 0u, 4u, 0u,	// to
+								 2u);			// num descriptors
+
+		commands->addResultBuffer();
+
+		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array1", "", commands));
+	}
 }
 
 } // anonymous
@@ -2673,6 +2991,7 @@
 
 	// Compute tests
 	addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, computeGroup, "uniform_buffer", PIPELINE_TYPE_COMPUTE);
+	addDescriptorCopyTests<InlineUniformBlockDescriptor>(testCtx, computeGroup, "inline_uniform_block", PIPELINE_TYPE_COMPUTE);
 	addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, computeGroup, "storage_buffer", PIPELINE_TYPE_COMPUTE);
 	addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, computeGroup, "combined_image_sampler", PIPELINE_TYPE_COMPUTE);
 	addDescriptorCopyTests<StorageImageDescriptor>(testCtx, computeGroup, "storage_image", PIPELINE_TYPE_COMPUTE);
@@ -2686,6 +3005,7 @@
 
 	// Graphics tests
 	addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, graphicsGroup, "uniform_buffer", PIPELINE_TYPE_GRAPHICS);
+	addDescriptorCopyTests<InlineUniformBlockDescriptor>(testCtx, graphicsGroup, "inline_uniform_block", PIPELINE_TYPE_GRAPHICS);
 	addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, graphicsGroup, "storage_buffer", PIPELINE_TYPE_GRAPHICS);
 	addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, graphicsGroup, "combined_image_sampler", PIPELINE_TYPE_GRAPHICS);
 	addDescriptorCopyTests<StorageImageDescriptor>(testCtx, graphicsGroup, "storage_image", PIPELINE_TYPE_GRAPHICS);
diff --git a/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorSetRandomTests.cpp b/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorSetRandomTests.cpp
index 8be1206..5f91777 100644
--- a/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorSetRandomTests.cpp
+++ b/external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorSetRandomTests.cpp
@@ -114,39 +114,6 @@
 	VkFlags allPipelineStages;
 };
 
-static void getNeededFeatures(const Context&									context,
-							  VkPhysicalDeviceFeatures2&						features,
-							  VkPhysicalDeviceInlineUniformBlockFeaturesEXT&	inlineUniformFeatures,
-							  VkPhysicalDeviceDescriptorIndexingFeaturesEXT&	indexingFeatures)
-{
-	deMemset(&inlineUniformFeatures, 0, sizeof(inlineUniformFeatures));
-	inlineUniformFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
-
-	deMemset(&indexingFeatures, 0, sizeof(indexingFeatures));
-	indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
-
-	deMemset(&features, 0, sizeof(features));
-	features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
-
-	bool descriptorIndexing		= context.isDeviceFunctionalitySupported("VK_EXT_descriptor_indexing");
-	bool uniformBlock			= context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block");
-	if (descriptorIndexing && uniformBlock)
-	{
-		indexingFeatures.pNext = &inlineUniformFeatures;
-		features.pNext = &indexingFeatures;
-	}
-	else if (descriptorIndexing)
-	{
-		features.pNext = &indexingFeatures;
-	}
-	else if (uniformBlock)
-	{
-		features.pNext = &inlineUniformFeatures;
-	}
-
-	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features);
-}
-
 class RandomLayout
 {
 public:
@@ -160,7 +127,7 @@
 
 	// These three are indexed by [set][binding]
 	vector<vector<VkDescriptorSetLayoutBinding> > layoutBindings;
-	vector<vector<VkDescriptorBindingFlagsEXT> > layoutBindingFlags;
+	vector<vector<VkDescriptorBindingFlags> > layoutBindingFlags;
 	vector<vector<deUint32> > arraySizes;
 	// size of the variable descriptor (last) binding in each set
 	vector<deUint32> variableDescriptorSizes;
@@ -213,18 +180,15 @@
 
 void DescriptorSetRandomTestCase::checkSupport(Context& context) const
 {
+	// Get needed properties.
 	VkPhysicalDeviceInlineUniformBlockPropertiesEXT inlineUniformProperties;
 	deMemset(&inlineUniformProperties, 0, sizeof(inlineUniformProperties));
 	inlineUniformProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT;
 
-	VkPhysicalDeviceRayTracingPropertiesNV rayTracingProperties;
-	deMemset(&rayTracingProperties, 0, sizeof(rayTracingProperties));
-	rayTracingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV;
-
 	VkPhysicalDeviceProperties2 properties;
 	deMemset(&properties, 0, sizeof(properties));
 	properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
-	void ** pNextTail = &properties.pNext;
+	void** pNextTail = &properties.pNext;
 
 	if (context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block"))
 	{
@@ -232,29 +196,25 @@
 		pNextTail = &inlineUniformProperties.pNext;
 	}
 
-	if (context.isDeviceFunctionalitySupported("VK_NV_ray_tracing"))
-	{
-		*pNextTail = &rayTracingProperties;
-		pNextTail = &rayTracingProperties.pNext;
-	}
 	*pNextTail = NULL;
 
 	context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
 
-	VkPhysicalDeviceFeatures2 features;
-	VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures;
-	VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures;
-	getNeededFeatures(context, features, inlineUniformFeatures, indexingFeatures);
+	// Get needed features.
+	auto features				= context.getDeviceFeatures2();
+	auto indexingFeatures		= context.getDescriptorIndexingFeatures();
+	auto inlineUniformFeatures	= context.getInlineUniformBlockFeaturesEXT();
 
+	// Check needed properties and features
 	if (m_data.stage == STAGE_VERTEX && !features.features.vertexPipelineStoresAndAtomics)
 	{
-		return TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
+		TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
 	}
-	else if (m_data.stage == STAGE_RAYGEN &&
-		!context.isDeviceFunctionalitySupported("VK_NV_ray_tracing"))
+	else if (m_data.stage == STAGE_RAYGEN)
 	{
-		return TCU_THROW(NotSupportedError, "Ray tracing is not supported");
+		context.requireDeviceFunctionality("VK_NV_ray_tracing");
 	}
+
 	if ((m_data.indexType == INDEX_TYPE_PUSHCONSTANT ||
 		 m_data.indexType == INDEX_TYPE_DEPENDENT ||
 		 m_data.indexType == INDEX_TYPE_RUNTIME_SIZE) &&
@@ -353,7 +313,7 @@
 	for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
 	{
 		vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
-		vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
+		vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
 		vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
 		int numBindings = randRange(&rnd, minBindings, maxBindings);
 
@@ -364,7 +324,7 @@
 		}
 
 		bindings = vector<VkDescriptorSetLayoutBinding>(numBindings);
-		bindingsFlags = vector<VkDescriptorBindingFlagsEXT>(numBindings);
+		bindingsFlags = vector<VkDescriptorBindingFlags>(numBindings);
 		arraySizes = vector<deUint32>(numBindings);
 	}
 
@@ -520,7 +480,7 @@
 	for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
 	{
 		vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
-		vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
+		vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
 		vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
 
 		// Choose a variable descriptor count size. If the feature is not supported, we'll just
@@ -533,7 +493,7 @@
 			randRange(&rnd, 1,4) == 1) // 1 in 4 chance
 		{
 
-			bindingsFlags[bindings.size()-1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
+			bindingsFlags[bindings.size()-1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
 			variableDescriptorSizes[s] = randRange(&rnd, 0,bindings[bindings.size()-1].descriptorCount);
 			if (bindings[bindings.size()-1].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
 			{
@@ -557,7 +517,7 @@
 	for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
 	{
 		vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
-		vector<VkDescriptorBindingFlagsEXT> bindingsFlags = randomLayout.layoutBindingFlags[s];
+		vector<VkDescriptorBindingFlags> bindingsFlags = randomLayout.layoutBindingFlags[s];
 		vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
 		vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
 
@@ -620,7 +580,7 @@
 					// Don't access descriptors past the end of the allocated range for
 					// variable descriptor count
 					if (b == bindings.size() - 1 &&
-						(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT))
+						(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))
 					{
 						if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
 						{
@@ -853,14 +813,16 @@
 
 tcu::TestStatus DescriptorSetRandomTestInstance::iterate (void)
 {
-	const DeviceInterface&	vk						= m_context.getDeviceInterface();
-	const VkDevice			device					= m_context.getDevice();
-	Allocator&				allocator				= m_context.getDefaultAllocator();
+	const InstanceInterface&	vki					= m_context.getInstanceInterface();
+	const DeviceInterface&		vk					= m_context.getDeviceInterface();
+	const VkDevice				device				= m_context.getDevice();
+	const VkPhysicalDevice		physicalDevice		= m_context.getPhysicalDevice();
+	Allocator&					allocator			= m_context.getDefaultAllocator();
 
 	RandomLayout randomLayout(m_data.numDescriptorSets);
 	generateRandomLayout(randomLayout, m_data);
 
-
+	// Get needed properties.
 	VkPhysicalDeviceProperties2 properties;
 	deMemset(&properties, 0, sizeof(properties));
 	properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
@@ -874,14 +836,12 @@
 		properties.pNext = &rayTracingProperties;
 	}
 
-	m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties);
+	vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
 
-	VkPhysicalDeviceFeatures2 features;
-	VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures;
-	VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures;
-	getNeededFeatures(m_context, features, inlineUniformFeatures, indexingFeatures);
-
-	m_context.getInstanceInterface().getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &features);
+	// Get needed features.
+	auto descriptorIndexingSupported	= m_context.isDeviceFunctionalitySupported("VK_EXT_descriptor_indexing");
+	auto indexingFeatures				= m_context.getDescriptorIndexingFeatures();
+	auto inlineUniformFeatures			= m_context.getInlineUniformBlockFeaturesEXT();
 
 	deRandom rnd;
 	deRandom_init(&rnd, m_data.seed);
@@ -910,7 +870,7 @@
 	for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
 	{
 		vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
-		vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
+		vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
 		vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
 
 		VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
@@ -922,7 +882,8 @@
 			numDescriptors += binding.descriptorCount;
 
 			// Randomly choose some bindings to use update-after-bind, if it is supported
-			if (m_data.uab == UPDATE_AFTER_BIND_ENABLED &&
+			if (descriptorIndexingSupported &&
+				m_data.uab == UPDATE_AFTER_BIND_ENABLED &&
 				randRange(&rnd, 1, 8) == 1 && // 1 in 8 chance
 				(binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER			|| indexingFeatures.descriptorBindingUniformBufferUpdateAfterBind) &&
 				(binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE				|| indexingFeatures.descriptorBindingStorageImageUpdateAfterBind) &&
@@ -934,31 +895,31 @@
 				(binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) &&
 				(binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
 			{
-				bindingsFlags[b] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT;
+				bindingsFlags[b] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
 				layoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
 				poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
 			}
 
 			if (!indexingFeatures.descriptorBindingVariableDescriptorCount)
 			{
-				bindingsFlags[b] &= ~VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
+				bindingsFlags[b] &= ~VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
 			}
 		}
 
 		// Create a layout and allocate a descriptor set for it.
 
-		const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT bindingFlagsInfo =
+		const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo =
 		{
 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT,	// VkStructureType						sType;
 			DE_NULL,																// const void*							pNext;
 			(deUint32)bindings.size(),												// uint32_t								bindingCount;
-			bindings.empty() ? DE_NULL : bindingsFlags.data(),						// const VkDescriptorBindingFlagsEXT*	pBindingFlags;
+			bindings.empty() ? DE_NULL : bindingsFlags.data(),						// const VkDescriptorBindingFlags*	pBindingFlags;
 		};
 
 		const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
 		{
 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-			&bindingFlagsInfo,
+			(descriptorIndexingSupported ? &bindingFlagsInfo : DE_NULL),
 
 			layoutCreateFlags,
 			(deUint32)bindings.size(),
@@ -994,9 +955,9 @@
 		descriptorPools[s] = poolBuilder.build(vk, device, poolCreateFlags, 1u,
 											   m_data.maxInlineUniformBlocks ? &inlineUniformBlockPoolCreateInfo : DE_NULL);
 
-		VkDescriptorSetVariableDescriptorCountAllocateInfoEXT variableCountInfo =
+		VkDescriptorSetVariableDescriptorCountAllocateInfo variableCountInfo =
 		{
-			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT,	// VkStructureType	sType;
+			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,		// VkStructureType	sType;
 			DE_NULL,																		// const void*		pNext;
 			0,																				// uint32_t			descriptorSetCount;
 			DE_NULL,																		// const uint32_t*	pDescriptorCounts;
@@ -1004,7 +965,7 @@
 
 		const void *pNext = DE_NULL;
 		if (bindings.size() > 0 &&
-			bindingsFlags[bindings.size()-1] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)
+			bindingsFlags[bindings.size()-1] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)
 		{
 			variableCountInfo.descriptorSetCount = 1;
 			variableCountInfo.pDescriptorCounts = &variableDescriptorSizes[s];
@@ -1362,7 +1323,7 @@
 	for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
 	{
 		vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
-		vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
+		vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
 		vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
 		vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
 
@@ -1389,13 +1350,13 @@
 			// Construct the declaration for the binding
 			if (binding.descriptorCount > 0)
 			{
-				bool updateAfterBind = !!(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT);
+				bool updateAfterBind = !!(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT);
 				for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement)
 				{
 					// Don't access descriptors past the end of the allocated range for
 					// variable descriptor count
 					if (b == bindings.size() - 1 &&
-						(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT))
+						(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))
 					{
 						if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
 						{
@@ -1450,7 +1411,7 @@
 
 					if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
 					{
-						VkWriteDescriptorSetInlineUniformBlockEXT inlineUniformBlock =
+						VkWriteDescriptorSetInlineUniformBlockEXT iuBlock =
 						{
 							VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT,	// VkStructureType	sType;
 							DE_NULL,															// const void*		pNext;
@@ -1458,7 +1419,7 @@
 							&descriptorNumber[descriptor],										// const void*		pData;
 						};
 
-						inlineInfoVec[vecIndex] = inlineUniformBlock;
+						inlineInfoVec[vecIndex] = iuBlock;
 						w.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy"
 						w.pNext = &inlineInfoVec[vecIndex];
 						w.descriptorCount = sizeof(deUint32);
diff --git a/external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp b/external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp
index 7de0907..e479adb 100644
--- a/external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp
+++ b/external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp
@@ -7634,7 +7634,7 @@
 	if (!hasViewOffset)
 		return 0u;
 
-	if (!context.getTexelBufferAlignmentFeatures().texelBufferAlignment)
+	if (!context.getTexelBufferAlignmentFeaturesEXT().texelBufferAlignment)
 		return (deUint32)context.getDeviceProperties().limits.minTexelBufferOffsetAlignment;
 
 	vk::VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT alignmentProperties;
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp b/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
index cb9d664..64510d1 100644
--- a/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
+++ b/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
@@ -609,7 +609,7 @@
 //! Primitives partially outside the clip volume, but depth clipped with explicit depth clip control
 tcu::TestStatus testPrimitivesDepthClip (Context& context, const VkPrimitiveTopology topology)
 {
-	if (!context.getDepthClipEnableFeatures().depthClipEnable)
+	if (!context.getDepthClipEnableFeaturesEXT().depthClipEnable)
 		throw tcu::NotSupportedError("VK_EXT_depth_clip_enable not supported");
 
 	std::vector<VulkanShader> shaders;
diff --git a/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp b/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
index 93e079b..1bf24d2 100644
--- a/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
+++ b/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
@@ -636,7 +636,7 @@
 	const VkDevice			device					= m_context.getDevice();
 	Allocator&				allocator				= m_context.getDefaultAllocator();
 	MemoryRequirement		memoryDeviceAddress		= m_data.storageClass == SC_PHYSICAL_STORAGE_BUFFER &&
-														m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ? MemoryRequirement::DeviceAddress : MemoryRequirement::Any;
+													  m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ? MemoryRequirement::DeviceAddress : MemoryRequirement::Any;
 	qpTestResult			finalres				= QP_TEST_RESULT_PASS;
 	tcu::TestLog&			log						= m_context.getTestContext().getLog();
 
@@ -846,9 +846,9 @@
 		{
 			const bool useKHR = m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address");
 
-			VkBufferDeviceAddressInfoKHR info =
+			VkBufferDeviceAddressInfo info =
 			{
-				VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType	 sType;
+				VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,		// VkStructureType	 sType;
 				DE_NULL,											// const void*		 pNext;
 				0,													// VkBuffer			buffer
 			};
@@ -858,7 +858,7 @@
 				info.buffer = **buffers[i];
 				VkDeviceAddress addr;
 				if (useKHR)
-					addr = vk.getBufferDeviceAddressKHR(device, &info);
+					addr = vk.getBufferDeviceAddress(device, &info);
 				else
 					addr = vk.getBufferDeviceAddressEXT(device, &info);
 				addrsInMemory[i] = addr;
diff --git a/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawTests.cpp b/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawTests.cpp
index 5cf344f..352e964 100644
--- a/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawTests.cpp
+++ b/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawTests.cpp
@@ -306,18 +306,18 @@
 			}
 			case DRAW_COMMAND_TYPE_DRAW_INDIRECT_COUNT:
 			{
-				m_vk.cmdDrawIndirectCountKHR(	cmdBuffer,
-												m_indirectBuffer->object(), indirectOffset,
-												m_indirectCountBuffer->object(), 0, 3,
-												sizeof(vk::VkDrawIndirectCommand));
+				m_vk.cmdDrawIndirectCount(	cmdBuffer,
+											m_indirectBuffer->object(), indirectOffset,
+											m_indirectCountBuffer->object(), 0, 3,
+											sizeof(vk::VkDrawIndirectCommand));
 				break;
 			}
 			case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT_COUNT:
 			{
-				m_vk.cmdDrawIndexedIndirectCountKHR(cmdBuffer,
-													m_indirectBuffer->object(), indexedIndirectOffset,
-													m_indirectCountBuffer->object(), 0, 3,
-													sizeof(vk::VkDrawIndexedIndirectCommand));
+				m_vk.cmdDrawIndexedIndirectCount(cmdBuffer,
+												 m_indirectBuffer->object(), indexedIndirectOffset,
+												 m_indirectCountBuffer->object(), 0, 3,
+												 sizeof(vk::VkDrawIndexedIndirectCommand));
 				break;
 			}
 			default: DE_ASSERT(false);
diff --git a/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.cpp b/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.cpp
index feb5099..4afc648 100644
--- a/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.cpp
@@ -38,7 +38,7 @@
 
 	if (data.conditionInherited)
 	{
-		const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& conditionalRenderingFeatures = context.getConditionalRenderingFeatures();
+		const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& conditionalRenderingFeatures = context.getConditionalRenderingFeaturesEXT();
 		if (!conditionalRenderingFeatures.inheritedConditionalRendering)
 		{
 			TCU_THROW(NotSupportedError, "Device does not support inherited conditional rendering");
diff --git a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.cpp b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.cpp
index 8977aff..bfec8b2 100644
--- a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.cpp
+++ b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.cpp
@@ -560,30 +560,30 @@
 		}
 	};
 
-	const VkDescriptorBindingFlagsEXT	bindingFlagUpdateAfterBind =
-		m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT : 0;
+	const VkDescriptorBindingFlags	bindingFlagUpdateAfterBind =
+		m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0;
 
-	const VkDescriptorBindingFlagsEXT bindingFlagsExt[] =
+	const VkDescriptorBindingFlags bindingFlags[] =
 	{
-		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | bindingFlagUpdateAfterBind,
-		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | bindingFlagUpdateAfterBind
+		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind,
+		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind
 	};
 
-	const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT	bindingCreateInfoExt =
+	const VkDescriptorSetLayoutBindingFlagsCreateInfo	bindingCreateInfo =
 	{
-		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT,
+		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
 		DE_NULL,
 		optional ? 2u : 1u,	// bindingCount
-		bindingFlagsExt,	// pBindingFlags
+		bindingFlags,		// pBindingFlags
 	};
 
 	const VkDescriptorSetLayoutCreateFlags	layoutCreateFlags =
-		m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT : 0;
+		m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT : 0;
 
 	const VkDescriptorSetLayoutCreateInfo	layoutCreateInfo =
 	{
 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-		&bindingCreateInfoExt,	// pNext
+		&bindingCreateInfo,		// pNext
 		layoutCreateFlags,		// flags
 		optional ? 2u : 1u,		// bindingCount
 		bindings,				// pBindings
@@ -594,7 +594,7 @@
 
 Move<VkDescriptorPool>	CommonDescriptorInstance::createDescriptorPool (deUint32							descriptorCount) const
 {
-	const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT : 0;
+	const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
 
 	DescriptorPoolBuilder builder;
 
diff --git a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.hpp b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.hpp
index c8a59c1..00709c8 100644
--- a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.hpp
+++ b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.hpp
@@ -191,26 +191,26 @@
 
 class DeviceProperties
 {
-	VkPhysicalDeviceDescriptorIndexingFeaturesEXT		m_descriptorIndexingFeatures;
+	VkPhysicalDeviceDescriptorIndexingFeatures			m_descriptorIndexingFeatures;
 	VkPhysicalDeviceFeatures2							m_features2;
 
-	VkPhysicalDeviceDescriptorIndexingPropertiesEXT		m_descriptorIndexingProperties;
+	VkPhysicalDeviceDescriptorIndexingProperties		m_descriptorIndexingProperties;
 	VkPhysicalDeviceProperties2							m_properties2;
 
 public:
 	DeviceProperties (const DeviceProperties& src);
 	DeviceProperties (const vkt::Context& testContext);
 
-	inline const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&		descriptorIndexingFeatures	(void) const;
+	inline const VkPhysicalDeviceDescriptorIndexingFeatures&		descriptorIndexingFeatures	(void) const;
 	inline const VkPhysicalDeviceProperties&						physicalDeviceProperties	(void) const;
-	inline const VkPhysicalDeviceDescriptorIndexingPropertiesEXT&	descriptorIndexingProperties(void) const;
+	inline const VkPhysicalDeviceDescriptorIndexingProperties&		descriptorIndexingProperties(void) const;
 	inline const VkPhysicalDeviceFeatures&							physicalDeviceFeatures		(void) const;
 
 	deUint32 computeMaxPerStageDescriptorCount	(VkDescriptorType	descriptorType,
 												 bool				enableUpdateAfterBind) const;
 };
 
-inline const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& DeviceProperties::descriptorIndexingFeatures (void) const
+inline const VkPhysicalDeviceDescriptorIndexingFeatures& DeviceProperties::descriptorIndexingFeatures (void) const
 {
 	return m_descriptorIndexingFeatures;
 }
@@ -220,7 +220,7 @@
 	return m_properties2.properties;
 }
 
-inline const VkPhysicalDeviceDescriptorIndexingPropertiesEXT& DeviceProperties::descriptorIndexingProperties (void) const
+inline const VkPhysicalDeviceDescriptorIndexingProperties& DeviceProperties::descriptorIndexingProperties (void) const
 {
 	return m_descriptorIndexingProperties;
 }
diff --git a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTestsUtils.cpp b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTestsUtils.cpp
index 0e71de9..ca7b675 100644
--- a/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTestsUtils.cpp
+++ b/external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTestsUtils.cpp
@@ -667,7 +667,7 @@
 	const InstanceInterface& interface = testContext.getInstanceInterface();
 
 	deMemset(&m_descriptorIndexingFeatures, 0, sizeof(m_descriptorIndexingFeatures));
-	m_descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
+	m_descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
 	m_descriptorIndexingFeatures.pNext = DE_NULL;
 
 	deMemset(&m_features2, 0, sizeof(m_features2));
@@ -677,7 +677,7 @@
 	interface.getPhysicalDeviceFeatures2(device, &m_features2);
 
 	deMemset(&m_descriptorIndexingProperties, 0, sizeof(m_descriptorIndexingProperties));
-	m_descriptorIndexingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
+	m_descriptorIndexingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
 	m_descriptorIndexingProperties.pNext = DE_NULL;
 
 	deMemset(&m_properties2, 0, sizeof(m_properties2));
@@ -690,8 +690,8 @@
 deUint32 DeviceProperties::computeMaxPerStageDescriptorCount	(VkDescriptorType	descriptorType,
 																 bool				enableUpdateAfterBind) const
 {
-	const VkPhysicalDeviceDescriptorIndexingPropertiesEXT&		descriptorProps = descriptorIndexingProperties();
-	const VkPhysicalDeviceProperties&							deviceProps = physicalDeviceProperties();
+	const VkPhysicalDeviceDescriptorIndexingProperties&		descriptorProps = descriptorIndexingProperties();
+	const VkPhysicalDeviceProperties&						deviceProps = physicalDeviceProperties();
 
 	deUint32		result					= 0;
 	deUint32		samplers				= 0;
diff --git a/external/vulkancts/modules/vulkan/device_group/vktDeviceGroupRendering.cpp b/external/vulkancts/modules/vulkan/device_group/vktDeviceGroupRendering.cpp
index 48c0000..3f0940a 100644
--- a/external/vulkancts/modules/vulkan/device_group/vktDeviceGroupRendering.cpp
+++ b/external/vulkancts/modules/vulkan/device_group/vktDeviceGroupRendering.cpp
@@ -54,6 +54,8 @@
 
 #include "rrRenderer.hpp"
 
+#include <sstream>
+
 namespace vkt
 {
 namespace DeviceGroup
@@ -70,11 +72,11 @@
 //Device group test modes
 enum TestModeType
 {
-	TEST_MODE_SFR			= 1 << 0,			//!< Split frame remdering
+	TEST_MODE_SFR			= 1 << 0,			//!< Split frame rendering
 	TEST_MODE_AFR			= 1 << 1,			//!< Alternate frame rendering
 	TEST_MODE_HOSTMEMORY	= 1 << 2,			//!< Use host memory for rendertarget
 	TEST_MODE_DEDICATED		= 1 << 3,			//!< Use dedicated allocations
-	TEST_MODE_PEER_FETCH	= 1 << 4,			//!< Peer vertex attributes from peer memroy
+	TEST_MODE_PEER_FETCH	= 1 << 4,			//!< Peer vertex attributes from peer memory
 	TEST_MODE_TESSELLATION	= 1 << 5,			//!< Generate a tessellated sphere instead of triangle
 	TEST_MODE_LINEFILL		= 1 << 6,			//!< Draw polygon edges as line segments
 };
@@ -240,15 +242,24 @@
 	}
 
 	{
-		const tcu::CommandLine&								cmdLine = m_context.getTestContext().getCommandLine();
-		const vector<VkPhysicalDeviceGroupProperties>		properties = enumeratePhysicalDeviceGroups(instanceInterface, m_context.getInstance());
-		if ((size_t)cmdLine.getVKDeviceGroupId() > properties.size())
-			TCU_THROW(TestError, "Invalid device group index.");
+		const tcu::CommandLine&								cmdLine		= m_context.getTestContext().getCommandLine();
+		const vector<vk::VkPhysicalDeviceGroupProperties>	properties	= enumeratePhysicalDeviceGroups(instanceInterface, m_context.getInstance());
+		const int											kGroupId	= cmdLine.getVKDeviceGroupId();
+		const int											kGroupIndex	= kGroupId - 1;
+		const int											kDevId		= cmdLine.getVKDeviceId();
+		const int											kDevIndex	= kDevId - 1;
 
-		m_physicalDeviceCount = properties[cmdLine.getVKDeviceGroupId() - 1].physicalDeviceCount;
+		if (kGroupId < 1 || static_cast<size_t>(kGroupId) > properties.size())
+		{
+			std::ostringstream msg;
+			msg << "Invalid device group id " << kGroupId << " (only " << properties.size() << " device groups found)";
+			TCU_THROW(NotSupportedError, msg.str());
+		}
+
+		m_physicalDeviceCount = properties[kGroupIndex].physicalDeviceCount;
 		for (deUint32 idx = 0; idx < m_physicalDeviceCount; idx++)
 		{
-			m_physicalDevices.push_back(properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices[idx]);
+			m_physicalDevices.push_back(properties[kGroupIndex].physicalDevices[idx]);
 		}
 
 		if (m_usePeerFetch && m_physicalDeviceCount < 2)
@@ -274,13 +285,20 @@
 		{
 			VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,					//stype
 			DE_NULL,															//pNext
-			properties[cmdLine.getVKDeviceGroupId() - 1].physicalDeviceCount,	//physicalDeviceCount
-			properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices		//physicalDevices
+			properties[kGroupIndex].physicalDeviceCount,	//physicalDeviceCount
+			properties[kGroupIndex].physicalDevices		//physicalDevices
 		};
 
-		VkPhysicalDevice			physicalDevice			= properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices[(size_t)(cmdLine.getVKDeviceId() - 1)];
+		if (kDevId < 1 || static_cast<deUint32>(kDevId) > m_physicalDeviceCount)
+		{
+			std::ostringstream msg;
+			msg << "Device id " << kDevId << " invalid for group " << kGroupId << " (group " << kGroupId << " has " << m_physicalDeviceCount << " devices)";
+			TCU_THROW(NotSupportedError, msg.str());
+		}
+
+		VkPhysicalDevice			physicalDevice			= properties[kGroupIndex].physicalDevices[kDevIndex];
 		VkPhysicalDeviceFeatures	enabledDeviceFeatures	= getPhysicalDeviceFeatures(instanceInterface, physicalDevice);
-		m_subsetAllocation									= properties[cmdLine.getVKDeviceGroupId() - 1].subsetAllocation;
+		m_subsetAllocation									= properties[kGroupIndex].subsetAllocation;
 
 		if (m_drawTessellatedSphere & static_cast<bool>(!enabledDeviceFeatures.tessellationShader))
 			TCU_THROW(NotSupportedError, "Tessellation is not supported.");
diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp
index d938af2..f11c511 100644
--- a/external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp
+++ b/external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp
@@ -500,9 +500,9 @@
 			case DRAW_TYPE_SEQUENTIAL:
 			{
 				if (m_testIndirectCountExt)
-					m_vk.cmdDrawIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
-												 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-												 m_strideInBuffer);
+					m_vk.cmdDrawIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
+											  m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+											  m_strideInBuffer);
 				else
 					m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
 				break;
@@ -510,9 +510,9 @@
 			case DRAW_TYPE_INDEXED:
 			{
 				if (m_testIndirectCountExt)
-					m_vk.cmdDrawIndexedIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
-														m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-														m_strideInBuffer);
+					m_vk.cmdDrawIndexedIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
+													 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+													 m_strideInBuffer);
 				else
 					m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
 				break;
@@ -530,9 +530,9 @@
 				case DRAW_TYPE_SEQUENTIAL:
 				{
 					if (m_testIndirectCountExt)
-						m_vk.cmdDrawIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
-													 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-													 m_strideInBuffer);
+						m_vk.cmdDrawIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
+												  m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+												  m_strideInBuffer);
 					else
 						m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer, 1u, 0u);
 					break;
@@ -540,9 +540,9 @@
 				case DRAW_TYPE_INDEXED:
 				{
 					if (m_testIndirectCountExt)
-						m_vk.cmdDrawIndexedIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
-															m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-															m_strideInBuffer);
+						m_vk.cmdDrawIndexedIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
+														 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+														 m_strideInBuffer);
 					else
 						m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer, 1u, 0u);
 					break;
@@ -815,9 +815,9 @@
 			case DRAW_TYPE_SEQUENTIAL:
 			{
 				if (m_testIndirectCountExt)
-					m_vk.cmdDrawIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
-												 m_indirectCountBuffer->object(), m_offsetInCountBuffer,
-												 m_drawCount + m_indirectCountExtDrawPadding, m_strideInBuffer);
+					m_vk.cmdDrawIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
+											  m_indirectCountBuffer->object(), m_offsetInCountBuffer,
+											  m_drawCount + m_indirectCountExtDrawPadding, m_strideInBuffer);
 				else
 					m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
 				break;
@@ -825,9 +825,9 @@
 			case DRAW_TYPE_INDEXED:
 			{
 				if (m_testIndirectCountExt)
-					m_vk.cmdDrawIndexedIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
-														m_indirectCountBuffer->object(), m_offsetInCountBuffer,
-														m_drawCount + m_indirectCountExtDrawPadding, m_strideInBuffer);
+					m_vk.cmdDrawIndexedIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer,
+													 m_indirectCountBuffer->object(), m_offsetInCountBuffer,
+													 m_drawCount + m_indirectCountExtDrawPadding, m_strideInBuffer);
 				else
 					m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
 				break;
@@ -845,9 +845,9 @@
 				case DRAW_TYPE_SEQUENTIAL:
 				{
 					if (m_testIndirectCountExt)
-						m_vk.cmdDrawIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
-													 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-													 m_strideInBuffer);
+						m_vk.cmdDrawIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
+												  m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+												  m_strideInBuffer);
 					else
 						m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer, 1u, 0u);
 					break;
@@ -855,9 +855,9 @@
 				case DRAW_TYPE_INDEXED:
 				{
 					if (m_testIndirectCountExt)
-						m_vk.cmdDrawIndexedIndirectCountKHR(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
-															m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
-															m_strideInBuffer);
+						m_vk.cmdDrawIndexedIndirectCount(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer,
+														 m_indirectCountBuffer->object(), m_offsetInCountBuffer, m_drawCount + m_indirectCountExtDrawPadding,
+														 m_strideInBuffer);
 					else
 						m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer + drawNdx*m_strideInBuffer, 1u, 0u);
 					break;
diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
index d4a75cf..f0df4a2 100644
--- a/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
+++ b/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
@@ -292,7 +292,7 @@
 		{
 			context.requireDeviceFunctionality("VK_EXT_vertex_attribute_divisor");
 
-			const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& vertexAttributeDivisorFeatures = context.getVertexAttributeDivisorFeatures();
+			const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& vertexAttributeDivisorFeatures = context.getVertexAttributeDivisorFeaturesEXT();
 
 			if (m_params.attribDivisor != 1 && !vertexAttributeDivisorFeatures.vertexAttributeInstanceRateDivisor)
 				TCU_THROW(NotSupportedError, "Implementation does not support vertexAttributeInstanceRateDivisor");
diff --git a/external/vulkancts/modules/vulkan/fragment_shader_interlock/vktFragmentShaderInterlockBasic.cpp b/external/vulkancts/modules/vulkan/fragment_shader_interlock/vktFragmentShaderInterlockBasic.cpp
index 1a53551..cd215af 100644
--- a/external/vulkancts/modules/vulkan/fragment_shader_interlock/vktFragmentShaderInterlockBasic.cpp
+++ b/external/vulkancts/modules/vulkan/fragment_shader_interlock/vktFragmentShaderInterlockBasic.cpp
@@ -154,19 +154,19 @@
 	context.requireDeviceFunctionality("VK_EXT_fragment_shader_interlock");
 
 	if ((m_data.interlock == INT_SAMPLE_ORDERED || m_data.interlock == INT_SAMPLE_UNORDERED) &&
-		!context.getFragmentShaderInterlockFeatures().fragmentShaderSampleInterlock)
+		!context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderSampleInterlock)
 	{
 		TCU_THROW(NotSupportedError, "Fragment shader sample interlock not supported");
 	}
 
 	if ((m_data.interlock == INT_PIXEL_ORDERED || m_data.interlock == INT_PIXEL_UNORDERED) &&
-		!context.getFragmentShaderInterlockFeatures().fragmentShaderPixelInterlock)
+		!context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderPixelInterlock)
 	{
 		TCU_THROW(NotSupportedError, "Fragment shader pixel interlock not supported");
 	}
 
 	if ((m_data.interlock == INT_SHADING_RATE_ORDERED || m_data.interlock == INT_SHADING_RATE_UNORDERED) &&
-		!context.getFragmentShaderInterlockFeatures().fragmentShaderShadingRateInterlock)
+		!context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderShadingRateInterlock)
 	{
 		TCU_THROW(NotSupportedError, "Fragment shader shading rate interlock not supported");
 	}
diff --git a/external/vulkancts/modules/vulkan/image/CMakeLists.txt b/external/vulkancts/modules/vulkan/image/CMakeLists.txt
index 8845883..19ba98c 100644
--- a/external/vulkancts/modules/vulkan/image/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/image/CMakeLists.txt
@@ -5,6 +5,8 @@
 	vktImageTests.hpp
 	vktImageTestsUtil.cpp
 	vktImageTestsUtil.hpp
+	vktImageAstcDecodeModeTests.cpp
+	vktImageAstcDecodeModeTests.hpp
 	vktImageAtomicOperationTests.cpp
 	vktImageAtomicOperationTests.hpp
 	vktImageLoadStoreTests.cpp
@@ -25,6 +27,8 @@
 	vktImageLoadStoreUtil.hpp
 	vktImageTranscodingSupportTests.cpp
 	vktImageTranscodingSupportTests.hpp
+	vktImageMisalignedCubeTests.cpp
+	vktImageMisalignedCubeTests.hpp
 	)
 
 set(DEQP_VK_IMAGE_LIBS
diff --git a/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.cpp
new file mode 100644
index 0000000..fac4db3
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.cpp
@@ -0,0 +1,574 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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  vktImageAstcDecodeModeTests.cpp
+ * \brief Astc decode mode tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktImageAstcDecodeModeTests.hpp"
+#include "vktImageLoadStoreUtil.hpp"
+
+#include "vktTestCaseUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+
+#include "tcuTextureUtil.hpp"
+#include "tcuTexture.hpp"
+#include "tcuCompressedTexture.hpp"
+#include "tcuImageCompare.hpp"
+
+#include "deRandom.hpp"
+#include <vector>
+
+using namespace vk;
+namespace vkt
+{
+namespace image
+{
+namespace
+{
+using std::string;
+using std::vector;
+using tcu::TestContext;
+using tcu::TestStatus;
+using tcu::UVec3;
+using tcu::IVec3;
+using tcu::CompressedTexFormat;
+using tcu::CompressedTexture;
+using de::MovePtr;
+using de::SharedPtr;
+using de::Random;
+
+struct TestParameters
+{
+	ImageType			imageType;
+	UVec3				imageSize;
+
+	VkFormat			testedFormat;
+	deBool				testedIsUnorm;
+	VkFormat			testedDecodeMode;
+	VkImageUsageFlags	testedImageUsage;
+
+	VkFormat			resultFormat;
+	VkImageUsageFlags	resultImageUsage;
+};
+
+class BasicComputeTestInstance : public TestInstance
+{
+public:
+					BasicComputeTestInstance	(Context&					context,
+												 const TestParameters&		parameters);
+
+	TestStatus		iterate						(void);
+
+protected:
+
+	void			generateData				(deUint8*		toFill,
+												 const size_t	size,
+												 const VkFormat format,
+												 const deUint32 layer,
+												 const deUint32 level);
+
+protected:
+
+	const TestParameters	m_parameters;
+};
+
+BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
+	: TestInstance	(context)
+	, m_parameters	(parameters)
+{
+}
+
+TestStatus BasicComputeTestInstance::iterate (void)
+{
+	Allocator&						allocator			= m_context.getDefaultAllocator();
+	const DeviceInterface&			vk					= m_context.getDeviceInterface();
+	const VkDevice					device				= m_context.getDevice();
+	const VkQueue					queue				= m_context.getUniversalQueue();
+	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
+	const VkImageType				imageType			= mapImageType(m_parameters.imageType);
+	const VkExtent3D				extentCompressed	= makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize));
+	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
+	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+	const Unique<VkShaderModule>	shaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
+
+	const VkImageCreateInfo compressedImageInfo =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
+		DE_NULL,												// const void*				pNext;
+		VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
+		VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,		// VkImageCreateFlags		flags;
+		imageType,												// VkImageType				imageType;
+		m_parameters.testedFormat,								// VkFormat					format;
+		extentCompressed,										// VkExtent3D				extent;
+		1u,														// deUint32					mipLevels;
+		1u,														// deUint32					arrayLayers;
+		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
+		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
+		VK_IMAGE_USAGE_SAMPLED_BIT |
+		VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage;
+		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
+		0u,														// deUint32					queueFamilyIndexCount;
+		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
+	};
+
+	const VkImageCreateInfo resultImageInfo =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
+		DE_NULL,												// const void*				pNext;
+		0u,														// VkImageCreateFlags		flags;
+		imageType,												// VkImageType				imageType;
+		m_parameters.resultFormat,								// VkFormat					format;
+		extentCompressed,										// VkExtent3D				extent;
+		1u,														// deUint32					mipLevels;
+		1u,														// deUint32					arrayLayers;
+		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
+		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
+		VK_IMAGE_USAGE_SAMPLED_BIT |
+		VK_IMAGE_USAGE_STORAGE_BIT |
+		VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+		VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage;
+		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
+		0u,														// deUint32					queueFamilyIndexCount;
+		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
+	};
+
+	// create images
+	Image							testedImage				(vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
+	Image							referenceImage			(vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
+	Image							resultImage				(vk, device, allocator, resultImageInfo, MemoryRequirement::Any);
+
+	// create image views
+	const VkImageViewType			imageViewType			(mapImageViewType(m_parameters.imageType));
+	VkImageSubresourceRange			subresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
+	VkFormat						viewFormat				= m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
+
+	VkImageViewASTCDecodeModeEXT decodeMode =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
+		DE_NULL,
+		m_parameters.testedDecodeMode
+	};
+
+	const VkImageViewCreateInfo imageViewParams =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+		&decodeMode,									// const void*				pNext;
+		0u,												// VkImageViewCreateFlags	flags;
+		testedImage.get(),								// VkImage					image;
+		imageViewType,									// VkImageViewType			viewType;
+		viewFormat,										// VkFormat					format;
+		makeComponentMappingRGBA(),						// VkComponentMapping		components;
+		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
+	};
+
+	Move<VkImageView>				testedView				= createImageView(vk, device, &imageViewParams);
+	Move<VkImageView>				referenceView			= makeImageView(vk, device, referenceImage.get(), imageViewType, viewFormat, subresourceRange);
+	Move<VkImageView>				resultView				= makeImageView(vk, device, resultImage.get(), imageViewType, m_parameters.resultFormat,
+																makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, resultImageInfo.extent.depth, 0u, resultImageInfo.arrayLayers));
+
+	Move<VkDescriptorSetLayout>		descriptorSetLayout		= DescriptorSetLayoutBuilder()
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
+																.build(vk, device);
+	Move<VkDescriptorPool>			descriptorPool			= DescriptorPoolBuilder()
+																.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
+																.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
+																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, resultImageInfo.arrayLayers)
+																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, resultImageInfo.arrayLayers);
+
+	Move<VkDescriptorSet>			descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
+	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
+	const Unique<VkPipeline>		pipeline				(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
+
+	const VkDeviceSize				bufferSizeCompresed		= getCompressedImageSizeInBytes(m_parameters.testedFormat, m_parameters.imageSize);
+	const VkDeviceSize				bufferSizeUncompressed	= getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), m_parameters.resultFormat);
+	VkBufferCreateInfo				compressedBufferCI		= makeBufferCreateInfo(bufferSizeCompresed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+	VkBufferCreateInfo				uncompressedBufferCI	= makeBufferCreateInfo(bufferSizeUncompressed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+	Buffer							inBuffer				(vk, device, allocator, compressedBufferCI, MemoryRequirement::HostVisible);
+	Buffer							resultBuffer			(vk, device, allocator, uncompressedBufferCI, MemoryRequirement::HostVisible);
+	Move<VkSampler>					sampler;
+
+	// generate data for compressed image and copy it to in buffer
+	{
+		vector<deUint8> generatedData;
+		generatedData.resize(static_cast<size_t>(bufferSizeCompresed));
+		generateData(generatedData.data(), generatedData.size(), m_parameters.testedFormat, 0u, 0u);
+
+		const Allocation& alloc = inBuffer.getAllocation();
+		deMemcpy(alloc.getHostPtr(), generatedData.data(), generatedData.size());
+		flushAlloc(vk, device, alloc);
+	}
+
+	{
+		const VkSamplerCreateInfo createInfo	=
+		{
+			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			//VkStructureType		sType;
+			DE_NULL,										//const void*			pNext;
+			0u,												//VkSamplerCreateFlags	flags;
+			VK_FILTER_NEAREST,								//VkFilter				magFilter;
+			VK_FILTER_NEAREST,								//VkFilter				minFilter;
+			VK_SAMPLER_MIPMAP_MODE_NEAREST,					//VkSamplerMipmapMode	mipmapMode;
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeU;
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeV;
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeW;
+			0.0f,											//float					mipLodBias;
+			VK_FALSE,										//VkBool32				anisotropyEnable;
+			1.0f,											//float					maxAnisotropy;
+			VK_FALSE,										//VkBool32				compareEnable;
+			VK_COMPARE_OP_EQUAL,							//VkCompareOp			compareOp;
+			0.0f,											//float					minLod;
+			1.0f,											//float					maxLod;
+			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		//VkBorderColor			borderColor;
+			VK_FALSE,										//VkBool32				unnormalizedCoordinates;
+		};
+		sampler = createSampler(vk, device, &createInfo);
+	}
+
+	VkDescriptorImageInfo descriptorImageInfos[] =
+	{
+		makeDescriptorImageInfo(*sampler,	*testedView,	VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
+		makeDescriptorImageInfo(*sampler,	*referenceView,	VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
+		makeDescriptorImageInfo(DE_NULL,	*resultView,	VK_IMAGE_LAYOUT_GENERAL),
+	};
+	DescriptorSetUpdateBuilder()
+		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[0])
+		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[1])
+		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[2])
+		.update(vk, device);
+
+	beginCommandBuffer(vk, *cmdBuffer);
+	{
+		// copy input buffer to tested and reference images
+		{
+			Image* inImages[] = { &testedImage, &referenceImage };
+			for (Image* image : inImages)
+			{
+				const VkImageMemoryBarrier preCopyImageBarrier = makeImageMemoryBarrier(
+					0u, VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					image->get(), subresourceRange);
+
+				const VkBufferMemoryBarrier flushHostCopyBarrier = makeBufferMemoryBarrier(
+					VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+					inBuffer.get(), 0ull, bufferSizeCompresed);
+
+				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+					(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &flushHostCopyBarrier, 1u, &preCopyImageBarrier);
+
+				const VkBufferImageCopy copyRegion =
+				{
+					0ull,																			//VkDeviceSize				bufferOffset;
+					0u,																				//deUint32					bufferRowLength;
+					0u,																				//deUint32					bufferImageHeight;
+					makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),				//VkImageSubresourceLayers	imageSubresource;
+					makeOffset3D(0, 0, 0),															//VkOffset3D				imageOffset;
+					extentCompressed,																//VkExtent3D				imageExtent;
+				};
+
+				vk.cmdCopyBufferToImage(*cmdBuffer, inBuffer.get(), image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
+			}
+		}
+
+		// bind pipeline and descriptors
+		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
+
+		{
+			const VkImageMemoryBarrier preShaderImageBarriers[] =
+			{
+				makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+					testedImage.get(), subresourceRange),
+
+				makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+					referenceImage.get(), subresourceRange),
+
+				makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
+					resultImage.get(), subresourceRange)
+			};
+
+			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
+				(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
+				DE_LENGTH_OF_ARRAY(preShaderImageBarriers), preShaderImageBarriers);
+		}
+
+		vk.cmdDispatch(*cmdBuffer, extentCompressed.width, extentCompressed.height, extentCompressed.depth);
+
+		{
+			const VkImageMemoryBarrier postShaderImageBarriers[] =
+			{
+				makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+					VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+					resultImage.get(), subresourceRange)
+			};
+
+			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+				(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
+				DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers);
+		}
+
+		const VkBufferImageCopy copyRegion =
+		{
+			0ull,																//	VkDeviceSize				bufferOffset;
+			0u,																	//	deUint32					bufferRowLength;
+			0u,																	//	deUint32					bufferImageHeight;
+			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	//	VkImageSubresourceLayers	imageSubresource;
+			makeOffset3D(0, 0, 0),												//	VkOffset3D					imageOffset;
+			resultImageInfo.extent,												//	VkExtent3D					imageExtent;
+		};
+		vk.cmdCopyImageToBuffer(*cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, &copyRegion);
+
+		{
+			const VkBufferMemoryBarrier postCopyBufferBarrier[] =
+			{
+				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
+					resultBuffer.get(), 0ull, bufferSizeUncompressed),
+			};
+
+			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
+				(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBufferBarrier), postCopyBufferBarrier,
+				0u, (const VkImageMemoryBarrier*)DE_NULL);
+		}
+	}
+	endCommandBuffer(vk, *cmdBuffer);
+	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
+
+	const Allocation& resultAlloc = resultBuffer.getAllocation();
+	invalidateAlloc(vk, device, resultAlloc);
+
+	// verification is done in shader - here we just check if one of pixels has wrong value
+	const size_t	numBytes		= static_cast<size_t>(bufferSizeUncompressed);
+	deUint8*		result		= static_cast<deUint8*>(resultAlloc.getHostPtr());
+	for (size_t i = 0 ; i < numBytes ; i += 4)
+	{
+		// expected result should be around 128 (if reference is same as tested mode then we return 0.5)
+		if ((result[i] < 100) || (result[i] > 150))
+			return TestStatus::fail("Fail");
+	}
+
+	return TestStatus::pass("Pass");
+}
+
+void BasicComputeTestInstance::generateData (deUint8*		toFill,
+											 const size_t	size,
+											 const VkFormat format,
+											 const deUint32 layer,
+											 const deUint32 level)
+{
+	// Random data
+	deUint32*	start32		= reinterpret_cast<deUint32*>(toFill);
+	size_t		sizeToRnd32	= size / sizeof(deUint32);
+	deUint32	seed		= (layer << 24) ^ (level << 16) ^ static_cast<deUint32>(format);
+	Random		rnd			(seed);
+
+	for (size_t i = 0; i < sizeToRnd32; i++)
+		start32[i] = rnd.getUint32();
+}
+
+class AstcDecodeModeCase : public TestCase
+{
+public:
+					AstcDecodeModeCase	(TestContext&			testCtx,
+										 const std::string&		name,
+										 const std::string&		desc,
+										 const TestParameters&	parameters);
+	virtual void	checkSupport		(Context&				context) const;
+	void			initPrograms		(SourceCollections&		programCollection) const;
+	TestInstance*	createInstance		(Context&				context) const;
+
+protected:
+
+	const TestParameters m_parameters;
+};
+
+AstcDecodeModeCase::AstcDecodeModeCase (TestContext&			testCtx,
+										const std::string&		name,
+										const std::string&		desc,
+										const TestParameters&	parameters)
+	: TestCase		(testCtx, name, desc)
+	, m_parameters	(parameters)
+{
+}
+
+void AstcDecodeModeCase::checkSupport (Context& context) const
+{
+	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
+	const InstanceInterface&	vk				= context.getInstanceInterface();
+
+	context.requireDeviceFunctionality("VK_EXT_astc_decode_mode");
+	if (!getPhysicalDeviceFeatures(vk, physicalDevice).textureCompressionASTC_LDR)
+		TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
+
+	VkImageFormatProperties imageFormatProperties;
+	if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.testedFormat,
+												  mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
+												  m_parameters.testedImageUsage, 0u, &imageFormatProperties))
+		TCU_THROW(NotSupportedError, "Operation not supported with this image format");
+
+	if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.resultFormat,
+												  mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
+												  m_parameters.resultImageUsage, 0u, &imageFormatProperties))
+		TCU_THROW(NotSupportedError, "Operation not supported with this image format");
+
+	if ((m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
+		!context.getASTCDecodeFeaturesEXT().decodeModeSharedExponent)
+		TCU_THROW(NotSupportedError, "decodeModeSharedExponent not supported");
+
+	VkFormatProperties properties;
+	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_parameters.resultFormat, &properties);
+	if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
+		TCU_THROW(NotSupportedError, "Format storage feature not supported");
+}
+
+void AstcDecodeModeCase::initPrograms (vk::SourceCollections& programCollection) const
+{
+	DE_ASSERT(m_parameters.imageSize.x() > 0);
+	DE_ASSERT(m_parameters.imageSize.y() > 0);
+
+	VkFormat					compatibileFormat	= m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
+	tcu::TextureFormat			testedTextureFormat	= mapVkFormat(compatibileFormat);
+	VkImageViewType				imageViewType		= mapImageViewType(m_parameters.imageType);
+	string						samplerType			= getGlslSamplerType(testedTextureFormat, imageViewType);
+	const string				formatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.resultFormat));
+	const string				imageTypeStr		= getShaderImageType(mapVkFormat(m_parameters.resultFormat), m_parameters.imageType);
+
+	std::ostringstream	src;
+	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n"
+		<< "layout (binding = 0) uniform " << samplerType << " compressed_tested;\n"
+		<< "layout (binding = 1) uniform " << samplerType << " compressed_reference;\n"
+		<< "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " result;\n"
+		<< "void main (void)\n"
+		<< "{\n"
+		<< "    const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
+		<< "    const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
+		<< "    const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n"
+		<< "    vec4 tested = texture(compressed_tested, cord);\n"
+		<< "    vec4 reference = texture(compressed_reference, cord);\n";
+
+	// special case for e5b9g9r9 decode mode that was set on unorm astc formats
+	// here negative values are clamped to zero and alpha is set to 1
+	if (m_parameters.testedIsUnorm && (m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
+		src << "    reference = max(vec4(0,0,0,1), reference);\n"
+			   "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
+	else
+		src << "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
+
+	src << "    imageStore(result, pos, vec4(result_color));\n"
+		<< "}\n";
+
+	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
+}
+
+TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
+{
+	return new BasicComputeTestInstance(context, m_parameters);
+}
+
+} // anonymous ns
+
+tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx)
+{
+	struct FormatData
+	{
+		VkFormat		format;
+		std::string		name;
+		deBool			isUnorm;
+	};
+	const FormatData astcFormats[] =
+	{
+		{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,		"4x4_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,		"4x4_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,		"5x4_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,		"5x4_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,		"5x5_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,		"5x5_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,		"6x5_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,		"6x5_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,		"6x6_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,		"6x6_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,		"8x5_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,		"8x5_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,		"8x6_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,		"8x6_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,		"8x8_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,		"8x8_srgb",		DE_FALSE },
+		{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,		"10x5_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,		"10x5_srgb",	DE_FALSE },
+		{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,		"10x6_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,		"10x6_srgb",	DE_FALSE },
+		{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,		"10x8_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,		"10x8_srgb",	DE_FALSE },
+		{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,		"10x10_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,		"10x10_srgb",	DE_FALSE },
+		{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,		"12x10_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,		"12x10_srgb",	DE_FALSE },
+		{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,		"12x12_unorm",	DE_TRUE },
+		{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,		"12x12_srgb",	DE_FALSE },
+	};
+
+	struct DecodeModeData
+	{
+		VkFormat		mode;
+		std::string		name;
+	};
+	const DecodeModeData decodeModes[] =
+	{
+		{ VK_FORMAT_R16G16B16A16_SFLOAT,	"r16g16b16a16_sfloat" },
+		{ VK_FORMAT_R8G8B8A8_UNORM,			"r8g8b8a8_unorm" },
+		{ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,	"e5b9g9r9_ufloat_pack32" }
+	};
+
+	MovePtr<tcu::TestCaseGroup> astcDecodeModeTests(new tcu::TestCaseGroup(testCtx, "astc_decode_mode", "Intermediate decoding precision cases"));
+	for (const FormatData& format : astcFormats)
+	{
+		for (const DecodeModeData& mode : decodeModes)
+		{
+			const TestParameters parameters =
+			{
+				IMAGE_TYPE_2D,
+				UVec3(64u, 64u, 1u),
+				format.format,
+				format.isUnorm,
+				mode.mode,
+				VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+				VK_FORMAT_R8G8B8A8_UNORM,
+				VK_IMAGE_USAGE_STORAGE_BIT
+			};
+
+			std::string name = format.name + "_to_" + mode.name;
+			astcDecodeModeTests->addChild(new AstcDecodeModeCase(testCtx, name, "", parameters));
+		}
+	}
+
+	return astcDecodeModeTests.release();
+}
+
+} // image
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.hpp b/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.hpp
new file mode 100644
index 0000000..9932d81
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/image/vktImageAstcDecodeModeTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTIMAGEASTCDECODEMODETESTS_HPP
+#define _VKTIMAGEASTCDECODEMODETESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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  vktImageAstcDecodeModeTests.hpp
+ * \brief Astc decode mode tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace image
+{
+
+tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx);
+
+} // image
+} // vkt
+
+#endif // _VKTIMAGEASTCDECODEMODETESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/image/vktImageAtomicOperationTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageAtomicOperationTests.cpp
index 244fe05..66d9265 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageAtomicOperationTests.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageAtomicOperationTests.cpp
@@ -123,12 +123,15 @@
 	switch (op)
 	{
 		case ATOMIC_OPERATION_ADD:
-		case ATOMIC_OPERATION_MIN:
-		case ATOMIC_OPERATION_MAX:
 		case ATOMIC_OPERATION_AND:
 		case ATOMIC_OPERATION_OR:
 		case ATOMIC_OPERATION_XOR:
 			return string("(" + x + "*" + x + " + " + y + "*" + y + " + " + z + "*" + z + ")");
+		case ATOMIC_OPERATION_MIN:
+		case ATOMIC_OPERATION_MAX:
+			// multiply by (1-2*(value % 2) to make half of the data negative
+			// this will result in generating large numbers for uint formats
+			return string("((1 - 2*(" + x + " % 2)) * (" + x + "*" + x + " + " + y + "*" + y + " + " + z + "*" + z + "))");
 		case ATOMIC_OPERATION_EXCHANGE:
 		case ATOMIC_OPERATION_COMPARE_EXCHANGE:
 			return string("((" + z + "*" + toString(gridSize.x()) + " + " + x + ")*" + toString(gridSize.y()) + " + " + y + ")");
@@ -193,7 +196,10 @@
 	}
 }
 
-static deInt32 getAtomicFuncArgument (const AtomicOperation op, const IVec3& invocationID, const IVec3& gridSize)
+template <typename T>
+static T getAtomicFuncArgument (const AtomicOperation	op,
+								const IVec3&			invocationID,
+								const IVec3&			gridSize)
 {
 	const int x = invocationID.x();
 	const int y = invocationID.y();
@@ -203,12 +209,14 @@
 	{
 		// \note Fall-throughs.
 		case ATOMIC_OPERATION_ADD:
-		case ATOMIC_OPERATION_MIN:
-		case ATOMIC_OPERATION_MAX:
 		case ATOMIC_OPERATION_AND:
 		case ATOMIC_OPERATION_OR:
 		case ATOMIC_OPERATION_XOR:
 			return x*x + y*y + z*z;
+		case ATOMIC_OPERATION_MIN:
+		case ATOMIC_OPERATION_MAX:
+			// multiply half of the data by -1
+			return (1-2*(x % 2))*(x*x + y*y + z*z);
 		case ATOMIC_OPERATION_EXCHANGE:
 		case ATOMIC_OPERATION_COMPARE_EXCHANGE:
 			return (z*gridSize.x() + x)*gridSize.y() + y;
@@ -230,7 +238,8 @@
 }
 
 //! Computes the result of an atomic operation where "a" is the data operated on and "b" is the parameter to the atomic function.
-static deInt32 computeBinaryAtomicOperationResult (const AtomicOperation op, const deInt32 a, const deInt32 b)
+template <typename T>
+static T computeBinaryAtomicOperationResult (const AtomicOperation op, const T a, const T b)
 {
 	switch (op)
 	{
@@ -600,6 +609,16 @@
 	virtual void		commandsAfterCompute		   (const VkCommandBuffer	cmdBuffer) const;
 
 	virtual bool		verifyResult				   (Allocation&				outputBufferAllocation) const;
+
+protected:
+
+	template <typename T>
+	bool				isValueCorrect				   (deInt32 resultValue,
+														deInt32 x,
+														deInt32 y,
+														deInt32 z,
+														const UVec3& gridSize,
+														const IVec3 extendedGridSize) const;
 };
 
 deUint32 BinaryAtomicEndResultInstance::getOutputBufferSize (void) const
@@ -653,6 +672,7 @@
 
 bool BinaryAtomicEndResultInstance::verifyResult (Allocation& outputBufferAllocation) const
 {
+	const bool	uintFormat			= isUintFormat(mapTextureFormat(m_format));
 	const UVec3	gridSize			= getShaderGridSize(m_imageType, m_imageSize);
 	const IVec3 extendedGridSize	= IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z());
 
@@ -666,16 +686,16 @@
 
 		if (isOrderIndependentAtomicOperation(m_operation))
 		{
-			deInt32 reference = getOperationInitialValue(m_operation);
-
-			for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
+			if (uintFormat)
 			{
-				const IVec3 gid(x + i*gridSize.x(), y, z);
-				reference = computeBinaryAtomicOperationResult(m_operation, reference, getAtomicFuncArgument(m_operation, gid, extendedGridSize));
+				if (!isValueCorrect<deUint32>(resultValue, x, y, z, gridSize, extendedGridSize))
+					return false;
 			}
-
-			if (resultValue != reference)
-				return false;
+			else
+			{
+				if (!isValueCorrect<deInt32>(resultValue, x, y, z, gridSize, extendedGridSize))
+					return false;
+			}
 		}
 		else if (m_operation == ATOMIC_OPERATION_EXCHANGE)
 		{
@@ -685,7 +705,7 @@
 			for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL) && !matchFound; i++)
 			{
 				const IVec3 gid(x + i*gridSize.x(), y, z);
-				matchFound = (resultValue == getAtomicFuncArgument(m_operation, gid, extendedGridSize));
+				matchFound = (resultValue == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize));
 			}
 
 			if (!matchFound)
@@ -699,7 +719,7 @@
 			for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL) && !matchFound; i++)
 			{
 				const IVec3 gid(x + i*gridSize.x(), y, z);
-				matchFound = (resultValue == getAtomicFuncArgument(m_operation, gid, extendedGridSize));
+				matchFound = (resultValue == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize));
 			}
 
 			if (!matchFound)
@@ -711,6 +731,19 @@
 	return true;
 }
 
+template <typename T>
+bool BinaryAtomicEndResultInstance::isValueCorrect(deInt32 resultValue, deInt32 x, deInt32 y, deInt32 z, const UVec3& gridSize, const IVec3 extendedGridSize) const
+{
+	T reference = static_cast<T>(getOperationInitialValue(m_operation));
+	for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
+	{
+		const IVec3 gid(x + i*gridSize.x(), y, z);
+		T			arg = getAtomicFuncArgument<T>(m_operation, gid, extendedGridSize);
+		reference = computeBinaryAtomicOperationResult(m_operation, reference, arg);
+	}
+	return (static_cast<T>(resultValue) == reference);
+}
+
 TestInstance* BinaryAtomicEndResultCase::createInstance (Context& context) const
 {
 	return new BinaryAtomicEndResultInstance(context, m_name, m_imageType, m_imageSize, m_format, m_operation);
@@ -740,11 +773,20 @@
 
 protected:
 
+	template <typename T>
+	bool				areValuesCorrect				   (tcu::ConstPixelBufferAccess& resultBuffer,
+															deInt32 x,
+															deInt32 y,
+															deInt32 z,
+															const UVec3& gridSize,
+															const IVec3 extendedGridSize) const;
+
+	template <typename T>
 	bool				verifyRecursive					   (const deInt32			index,
-															const deInt32			valueSoFar,
+															const T					valueSoFar,
 															bool					argsUsed[NUM_INVOCATIONS_PER_PIXEL],
-															const deInt32			atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
-															const deInt32			resultValues[NUM_INVOCATIONS_PER_PIXEL]) const;
+															const T					atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
+															const T					resultValues[NUM_INVOCATIONS_PER_PIXEL]) const;
 	de::MovePtr<Image>	m_intermResultsImage;
 	Move<VkImageView>	m_intermResultsImageView;
 };
@@ -862,6 +904,7 @@
 
 bool BinaryAtomicIntermValuesInstance::verifyResult (Allocation&	outputBufferAllocation) const
 {
+	const bool	uintFormat		 = isUintFormat(mapTextureFormat(m_format));
 	const UVec3	gridSize		 = getShaderGridSize(m_imageType, m_imageSize);
 	const IVec3 extendedGridSize = IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z());
 
@@ -871,34 +914,47 @@
 	for (deInt32 y = 0; y < resultBuffer.getHeight(); y++)
 	for (deUint32 x = 0; x < gridSize.x(); x++)
 	{
-		deInt32 resultValues[NUM_INVOCATIONS_PER_PIXEL];
-		deInt32 atomicArgs[NUM_INVOCATIONS_PER_PIXEL];
-		bool	argsUsed[NUM_INVOCATIONS_PER_PIXEL];
-
-		for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
+		if (uintFormat)
 		{
-			IVec3 gid(x + i*gridSize.x(), y, z);
-
-			resultValues[i] = resultBuffer.getPixelInt(gid.x(), gid.y(), gid.z()).x();
-			atomicArgs[i]	= getAtomicFuncArgument(m_operation, gid, extendedGridSize);
-			argsUsed[i]		= false;
+			if (!areValuesCorrect<deUint32>(resultBuffer, x, y, z, gridSize, extendedGridSize))
+				return false;
 		}
-
-		// Verify that the return values form a valid sequence.
-		if (!verifyRecursive(0, getOperationInitialValue(m_operation), argsUsed, atomicArgs, resultValues))
+		else
 		{
-			return false;
+			if (!areValuesCorrect<deInt32>(resultBuffer, x, y, z, gridSize, extendedGridSize))
+				return false;
 		}
 	}
 
 	return true;
 }
 
+template <typename T>
+bool BinaryAtomicIntermValuesInstance::areValuesCorrect(tcu::ConstPixelBufferAccess& resultBuffer, deInt32 x, deInt32 y, deInt32 z, const UVec3& gridSize, const IVec3 extendedGridSize) const
+{
+	T		resultValues[NUM_INVOCATIONS_PER_PIXEL];
+	T		atomicArgs[NUM_INVOCATIONS_PER_PIXEL];
+	bool	argsUsed[NUM_INVOCATIONS_PER_PIXEL];
+
+	for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
+	{
+		IVec3 gid(x + i*gridSize.x(), y, z);
+
+		resultValues[i] = resultBuffer.getPixelInt(gid.x(), gid.y(), gid.z()).cast<T>().x();
+		atomicArgs[i]	= getAtomicFuncArgument<T>(m_operation, gid, extendedGridSize);
+		argsUsed[i]		= false;
+	}
+
+	// Verify that the return values form a valid sequence.
+	return verifyRecursive(0, static_cast<T>(getOperationInitialValue(m_operation)), argsUsed, atomicArgs, resultValues);
+}
+
+template <typename T>
 bool BinaryAtomicIntermValuesInstance::verifyRecursive (const deInt32	index,
-														const deInt32	valueSoFar,
+														const T			valueSoFar,
 														bool			argsUsed[NUM_INVOCATIONS_PER_PIXEL],
-														const deInt32	atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
-														const deInt32	resultValues[NUM_INVOCATIONS_PER_PIXEL]) const
+														const T			atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
+														const T			resultValues[NUM_INVOCATIONS_PER_PIXEL]) const
 {
 	if (index >= static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL))
 		return true;
diff --git a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
index 6f5a7b8..8f696bb 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
@@ -2882,10 +2882,12 @@
 			!physicalDeviceFeatures.textureCompressionASTC_LDR)
 			TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
 
-		if ((m_parameters.uncompressedImageUsage & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
-			isStorageImageExtendedFormat(m_parameters.formatUncompressed) &&
-			!physicalDeviceFeatures.shaderStorageImageExtendedFormats)
-			TCU_THROW(NotSupportedError, "Storage view format requires shaderStorageImageExtended");
+		if (m_parameters.uncompressedImageUsage & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)
+		{
+			const VkFormatProperties p = getPhysicalDeviceFormatProperties(vk, physicalDevice, m_parameters.formatUncompressed);
+			if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
+				TCU_THROW(NotSupportedError, "Storage view format not supported");
+		}
 	}
 }
 
diff --git a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp
index 44eff95..081e6c7 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp
@@ -652,7 +652,7 @@
 {
 	if (m_minalign)
 	{
-		if (!context.getTexelBufferAlignmentFeatures().texelBufferAlignment)
+		if (!context.getTexelBufferAlignmentFeaturesEXT().texelBufferAlignment)
 			return (deUint32)context.getDeviceProperties().limits.minTexelBufferOffsetAlignment;
 
 		VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT alignmentProperties;
diff --git a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.cpp b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.cpp
index c5cbd40..a92f45c 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.cpp
@@ -112,40 +112,6 @@
 		return alignment;
 }
 
-bool isStorageImageExtendedFormat (const vk::VkFormat format)
-{
-	switch (format)
-	{
-		case VK_FORMAT_R32G32_SFLOAT:
-		case VK_FORMAT_R32G32_SINT:
-		case VK_FORMAT_R32G32_UINT:
-		case VK_FORMAT_R16G16B16A16_UNORM:
-		case VK_FORMAT_R16G16B16A16_SNORM:
-		case VK_FORMAT_R16G16_SFLOAT:
-		case VK_FORMAT_R16G16_UNORM:
-		case VK_FORMAT_R16G16_SNORM:
-		case VK_FORMAT_R16G16_SINT:
-		case VK_FORMAT_R16G16_UINT:
-		case VK_FORMAT_R16_SFLOAT:
-		case VK_FORMAT_R16_UNORM:
-		case VK_FORMAT_R16_SNORM:
-		case VK_FORMAT_R16_SINT:
-		case VK_FORMAT_R16_UINT:
-		case VK_FORMAT_R8G8_UNORM:
-		case VK_FORMAT_R8G8_SNORM:
-		case VK_FORMAT_R8G8_SINT:
-		case VK_FORMAT_R8G8_UINT:
-		case VK_FORMAT_R8_UNORM:
-		case VK_FORMAT_R8_SNORM:
-		case VK_FORMAT_R8_SINT:
-		case VK_FORMAT_R8_UINT:
-			return true;
-
-		default:
-			return false;
-	}
-}
-
 bool isRepresentableIntegerValue (tcu::Vector<deInt64, 4> value, tcu::TextureFormat format)
 {
 	const tcu::IVec4	formatBitDepths	= tcu::getTextureFormatBitDepth(format);
diff --git a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.hpp b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.hpp
index 6a941e0..24e8fd0 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.hpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageLoadStoreUtil.hpp
@@ -72,7 +72,6 @@
 ImageType				getImageTypeForSingleLayer			(const ImageType imageType);
 vk::VkImageCreateInfo	makeImageCreateInfo					(const Texture& texture, const vk::VkFormat format, const vk::VkImageUsageFlags usage, const vk::VkImageCreateFlags flags);
 vk::VkDeviceSize		getOptimalUniformBufferChunkSize	(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, vk::VkDeviceSize minimumRequiredChunkSizeBytes);
-bool					isStorageImageExtendedFormat		(const vk::VkFormat format);
 bool					isRepresentableIntegerValue			(const tcu::Vector<deInt64, 4> value, tcu::TextureFormat format);
 
 } // image
diff --git a/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.cpp
new file mode 100644
index 0000000..bbe97a7
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.cpp
@@ -0,0 +1,390 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 The Android Open Source Project
+ *
+ * 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 Cube image with misaligned baseArrayLayer tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktImageMisalignedCubeTests.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktImageTestsUtil.hpp"
+#include "vktImageTexture.hpp"
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkPrograms.hpp"
+#include "vkMemUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkTypeUtil.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deStringUtil.hpp"
+#include "deMath.h"
+
+#include <string>
+
+using namespace vk;
+
+namespace vkt
+{
+namespace image
+{
+namespace
+{
+
+inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec3& size, const VkFormat format)
+{
+	const VkImageUsageFlags	usage		= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+	const VkImageCreateInfo	imageParams	=
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//  VkStructureType			sType;
+		DE_NULL,								//  const void*				pNext;
+		VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,	//  VkImageCreateFlags		flags;
+		VK_IMAGE_TYPE_2D,						//  VkImageType				imageType;
+		format,									//  VkFormat				format;
+		makeExtent3D(size.x(), size.y(), 1u),	//  VkExtent3D				extent;
+		1u,										//  deUint32				mipLevels;
+		(deUint32)size.z(),						//  deUint32				arrayLayers;
+		VK_SAMPLE_COUNT_1_BIT,					//  VkSampleCountFlagBits	samples;
+		VK_IMAGE_TILING_OPTIMAL,				//  VkImageTiling			tiling;
+		usage,									//  VkImageUsageFlags		usage;
+		VK_SHARING_MODE_EXCLUSIVE,				//  VkSharingMode			sharingMode;
+		0u,										//  deUint32				queueFamilyIndexCount;
+		DE_NULL,								//  const deUint32*			pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,				//  VkImageLayout			initialLayout;
+	};
+
+	return imageParams;
+}
+
+void fillBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize offset, const VkDeviceSize size, const VkFormat format, const tcu::Vec4& color)
+{
+	const tcu::TextureFormat	textureFormat		= mapVkFormat(format);
+	const deUint32				colorPixelSize		= static_cast<deUint32>(tcu::getPixelSize(textureFormat));
+	tcu::TextureLevel			colorPixelBuffer	(textureFormat, 1, 1);
+	tcu::PixelBufferAccess		colorPixel			(colorPixelBuffer);
+
+	colorPixel.setPixel(color, 0, 0);
+
+	const deUint8*	src		= static_cast<deUint8*>(colorPixel.getDataPtr());
+	deUint8*		dstBase	= static_cast<deUint8*>(alloc.getHostPtr());
+	deUint8*		dst		= &dstBase[offset];
+
+	for (deUint32 pixelPos = 0; pixelPos < size; pixelPos += colorPixelSize)
+		deMemcpy(&dst[pixelPos], src, colorPixelSize);
+
+	flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset() + offset, size);
+}
+
+VkBufferImageCopy makeBufferImageCopy (const vk::VkDeviceSize&				bufferOffset,
+									   const vk::VkImageSubresourceLayers&	imageSubresource,
+									   const vk::VkOffset3D&				imageOffset,
+									   const vk::VkExtent3D&				imageExtent)
+{
+	const VkBufferImageCopy copyParams =
+	{
+		bufferOffset,								//	VkDeviceSize				bufferOffset;
+		0u,											//	deUint32					bufferRowLength;
+		0u,											//	deUint32					bufferImageHeight;
+		imageSubresource,							//	VkImageSubresourceLayers	imageSubresource;
+		imageOffset,								//	VkOffset3D					imageOffset;
+		imageExtent,								//	VkExtent3D					imageExtent;
+	};
+	return copyParams;
+}
+
+//! Interpret the memory as IVec4
+inline tcu::Vec4 readVec4 (const void* const data, const deUint32 ndx)
+{
+	const float* const	p	= reinterpret_cast<const float*>(data);
+	const deUint32		ofs	= 4 * ndx;
+
+	return tcu::Vec4(p[ofs+0], p[ofs+1], p[ofs+2], p[ofs+3]);
+}
+
+class MisalignedCubeTestInstance : public TestInstance
+{
+public:
+					MisalignedCubeTestInstance	(Context&			context,
+												 const tcu::IVec3&	size,
+												 const VkFormat		format);
+	tcu::TestStatus	iterate						(void);
+
+private:
+	const tcu::IVec3&	m_size;
+	const VkFormat		m_format;
+};
+
+MisalignedCubeTestInstance::MisalignedCubeTestInstance (Context& context, const tcu::IVec3& size, const VkFormat format)
+	: TestInstance	(context)
+	, m_size		(size)
+	, m_format		(format)
+{
+}
+
+tcu::TestStatus MisalignedCubeTestInstance::iterate (void)
+{
+	DE_ASSERT(de::inRange(m_size.z(), 6, 16));
+	DE_ASSERT(m_format == VK_FORMAT_R8G8B8A8_UNORM);
+
+	const DeviceInterface&			vk						= m_context.getDeviceInterface();
+	const VkDevice					device					= m_context.getDevice();
+	Allocator&						allocator				= m_context.getDefaultAllocator();
+	const VkQueue					queue					= m_context.getUniversalQueue();
+	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
+	const deUint32					numLayers				= m_size.z();
+	const deUint32					cube0LayerStart			= 0;
+	const deUint32					cube1LayerStart			= numLayers - 6u;
+	const VkDeviceSize				resultBufferSizeBytes	= 2 * 6 * 4 * sizeof(float);	// vec4[6] in shader
+	const VkExtent3D				imageExtent				= makeExtent3D(m_size.x(), m_size.y(), 1u);
+	const deUint32					pixelSize				= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(m_format)));
+	const deUint32					layerSize				= imageExtent.width * imageExtent.height * pixelSize;
+	const float						eps						= 1.0f / float(2 * 256);
+
+	const VkBufferCreateInfo		resultBufferCreateInfo	= makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+	de::MovePtr<Buffer>				resultBuffer			= de::MovePtr<Buffer>(new Buffer(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
+	const Allocation&				resultBufferAlloc		= resultBuffer->getAllocation();
+	const VkImageCreateInfo			imageCreateInfo			= makeImageCreateInfo(m_size, m_format);
+	de::MovePtr<Image>				image					= de::MovePtr<Image>(new Image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
+	const VkImageSubresourceRange	imageSubresourceRange0	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, cube0LayerStart, 6u);
+	Move<VkImageView>				imageView0				= makeImageView(vk, device, image->get(), VK_IMAGE_VIEW_TYPE_CUBE, m_format, imageSubresourceRange0);
+	const VkImageSubresourceRange	imageSubresourceRange1	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, cube1LayerStart, 6u);
+	Move<VkImageView>				imageView1				= makeImageView(vk, device, image->get(), VK_IMAGE_VIEW_TYPE_CUBE, m_format, imageSubresourceRange1);
+
+	Move<VkDescriptorSetLayout>		descriptorSetLayout		= DescriptorSetLayoutBuilder()
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
+																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
+																.build(vk, device);
+	Move<VkDescriptorPool>			descriptorPool			= DescriptorPoolBuilder()
+																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+																.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
+																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+	Move<VkDescriptorSet>			descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
+	const VkDescriptorImageInfo		descriptorImageInfo0	= makeDescriptorImageInfo(DE_NULL, *imageView0, VK_IMAGE_LAYOUT_GENERAL);
+	const VkDescriptorImageInfo		descriptorImageInfo1	= makeDescriptorImageInfo(DE_NULL, *imageView1, VK_IMAGE_LAYOUT_GENERAL);
+	const VkDescriptorBufferInfo	descriptorBufferInfo	= makeDescriptorBufferInfo(resultBuffer->get(), 0ull, resultBufferSizeBytes);
+
+	const Move<VkShaderModule>		shaderModule			= createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0);
+	const Move<VkPipelineLayout>	pipelineLayout			= makePipelineLayout(vk, device, *descriptorSetLayout);
+	const Move<VkPipeline>			pipeline				= makeComputePipeline(vk, device, *pipelineLayout, *shaderModule);
+	const Move<VkCommandPool>		cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
+	const Move<VkCommandBuffer>		cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+	const VkDeviceSize				clearBufferSize			= layerSize * numLayers;
+	const Move<VkBuffer>			clearBuffer				= makeBuffer(vk, device, clearBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+	const de::MovePtr<Allocation>	clearBufferAlloc		= bindBuffer(vk, device, allocator, *clearBuffer, MemoryRequirement::HostVisible);
+	const VkImageSubresourceRange	clearSubresRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers);
+	const VkImageMemoryBarrier		clearBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
+																					 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+																					 image->get(), clearSubresRange);
+	const VkImageMemoryBarrier		preShaderImageBarrier	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
+																					 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
+																					 image->get(), clearSubresRange);
+	const VkBufferMemoryBarrier		postShaderBarrier		= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
+																					  resultBuffer->get(), 0ull, VK_WHOLE_SIZE);
+	bool							result					= true;
+
+	DescriptorSetUpdateBuilder()
+		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo0)
+		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo1)
+		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
+		.update(vk, device);
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
+
+	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &clearBarrier);
+
+	// Clear layers with predefined values
+	for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx)
+	{
+		const float						componentValue			= float(16 * layerNdx) / 255.0f;
+		const tcu::Vec4					clearColor				= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);
+		const VkDeviceSize				bufferOffset			= layerNdx * layerSize;
+		const VkImageSubresourceLayers	imageSubresource		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layerNdx, 1u);
+		const VkBufferImageCopy			bufferImageCopyRegion	= makeBufferImageCopy(bufferOffset, imageSubresource, makeOffset3D(0u, 0u, 0u), imageExtent);
+
+		fillBuffer(vk, device, *clearBufferAlloc, bufferOffset, layerSize, m_format, clearColor);
+
+		vk.cmdCopyBufferToImage(*cmdBuffer, *clearBuffer, image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
+	}
+
+	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preShaderImageBarrier);
+
+	vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
+
+	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, DE_NULL, 1, &postShaderBarrier, 0, DE_NULL);
+
+	endCommandBuffer(vk, *cmdBuffer);
+
+	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
+
+	invalidateAlloc(vk, device, resultBufferAlloc);
+
+	// Check cube 0
+	for (deUint32 layerNdx = 0; layerNdx < 6; ++layerNdx)
+	{
+		const deUint32	layerUsed		= cube0LayerStart + layerNdx;
+		const float		componentValue	= float(16 * layerUsed) / 255.0f;
+		const tcu::Vec4	expectedColor	= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);;
+		const tcu::Vec4	resultColor		= readVec4(resultBufferAlloc.getHostPtr(), layerNdx);
+		const tcu::Vec4	delta			= expectedColor - resultColor;
+
+		if (deFloatAbs(delta.x()) > eps || deFloatAbs(delta.y()) > eps || deFloatAbs(delta.z()) > eps || deFloatAbs(delta.w()) > eps)
+			result = false;
+	}
+
+	// Check cube 1
+	for (deUint32 layerNdx = 0; layerNdx < 6; ++layerNdx)
+	{
+		const deUint32	layerUsed		= cube1LayerStart + layerNdx;
+		const float		componentValue	= float(16 * layerUsed) / 255.0f;
+		const tcu::Vec4	expectedColor	= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);;
+		const tcu::Vec4 resultColor		= readVec4(resultBufferAlloc.getHostPtr(), layerNdx + 6u);
+		const tcu::Vec4	delta			= expectedColor - resultColor;
+
+		if (deFloatAbs(delta.x()) > eps || deFloatAbs(delta.y()) > eps || deFloatAbs(delta.z()) > eps || deFloatAbs(delta.w()) > eps)
+			result = false;
+	}
+
+	if (result)
+		return tcu::TestStatus::pass("pass");
+	else
+		return tcu::TestStatus::fail("fail");
+}
+
+class MisalignedCubeTest : public TestCase
+{
+public:
+						MisalignedCubeTest	(tcu::TestContext&	testCtx,
+											 const std::string&	name,
+											 const std::string&	description,
+											 const tcu::IVec3&	size,
+											 const VkFormat		format);
+
+	void				initPrograms		(SourceCollections& programCollection) const;
+	TestInstance*		createInstance		(Context&			context) const;
+
+private:
+	const tcu::IVec3	m_size;
+	const VkFormat		m_format;
+};
+
+MisalignedCubeTest::MisalignedCubeTest (tcu::TestContext&	testCtx,
+										const std::string&	name,
+										const std::string&	description,
+										const tcu::IVec3&	size,
+										const VkFormat		format)
+	: TestCase	(testCtx, name, description)
+	, m_size	(size)
+	, m_format	(format)
+{
+}
+
+void MisalignedCubeTest::initPrograms (SourceCollections& programCollection) const
+{
+	const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
+
+	std::ostringstream src;
+	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
+		<< "\n"
+		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+		<< "layout (binding = 0, " << formatQualifierStr << ") " << "readonly uniform highp imageCube u_cubeImage0;\n"
+		<< "layout (binding = 1, " << formatQualifierStr << ") " << "readonly uniform highp imageCube u_cubeImage1;\n"
+		<< "layout (binding = 2) writeonly buffer Output\n"
+		<< "{\n"
+		<< "    vec4 cube0_color0;\n"
+		<< "    vec4 cube0_color1;\n"
+		<< "    vec4 cube0_color2;\n"
+		<< "    vec4 cube0_color3;\n"
+		<< "    vec4 cube0_color4;\n"
+		<< "    vec4 cube0_color5;\n"
+		<< "    vec4 cube1_color0;\n"
+		<< "    vec4 cube1_color1;\n"
+		<< "    vec4 cube1_color2;\n"
+		<< "    vec4 cube1_color3;\n"
+		<< "    vec4 cube1_color4;\n"
+		<< "    vec4 cube1_color5;\n"
+		<< "} sb_out;\n"
+		<< "\n"
+		<< "void main (void)\n"
+		<< "{\n"
+		<< "    sb_out.cube0_color0 = imageLoad(u_cubeImage0, ivec3(1, 1, 0));\n"
+		<< "    sb_out.cube0_color1 = imageLoad(u_cubeImage0, ivec3(1, 1, 1));\n"
+		<< "    sb_out.cube0_color2 = imageLoad(u_cubeImage0, ivec3(1, 1, 2));\n"
+		<< "    sb_out.cube0_color3 = imageLoad(u_cubeImage0, ivec3(1, 1, 3));\n"
+		<< "    sb_out.cube0_color4 = imageLoad(u_cubeImage0, ivec3(1, 1, 4));\n"
+		<< "    sb_out.cube0_color5 = imageLoad(u_cubeImage0, ivec3(1, 1, 5));\n"
+		<< "    sb_out.cube1_color0 = imageLoad(u_cubeImage1, ivec3(1, 1, 0));\n"
+		<< "    sb_out.cube1_color1 = imageLoad(u_cubeImage1, ivec3(1, 1, 1));\n"
+		<< "    sb_out.cube1_color2 = imageLoad(u_cubeImage1, ivec3(1, 1, 2));\n"
+		<< "    sb_out.cube1_color3 = imageLoad(u_cubeImage1, ivec3(1, 1, 3));\n"
+		<< "    sb_out.cube1_color4 = imageLoad(u_cubeImage1, ivec3(1, 1, 4));\n"
+		<< "    sb_out.cube1_color5 = imageLoad(u_cubeImage1, ivec3(1, 1, 5));\n"
+		<< "}\n";
+
+	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
+}
+
+TestInstance* MisalignedCubeTest::createInstance (Context& context) const
+{
+	return new MisalignedCubeTestInstance(context, m_size, m_format);
+}
+
+//! Base sizes used to generate actual imager sizes in the test.
+static const tcu::IVec3 s_baseImageSizes[] =
+{
+	tcu::IVec3(16, 16,  7),
+	tcu::IVec3(16, 16,  8),
+	tcu::IVec3(16, 16,  9),
+	tcu::IVec3(16, 16, 10),
+	tcu::IVec3(16, 16, 11),
+};
+
+} // anonymous ns
+
+tcu::TestCaseGroup* createMisalignedCubeTests (tcu::TestContext& testCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "misaligned_cube", "Cube image with misaligned baseArrayLayer test cases"));
+
+	const VkFormat	format	= VK_FORMAT_R8G8B8A8_UNORM;
+
+	for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(s_baseImageSizes); ++imageSizeNdx)
+	{
+		const tcu::IVec3	size	= s_baseImageSizes[imageSizeNdx];
+
+		testGroup->addChild(new MisalignedCubeTest(testCtx, de::toString(size.z()), "", size, format));
+	}
+
+	return testGroup.release();
+}
+
+} // image
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.hpp b/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.hpp
new file mode 100644
index 0000000..9fb303d
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/image/vktImageMisalignedCubeTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTIMAGEMISALIGNEDCUBETESTS_HPP
+#define _VKTIMAGEMISALIGNEDCUBETESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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 Cube image with misaligned baseArrayLayer tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace image
+{
+
+tcu::TestCaseGroup* createMisalignedCubeTests	(tcu::TestContext& testCtx);
+
+} // image
+} // vkt
+
+#endif // _VKTIMAGEMISALIGNEDCUBETESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/image/vktImageMutableTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageMutableTests.cpp
index 0cac4d8..6593c74 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageMutableTests.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageMutableTests.cpp
@@ -525,7 +525,7 @@
 		viewFormat
 	};
 
-	const VkImageFormatListCreateInfoKHR formatListInfo =
+	const VkImageFormatListCreateInfo formatListInfo =
 	{
 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,	// VkStructureType			sType;
 		DE_NULL,												// const void*				pNext;
@@ -1696,13 +1696,6 @@
 		break;
 	}
 
-	if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
-		isStorageImageExtendedFormat(caseDef.viewFormat) &&
-		!getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
-	{
-		TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
-	}
-
 	if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
 		TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
 
@@ -1874,39 +1867,6 @@
 	return createCustomDevice(enableValidation, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
 }
 
-deUint32 getNumQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
-{
-	deUint32	numFamilies = 0;
-
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
-
-	return numFamilies;
-}
-
-vector<deUint32> getSupportedQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
-{
-	const deUint32		numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
-	vector<deUint32>	supportedFamilyIndices;
-
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
-}
-
 struct InstanceHelper
 {
 	const vector<VkExtensionProperties>	supportedExtensions;
@@ -2023,7 +1983,7 @@
 		viewFormat
 	};
 
-	const VkImageFormatListCreateInfoKHR formatListInfo =
+	const VkImageFormatListCreateInfo formatListInfo =
 	{
 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,	// VkStructureType			sType;
 		DE_NULL,												// const void*				pNext;
@@ -2104,8 +2064,8 @@
 
 	// Check support for requested formats by swapchain surface
 	const vector<VkSurfaceFormatKHR>surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
-																						 physDevice,
-																						 *surface);
+																					 physDevice,
+																					 *surface);
 
 	const VkSurfaceFormatKHR*		surfaceFormat = DE_NULL;
 	const VkFormat*					viewFormat = DE_NULL;
diff --git a/external/vulkancts/modules/vulkan/image/vktImageTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageTests.cpp
index 58165f0..793c21d 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageTests.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageTests.cpp
@@ -31,6 +31,8 @@
 #include "vktImageAtomicOperationTests.hpp"
 #include "vktImageCompressionTranscodingSupport.hpp"
 #include "vktImageTranscodingSupportTests.hpp"
+#include "vktImageAstcDecodeModeTests.hpp"
+#include "vktImageMisalignedCubeTests.hpp"
 
 namespace vkt
 {
@@ -56,6 +58,8 @@
 	imageTests->addChild(createImageCompressionTranscodingTests(testCtx));
 	imageTests->addChild(createImageTranscodingSupportTests(testCtx));
 	imageTests->addChild(createImageExtendOperandsTests(testCtx));
+	imageTests->addChild(createImageAstcDecodeModeTests(testCtx));
+	imageTests->addChild(createMisalignedCubeTests(testCtx));
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp b/external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp
index 3ca5d03..a0449c1 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp
@@ -122,35 +122,18 @@
 {
 }
 
-// The templated functions below work with specializations of tcu::Float as class T. See "tcuFloat.hpp".
-
-// Return smallest floating point normal value preserving the existing sign bit.
-// The smallest normal value has the mantissa bits zeroed out and 1 as the exponent (tough constructBits() expects something else).
-template <class T>
-inline T SmallestFloat (T value)
-{
-	return T::constructBits(value.sign(), -(T::EXPONENT_BIAS - 1), typename T::StorageType(0u));
-}
-
-// Return the largest floating point normal value preserving the existing sign bit.
-// The largest normal value has the mantissa bits all set to 1 and the exponent set to the largest even value (see constructBits() for the details).
-template <class T>
-inline T LargestFloat (T value)
-{
-	return T::constructBits(value.sign(), T::EXPONENT_BIAS, typename T::StorageType((1<<T::MANTISSA_BITS)-1));
-}
-
 // Replace Infs and NaNs with the largest normal value.
 // Replace denormal numbers with the smallest normal value.
 // Leave the rest untouched.
+// T is a tcu::Float specialization.
 template <class T>
 void fixFloatIfNeeded(deUint8* ptr_)
 {
 	T* ptr = reinterpret_cast<T*>(ptr_);
 	if (ptr->isInf() || ptr->isNaN())
-		*ptr = LargestFloat<T>(*ptr);
+		*ptr = T::largestNormal(ptr->sign());
 	else if (ptr->isDenorm())
-		*ptr = SmallestFloat<T>(*ptr);
+		*ptr = T::smallestNormal(ptr->sign());
 }
 
 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
diff --git a/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp
index 7b44df9..8db36cb 100644
--- a/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp
+++ b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp
@@ -111,11 +111,11 @@
 	}
 }
 
-VkAttachmentReference2KHR convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask)
+VkAttachmentReference2 convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask)
 {
-	const VkAttachmentReference2KHR	attachmentReference2	=
+	const VkAttachmentReference2	attachmentReference2	=
 	{
-		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,	//  VkStructureType		sType;
+		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,		//  VkStructureType		sType;
 		DE_NULL,										//  const void*			pNext;
 		attachmentReference.attachment,					//  deUint32			attachment;
 		attachmentReference.layout,						//  VkImageLayout		layout;
@@ -125,18 +125,18 @@
 	return attachmentReference2;
 }
 
-std::vector<VkAttachmentDescription2KHR> convertAttachmentDescriptions (const std::vector<VkAttachmentDescription>& attachmentDescriptions)
+std::vector<VkAttachmentDescription2> convertAttachmentDescriptions (const std::vector<VkAttachmentDescription>& attachmentDescriptions)
 {
-	std::vector<VkAttachmentDescription2KHR>	attachmentDescriptions2;
+	std::vector<VkAttachmentDescription2>	attachmentDescriptions2;
 
 	attachmentDescriptions2.reserve(attachmentDescriptions.size());
 
 	for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx)
 	{
 		const VkAttachmentDescription&		attachmentDescription	= attachmentDescriptions[adNdx];
-		const VkAttachmentDescription2KHR	attachmentDescription2	=
+		const VkAttachmentDescription2		attachmentDescription2	=
 		{
-			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR,	//  VkStructureType					sType;
+			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,		//  VkStructureType					sType;
 			DE_NULL,										//  const void*						pNext;
 			attachmentDescription.flags,					//  VkAttachmentDescriptionFlags	flags;
 			attachmentDescription.format,					//  VkFormat						format;
@@ -327,58 +327,58 @@
 	{
 		const VkImageAspectFlags							colorAspectMask							= VK_IMAGE_ASPECT_COLOR_BIT;
 		const VkImageAspectFlags							depthStencilAspectMask					= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-		const VkAttachmentReference2KHR						colorAttachmentRef2						= convertAttachmentReference(colorAttachmentRef, colorAspectMask);
-		const VkAttachmentReference2KHR						depthStencilAttachmentRef2				= convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
-		const VkAttachmentReference2KHR						colorResolveAttachmentRef2				= convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
-		const VkAttachmentReference2KHR						depthStencilResolveAttachmentRef2		=
+		const VkAttachmentReference2						colorAttachmentRef2						= convertAttachmentReference(colorAttachmentRef, colorAspectMask);
+		const VkAttachmentReference2						depthStencilAttachmentRef2				= convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
+		const VkAttachmentReference2						colorResolveAttachmentRef2				= convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
+		const VkAttachmentReference2						depthStencilResolveAttachmentRef2		=
 		{
-			VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,			//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,				//  VkStructureType		sType;
 			DE_NULL,												//  const void*			pNext;
 			hasDepthStencilResolve ? attachmentCounter++ : 0u,		//  deUint32			attachment;
 			subpassLayoutDepthStencil,								//  VkImageLayout		layout;
 			depthStencilAspectMask									//  VkImageAspectFlags	aspectMask;
 		};
-		const VkSubpassDescriptionDepthStencilResolveKHR	subpassDescriptionDepthStencilResolve	=
+		const VkSubpassDescriptionDepthStencilResolve		subpassDescriptionDepthStencilResolve	=
 		{
-			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,	//  VkStructureType						sType;
+			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,		//  VkStructureType						sType;
 			DE_NULL,															//  const void*							pNext;
-			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,								//  VkResolveModeFlagBitsKHR			depthResolveMode;
-			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,								//  VkResolveModeFlagBitsKHR			stencilResolveMode;
+			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,									//  VkResolveModeFlagBitsKHR			depthResolveMode;
+			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,									//  VkResolveModeFlagBitsKHR			stencilResolveMode;
 			&depthStencilResolveAttachmentRef2									//  const VkAttachmentReference2KHR*	pDepthStencilResolveAttachment;
 		};
-		const VkSubpassDescription2KHR						subpassDescription2						=
+		const VkSubpassDescription2							subpassDescription2						=
 		{
-			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,				//  VkStructureType						sType;
+			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,					//  VkStructureType						sType;
 			&subpassDescriptionDepthStencilResolve,						//  const void*							pNext;
 			(VkSubpassDescriptionFlags)0,								//  VkSubpassDescriptionFlags			flags;
 			VK_PIPELINE_BIND_POINT_GRAPHICS,							//  VkPipelineBindPoint					pipelineBindPoint;
 			0u,															//  deUint32							viewMask;
 			0u,															//  deUint32							inputAttachmentCount;
-			DE_NULL,													//  const VkAttachmentReference2KHR*	pInputAttachments;
+			DE_NULL,													//  const VkAttachmentReference2*		pInputAttachments;
 			hasColor ? 1u : 0u,											//  deUint32							colorAttachmentCount;
-			hasColor ? &colorAttachmentRef2 : DE_NULL,					//  const VkAttachmentReference2KHR*	pColorAttachments;
-			hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2KHR*	pResolveAttachments;
-			hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
+			hasColor ? &colorAttachmentRef2 : DE_NULL,					//  const VkAttachmentReference2*		pColorAttachments;
+			hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2*		pResolveAttachments;
+			hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2*		pDepthStencilAttachment;
 			0u,															//  deUint32							preserveAttachmentCount;
 			DE_NULL														//  const deUint32*						pPreserveAttachments;
 		};
-		const std::vector<VkAttachmentDescription2KHR>		attachmentDescriptions2					= convertAttachmentDescriptions(attachmentDescriptions);
-		const VkRenderPassCreateInfo2KHR					renderPassInfo							=
+		const std::vector<VkAttachmentDescription2>			attachmentDescriptions2					= convertAttachmentDescriptions(attachmentDescriptions);
+		const VkRenderPassCreateInfo2						renderPassInfo							=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,	//  VkStructureType						sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,		//  VkStructureType						sType;
 			DE_NULL,											//  const void*							pNext;
 			(VkRenderPassCreateFlags)0,							//  VkRenderPassCreateFlags				flags;
 			(deUint32)attachmentDescriptions2.size(),			//  deUint32							attachmentCount;
-			&attachmentDescriptions2[0],						//  const VkAttachmentDescription2KHR*	pAttachments;
+			&attachmentDescriptions2[0],						//  const VkAttachmentDescription2*		pAttachments;
 			1u,													//  deUint32							subpassCount;
-			&subpassDescription2,								//  const VkSubpassDescription2KHR*		pSubpasses;
+			&subpassDescription2,								//  const VkSubpassDescription2*		pSubpasses;
 			0u,													//  deUint32							dependencyCount;
-			DE_NULL,											//  const VkSubpassDependency2KHR*		pDependencies;
+			DE_NULL,											//  const VkSubpassDependency2*			pDependencies;
 			0u,													//  deUint32							correlatedViewMaskCount;
 			DE_NULL												//  const deUint32*						pCorrelatedViewMasks;
 		};
 
-		return createRenderPass2KHR(vk, device, &renderPassInfo, allocationCallbacks);
+		return createRenderPass2(vk, device, &renderPassInfo, allocationCallbacks);
 	}
 	else
 	{
@@ -493,7 +493,7 @@
 		VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			//  VkPipelineStageFlags			dstStageMask;
 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			//  VkAccessFlags					srcAccessMask;
 		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			//  VkAccessFlags					dstAccessMask;
-		VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR,				//  VkDependencyFlags				dependencyFlags;
+		VK_DEPENDENCY_VIEW_LOCAL_BIT,					//  VkDependencyFlags				dependencyFlags;
 	};
 	const VkRenderPassCreateInfo	renderPassInfo				=
 	{
@@ -535,26 +535,26 @@
 	return imageParams;
 }
 
-std::vector<VkFramebufferAttachmentImageInfoKHR> makeFramebufferAttachmentImageInfos (const VkExtent2D&			renderSize,
-																					  const VkFormat*			colorFormat,
-																					  const VkImageUsageFlags	colorUsage,
-																					  const VkFormat*			dsFormat,
-																					  const VkImageUsageFlags	dsUsage,
-																					  const AspectFlags			resolveAspects,
-																					  const deUint32			inputAttachmentCount)
+std::vector<VkFramebufferAttachmentImageInfo> makeFramebufferAttachmentImageInfos (const VkExtent2D&			renderSize,
+																				   const VkFormat*				colorFormat,
+																				   const VkImageUsageFlags		colorUsage,
+																				   const VkFormat*				dsFormat,
+																				   const VkImageUsageFlags		dsUsage,
+																				   const AspectFlags			resolveAspects,
+																				   const deUint32				inputAttachmentCount)
 {
-	const bool											colorResolve					= (resolveAspects & ASPECT_COLOR) != 0;
-	const bool											depthStencilResolve				= (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
-	std::vector<VkFramebufferAttachmentImageInfoKHR>	framebufferAttachmentImageInfos;
+	const bool										colorResolve					= (resolveAspects & ASPECT_COLOR) != 0;
+	const bool										depthStencilResolve				= (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
+	std::vector<VkFramebufferAttachmentImageInfo>	framebufferAttachmentImageInfos;
 
 	DE_ASSERT(colorFormat != DE_NULL);
 	DE_ASSERT(dsFormat != DE_NULL);
 
 	if (*colorFormat != VK_FORMAT_UNDEFINED)
 	{
-		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
+		const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo		=
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
 			colorUsage,													//  VkImageUsageFlags	usage;
@@ -570,9 +570,9 @@
 
 	if (*dsFormat != VK_FORMAT_UNDEFINED)
 	{
-		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
+		const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo		=
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
 			dsUsage,													//  VkImageUsageFlags	usage;
@@ -588,9 +588,9 @@
 
 	if (colorResolve)
 	{
-		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
+		const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo		=
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
 			colorUsage,													//  VkImageUsageFlags	usage;
@@ -608,9 +608,9 @@
 
 	if (depthStencilResolve)
 	{
-		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
+		const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo		=
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
 			dsUsage,													//  VkImageUsageFlags	usage;
@@ -628,9 +628,9 @@
 
 	for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx)
 	{
-		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
+		const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo		=
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
 			colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,			//  VkImageUsageFlags	usage;
@@ -658,20 +658,20 @@
 									 const AspectFlags				resolveAspects			= ASPECT_NONE,
 									 const deUint32					inputAttachmentCount	= 0)
 {
-	const std::vector<VkFramebufferAttachmentImageInfoKHR>	framebufferAttachmentImageInfos		= makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount);
+	const std::vector<VkFramebufferAttachmentImageInfo>		framebufferAttachmentImageInfos		= makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount);
 	const deUint32											attachmentCount						= static_cast<deUint32>(framebufferAttachmentImageInfos.size());
-	const VkFramebufferAttachmentsCreateInfoKHR				framebufferAttachmentsCreateInfo	=
+	const VkFramebufferAttachmentsCreateInfo				framebufferAttachmentsCreateInfo	=
 	{
-		VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR,	//  VkStructureType								sType;
+		VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,		//  VkStructureType								sType;
 		DE_NULL,													//  const void*									pNext;
 		attachmentCount,											//  deUint32									attachmentImageInfoCount;
-		&framebufferAttachmentImageInfos[0]							//  const VkFramebufferAttachmentImageInfoKHR*	pAttachmentImageInfos;
+		&framebufferAttachmentImageInfos[0]							//  const VkFramebufferAttachmentImageInfo*		pAttachmentImageInfos;
 	};
 	const VkFramebufferCreateInfo							framebufferInfo	=
 	{
 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					//  VkStructureType				sType;
 		&framebufferAttachmentsCreateInfo,							//  const void*					pNext;
-		VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR,					//  VkFramebufferCreateFlags	flags;
+		VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,						//  VkFramebufferCreateFlags	flags;
 		renderPass,													//  VkRenderPass				renderPass;
 		attachmentCount,											//  deUint32					attachmentCount;
 		DE_NULL,													//  const VkImageView*			pAttachments;
@@ -960,7 +960,7 @@
 {
 	const InstanceInterface&								vki								= m_context.getInstanceInterface();
 	const VkPhysicalDevice									physDevice						= m_context.getPhysicalDevice();
-	const VkPhysicalDeviceImagelessFramebufferFeaturesKHR&	imagelessFramebufferFeatures	(context.getImagelessFramebufferFeatures());
+	const VkPhysicalDeviceImagelessFramebufferFeatures&		imagelessFramebufferFeatures	(context.getImagelessFramebufferFeatures());
 
 	if (imagelessFramebufferFeatures.imagelessFramebuffer == DE_FALSE)
 		TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported");
@@ -1229,9 +1229,9 @@
 
 	beginCommandBuffer(vk, *cmdBuffer);
 	{
-		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
+		const VkRenderPassAttachmentBeginInfo		renderPassAttachmentBeginInfo	=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			1u,															//  deUint32			attachmentCount;
 			&*colorAttachment											//  const VkImageView*	pAttachments;
@@ -1462,9 +1462,9 @@
 	beginCommandBuffer(vk, *cmdBuffer);
 	{
 		const VkImageView							attachments[]					= { *colorAttachment, *dsAttachment };
-		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
+		const VkRenderPassAttachmentBeginInfo		renderPassAttachmentBeginInfo	=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
 			attachments													//  const VkImageView*	pAttachments;
@@ -1665,9 +1665,9 @@
 	beginCommandBuffer(vk, *cmdBuffer);
 	{
 		const VkImageView							attachments[]					= { *colorAttachment, *colorResolveAttachment };
-		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
+		const VkRenderPassAttachmentBeginInfo		renderPassAttachmentBeginInfo	=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
 			attachments													//  const VkImageView*	pAttachments;
@@ -1753,7 +1753,7 @@
 	const InstanceInterface&							vki					= m_context.getInstanceInterface();
 	const VkPhysicalDevice								physDevice			= m_context.getPhysicalDevice();
 	VkPhysicalDeviceProperties2							deviceProperties;
-	VkPhysicalDeviceDepthStencilResolvePropertiesKHR	dsResolveProperties;
+	VkPhysicalDeviceDepthStencilResolveProperties		dsResolveProperties;
 
 	deMemset(&deviceProperties, 0, sizeof(deviceProperties));
 	deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties));
@@ -1761,7 +1761,7 @@
 	deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
 	deviceProperties.pNext = &dsResolveProperties;
 
-	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
+	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
 	dsResolveProperties.pNext = DE_NULL;
 
 	vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties);
@@ -1965,9 +1965,9 @@
 	beginCommandBuffer(vk, *cmdBuffer);
 	{
 		const VkImageView							attachments[]					= { *colorAttachment, *dsAttachment, *colorResolveAttachment, *dsResolveAttachment };
-		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
+		const VkRenderPassAttachmentBeginInfo		renderPassAttachmentBeginInfo	=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
 			attachments													//  const VkImageView*	pAttachments;
@@ -2229,9 +2229,9 @@
 	beginCommandBuffer(vk, *cmdBuffer);
 	{
 		const VkImageView							attachments[]					= { *color0Attachment, *color1Attachment };
-		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
+		const VkRenderPassAttachmentBeginInfo		renderPassAttachmentBeginInfo	=
 		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
+			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,		//  VkStructureType		sType;
 			DE_NULL,													//  const void*			pNext;
 			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
 			&attachments[0]												//  const VkImageView*	pAttachments;
diff --git a/external/vulkancts/modules/vulkan/memory/vktMemoryBindingTests.cpp b/external/vulkancts/modules/vulkan/memory/vktMemoryBindingTests.cpp
index 27815e1..15f085f 100644
--- a/external/vulkancts/modules/vulkan/memory/vktMemoryBindingTests.cpp
+++ b/external/vulkancts/modules/vulkan/memory/vktMemoryBindingTests.cpp
@@ -953,7 +953,7 @@
 	{
 		ctx.requireDeviceFunctionality("VK_KHR_bind_memory2");
 
-		if (m_params.usePriority && !ctx.getMemoryPriorityFeatures().memoryPriority)
+		if (m_params.usePriority && !ctx.getMemoryPriorityFeaturesEXT().memoryPriority)
 			TCU_THROW(NotSupportedError, "VK_EXT_memory_priority Not supported");
 	}
 
diff --git a/external/vulkancts/modules/vulkan/memory_model/CMakeLists.txt b/external/vulkancts/modules/vulkan/memory_model/CMakeLists.txt
index b77e679..53a8abf 100644
--- a/external/vulkancts/modules/vulkan/memory_model/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/memory_model/CMakeLists.txt
@@ -3,6 +3,8 @@
 set(DEQP_VK_DEVICE_GROUP_SRCS
 	vktMemoryModelTests.hpp
 	vktMemoryModelMessagePassing.cpp
+	vktMemoryModelPadding.hpp
+	vktMemoryModelPadding.cpp
 )
 
 set(DEQP_VK_DEVICE_GROUP_LIBS
diff --git a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
index 6028658..fb1d586 100644
--- a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
+++ b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
@@ -23,6 +23,7 @@
  *//*--------------------------------------------------------------------*/
 
 #include "vktMemoryModelTests.hpp"
+#include "vktMemoryModelPadding.hpp"
 
 #include "vkBufferWithMemory.hpp"
 #include "vkImageWithMemory.hpp"
@@ -1005,7 +1006,7 @@
 			local = m_data.payloadMemLocal;
 			if (m_data.payloadSC == SC_PHYSBUFFER)
 			{
-				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
+				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
 				if (m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
 					memoryDeviceAddress = true;
 			}
@@ -1016,7 +1017,7 @@
 			local = m_data.guardMemLocal;
 			if (m_data.guardSC == SC_PHYSBUFFER)
 			{
-				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
+				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
 				if (m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
 					memoryDeviceAddress = true;
 			}
@@ -1452,9 +1453,9 @@
 	Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
 	Move<VkCommandBuffer>			cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
 
-	VkBufferDeviceAddressInfoKHR addrInfo =
+	VkBufferDeviceAddressInfo addrInfo =
 		{
-			VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,// VkStructureType	sType;
+			VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,	// VkStructureType	sType;
 			DE_NULL,										// const void*		 pNext;
 			0,												// VkBuffer			buffer
 		};
@@ -1527,7 +1528,7 @@
 			addrInfo.buffer = **buffers[0];
 			VkDeviceAddress addr;
 			if (useKHR)
-				addr = vk.getBufferDeviceAddressKHR(device, &addrInfo);
+				addr = vk.getBufferDeviceAddress(device, &addrInfo);
 			else
 				addr = vk.getBufferDeviceAddressEXT(device, &addrInfo);
 			vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages,
@@ -1539,7 +1540,7 @@
 			addrInfo.buffer = **buffers[1];
 			VkDeviceAddress addr;
 			if (useKHR)
-				addr = vk.getBufferDeviceAddressKHR(device, &addrInfo);
+				addr = vk.getBufferDeviceAddress(device, &addrInfo);
 			else
 				addr = vk.getBufferDeviceAddressEXT(device, &addrInfo);
 			vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages,
@@ -1937,6 +1938,9 @@
 	}
 	group->addChild(transGroup.release());
 
+	// Padding tests.
+	group->addChild(createPaddingTests(testCtx));
+
 	return group.release();
 }
 
diff --git a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.cpp b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.cpp
new file mode 100644
index 0000000..6c02f3a
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.cpp
@@ -0,0 +1,353 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 Vulkan Memory Model padding access tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktMemoryModelPadding.hpp"
+#include "vktTestCase.hpp"
+
+#include "vkBufferWithMemory.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkCmdUtil.hpp"
+
+#include "deMemory.h"
+
+namespace vkt
+{
+namespace MemoryModel
+{
+
+namespace
+{
+// The structures below match the shader declarations but have explicit padding members at the end so we can check their contents
+// easily after running the shader. Using the std140 layout means structures are aligned to 16 bytes.
+
+// Structure with a 12-byte padding at the end.
+struct Pad12
+{
+	deInt32 a;
+	deUint8 padding[12];
+};
+
+// Structure with an 8-byte padding at the end.
+struct Pad8
+{
+	deInt32 a, b;
+	deUint8 padding[8];
+};
+
+// Structure with a 4-byte padding at the end.
+struct Pad4
+{
+	deInt32 a, b, c;
+	deUint8 padding[4];
+};
+
+// Buffer structure for the input and output buffers.
+struct BufferStructure
+{
+	static constexpr deUint32 kArrayLength = 3u;
+
+	Pad12	subA[kArrayLength];
+	Pad8	subB[kArrayLength];
+	Pad4	subC[kArrayLength];
+
+	// Pre-fill substructures with the given data.
+	BufferStructure (deInt32 a, deInt32 b, deInt32 c, deUint8 paddingByte)
+	{
+		for (deUint32 i = 0; i < kArrayLength; ++i)
+		{
+			subA[i].a = a;
+			subB[i].a = a;
+			subC[i].a = a;
+			subB[i].b = b;
+			subC[i].b = b;
+			subC[i].c = c;
+			deMemset(subA[i].padding, static_cast<int>(paddingByte), sizeof(subA[i].padding));
+			deMemset(subB[i].padding, static_cast<int>(paddingByte), sizeof(subB[i].padding));
+			deMemset(subC[i].padding, static_cast<int>(paddingByte), sizeof(subC[i].padding));
+		}
+	}
+
+	// Pre-fill substructures with zeros.
+	BufferStructure (deUint8 paddingByte)
+		: BufferStructure (0, 0, 0, paddingByte)
+		{}
+
+	// Verify members and padding bytes.
+	bool checkValues (deInt32 a, deInt32 b, deInt32 c, deUint8 paddingByte) const
+	{
+		for (deUint32 i = 0; i < kArrayLength; ++i)
+		{
+			if (subA[i].a != a || subB[i].a != a || subC[i].a != a ||
+				subB[i].b != b || subC[i].b != b ||
+				subC[i].c != c)
+				return false;
+		}
+		return checkPaddingBytes(paddingByte);
+	}
+
+	// Verify padding bytes have a known value.
+	bool checkPaddingBytes (deUint8 value) const
+	{
+		for (deUint32 j = 0; j < kArrayLength; ++j)
+		{
+			for (int i = 0; i < DE_LENGTH_OF_ARRAY(subA[j].padding); ++i)
+			{
+				if (subA[j].padding[i] != value)
+					return false;
+			}
+			for (int i = 0; i < DE_LENGTH_OF_ARRAY(subB[j].padding); ++i)
+			{
+				if (subB[j].padding[i] != value)
+					return false;
+			}
+			for (int i = 0; i < DE_LENGTH_OF_ARRAY(subC[j].padding); ++i)
+			{
+				if (subC[j].padding[i] != value)
+					return false;
+			}
+		}
+		return true;
+	}
+};
+
+class PaddingTest : public vkt::TestCase
+{
+public:
+							PaddingTest		(tcu::TestContext& testCtx, const std::string& name, const std::string& description);
+	virtual					~PaddingTest	(void) {}
+
+	virtual void			initPrograms	(vk::SourceCollections& programCollection) const;
+	virtual TestInstance*	createInstance	(Context& context) const;
+	virtual void			checkSupport	(Context& context) const;
+
+	IterateResult			iterate			(void) { DE_ASSERT(false); return STOP; } // Deprecated in this module
+};
+
+class PaddingTestInstance : public vkt::TestInstance
+{
+public:
+								PaddingTestInstance		(Context& context)
+									: vkt::TestInstance(context)
+									{}
+	virtual						~PaddingTestInstance	(void) {}
+
+	virtual tcu::TestStatus		iterate					(void);
+};
+
+
+PaddingTest::PaddingTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description)
+	: vkt::TestCase(testCtx, name, description)
+{
+}
+
+TestInstance* PaddingTest::createInstance (Context& context) const
+{
+	return new PaddingTestInstance(context);
+}
+
+void PaddingTest::initPrograms (vk::SourceCollections& programCollection) const
+{
+	const std::string arrayLenghtStr = std::to_string(BufferStructure::kArrayLength);
+
+	std::ostringstream shaderSrc;
+	shaderSrc
+		<< "#version 450\n"
+		<< "#pragma use_vulkan_memory_model\n"
+		<< "\n"
+		<< "struct A {\n"
+		<< "    int a;\n"
+		<< "};\n"
+		<< "\n"
+		<< "struct B {\n"
+		<< "    int a, b;\n"
+		<< "};\n"
+		<< "\n"
+		<< "struct C {\n"
+		<< "    int a, b, c;\n"
+		<< "};\n"
+		<< "\n"
+		<< "struct BufferStructure {\n"
+		<< "    A subA[" << arrayLenghtStr << "];\n"
+		<< "    B subB[" << arrayLenghtStr << "];\n"
+		<< "    C subC[" << arrayLenghtStr << "];\n"
+		<< "};\n"
+		<< "\n"
+		<< "layout (set=0, binding=0, std140) uniform InputBlock\n"
+		<< "{\n"
+		<< "    BufferStructure inBlock;\n"
+		<< "};\n"
+		<< "\n"
+		<< "layout (set=0, binding=1, std140) buffer OutputBlock\n"
+		<< "{\n"
+		<< "    BufferStructure outBlock;\n"
+		<< "};\n"
+		<< "\n"
+		<< "void main()\n"
+		<< "{\n"
+		<< "    const uint idx = gl_GlobalInvocationID.x;\n"
+		<< "    outBlock.subA[idx] = inBlock.subA[idx];\n"
+		<< "    outBlock.subB[idx] = inBlock.subB[idx];\n"
+		<< "    outBlock.subC[idx] = inBlock.subC[idx];\n"
+		<< "}\n";
+
+	programCollection.glslSources.add("comp") << glu::ComputeSource(shaderSrc.str());
+}
+
+void PaddingTest::checkSupport (Context& context) const
+{
+	context.requireDeviceFunctionality("VK_KHR_vulkan_memory_model");
+	if (!context.getVulkanMemoryModelFeatures().vulkanMemoryModel)
+	{
+		TCU_THROW(NotSupportedError, "Vulkan memory model not supported");
+	}
+}
+
+tcu::TestStatus PaddingTestInstance::iterate (void)
+{
+	const auto&	vkd			= m_context.getDeviceInterface();
+	const auto	device		= m_context.getDevice();
+	auto&		allocator	= m_context.getDefaultAllocator();
+	const auto	queue		= m_context.getUniversalQueue();
+	const auto	queueIndex	= m_context.getUniversalQueueFamilyIndex();
+
+	constexpr vk::VkDeviceSize kBufferSize	= static_cast<vk::VkDeviceSize>(sizeof(BufferStructure));
+	constexpr deInt32 kA					= 1;
+	constexpr deInt32 kB					= 2;
+	constexpr deInt32 kC					= 3;
+	constexpr deUint8 kInputPaddingByte		= 0xFEu;
+	constexpr deUint8 kOutputPaddingByte	= 0x7Fu;
+
+	// Create input and output buffers.
+	auto inputBufferInfo	= vk::makeBufferCreateInfo(kBufferSize, vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+	auto outputBufferInfo	= vk::makeBufferCreateInfo(kBufferSize, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+
+	vk::BufferWithMemory inputBuffer	{vkd, device, allocator, inputBufferInfo,	vk::MemoryRequirement::HostVisible};
+	vk::BufferWithMemory outputBuffer	{vkd, device, allocator, outputBufferInfo,	vk::MemoryRequirement::HostVisible};
+
+	// Fill buffers with initial contents.
+	BufferStructure inputValues	{kA, kB, kC, kInputPaddingByte};
+	BufferStructure outputInit	{kOutputPaddingByte};
+
+	auto& inputAlloc	= inputBuffer.getAllocation();
+	auto& outputAlloc	= outputBuffer.getAllocation();
+
+	void* inputBufferPtr	= static_cast<deUint8*>(inputAlloc.getHostPtr()) + inputAlloc.getOffset();
+	void* outputBufferPtr	= static_cast<deUint8*>(outputAlloc.getHostPtr()) + outputAlloc.getOffset();
+
+	deMemcpy(inputBufferPtr,	&inputValues,	sizeof(inputValues));
+	deMemcpy(outputBufferPtr,	&outputInit,	sizeof(outputInit));
+
+	vk::flushAlloc(vkd, device, inputAlloc);
+	vk::flushAlloc(vkd, device, outputAlloc);
+
+	// Descriptor set layout.
+	vk::DescriptorSetLayoutBuilder layoutBuilder;
+	layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+	layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+	auto descriptorSetLayout = layoutBuilder.build(vkd, device);
+
+	// Descriptor pool.
+	vk::DescriptorPoolBuilder poolBuilder;
+	poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
+	poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
+	auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+	// Descriptor set.
+	const auto descriptorSet = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
+
+	// Update descriptor set using the buffers.
+	const auto inputBufferDescriptorInfo	= vk::makeDescriptorBufferInfo(inputBuffer.get(), 0ull, VK_WHOLE_SIZE);
+	const auto outputBufferDescriptorInfo	= vk::makeDescriptorBufferInfo(outputBuffer.get(), 0ull, VK_WHOLE_SIZE);
+
+	vk::DescriptorSetUpdateBuilder updateBuilder;
+	updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &inputBufferDescriptorInfo);
+	updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo);
+	updateBuilder.update(vkd, device);
+
+	// Create compute pipeline.
+	auto shaderModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
+	auto pipelineLayout = vk::makePipelineLayout(vkd, device, descriptorSetLayout.get());
+
+	const vk::VkComputePipelineCreateInfo		pipelineCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+		nullptr,
+		0u,															// flags
+		{															// compute shader
+			vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			nullptr,													// const void*							pNext;
+			0u,															// VkPipelineShaderStageCreateFlags		flags;
+			vk::VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
+			shaderModule.get(),											// VkShaderModule						module;
+			"main",														// const char*							pName;
+			nullptr,													// const VkSpecializationInfo*			pSpecializationInfo;
+		},
+		pipelineLayout.get(),										// layout
+		DE_NULL,													// basePipelineHandle
+		0,															// basePipelineIndex
+	};
+	auto pipeline = vk::createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
+
+	// Synchronization barriers.
+	auto inputBufferHostToDevBarrier	= vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_SHADER_READ_BIT, inputBuffer.get(), 0ull, VK_WHOLE_SIZE);
+	auto outputBufferHostToDevBarrier	= vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_SHADER_WRITE_BIT, outputBuffer.get(), 0ull, VK_WHOLE_SIZE);
+	auto outputBufferDevToHostBarrier	= vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, outputBuffer.get(), 0ull, VK_WHOLE_SIZE);
+
+	// Command buffer.
+	auto cmdPool		= vk::makeCommandPool(vkd, device, queueIndex);
+	auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+	auto cmdBuffer		= cmdBufferPtr.get();
+
+	// Record and submit commands.
+	vk::beginCommandBuffer(vkd, cmdBuffer);
+		vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get());
+		vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0, 1u, &descriptorSet.get(), 0u, nullptr);
+		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 1u, &inputBufferHostToDevBarrier, 0u, nullptr);
+		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 1u, &outputBufferHostToDevBarrier, 0u, nullptr);
+		vkd.cmdDispatch(cmdBuffer, BufferStructure::kArrayLength, 1u, 1u);
+		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &outputBufferDevToHostBarrier, 0u, nullptr);
+	vk::endCommandBuffer(vkd, cmdBuffer);
+	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
+
+	// Verify output buffer contents.
+	vk::invalidateAlloc(vkd, device, outputAlloc);
+	BufferStructure* outputData = reinterpret_cast<BufferStructure*>(outputBufferPtr);
+	return (outputData->checkValues(kA, kB, kC, kOutputPaddingByte) ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Unexpected values in output data"));
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createPaddingTests (tcu::TestContext& testCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup> paddingGroup(new tcu::TestCaseGroup(testCtx, "padding", "Padding bytes tests"));
+	paddingGroup->addChild(new PaddingTest(testCtx, "test", "Check padding bytes at the end of structures are not touched on copy"));
+
+	return paddingGroup.release();
+}
+
+} // MemoryModel
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.hpp b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.hpp
new file mode 100644
index 0000000..3478b69
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelPadding.hpp
@@ -0,0 +1,38 @@
+#ifndef _VKTMEMORYMODELPADDING_HPP
+#define _VKTMEMORYMODELPADDING_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 Vulkan Memory Model padding access tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace MemoryModel
+{
+tcu::TestCaseGroup* createPaddingTests (tcu::TestContext& testCtx);
+} // MemoryModel
+} // vkt
+
+#endif // _VKTMEMORYMODELPADDING_HPP
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.cpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.cpp
index a31d9cf..698aeb5 100644
--- a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.cpp
+++ b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.cpp
@@ -69,7 +69,7 @@
 												VkImageLayout					initialLayout_,
 												VkImageLayout					finalLayout_)
 {
-	sType			= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
+	sType			= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
 	pNext			= pNext_;
 	flags			= flags_;
 	format			= format_;
@@ -102,7 +102,7 @@
 											VkImageLayout		layout_,
 											VkImageAspectFlags	aspectMask_)
 {
-	sType		= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+	sType		= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
 	pNext		= pNext_;
 	attachment	= attachment_;
 	layout		= layout_;
@@ -145,15 +145,15 @@
 										  VkPipelineBindPoint				pipelineBindPoint_,
 										  deUint32							viewMask_,
 										  deUint32							inputAttachmentCount_,
-										  const VkAttachmentReference2KHR*	pInputAttachments_,
+										  const VkAttachmentReference2*		pInputAttachments_,
 										  deUint32							colorAttachmentCount_,
-										  const VkAttachmentReference2KHR*	pColorAttachments_,
-										  const VkAttachmentReference2KHR*	pResolveAttachments_,
-										  const VkAttachmentReference2KHR*	pDepthStencilAttachment_,
+										  const VkAttachmentReference2*		pColorAttachments_,
+										  const VkAttachmentReference2*		pResolveAttachments_,
+										  const VkAttachmentReference2*		pDepthStencilAttachment_,
 										  deUint32							preserveAttachmentCount_,
 										  const deUint32*					pPreserveAttachments_)
 {
-	sType					= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+	sType					= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
 	pNext					= pNext_;
 	flags					= flags_;
 	pipelineBindPoint		= pipelineBindPoint_;
@@ -203,7 +203,7 @@
 										VkDependencyFlags		dependencyFlags_,
 										deInt32					viewOffset_)
 {
-	sType			= VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
+	sType			= VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
 	pNext			= pNext_;
 	srcSubpass		= srcSubpass_;
 	dstSubpass		= dstSubpass_;
@@ -250,15 +250,15 @@
 RenderPassCreateInfo2::RenderPassCreateInfo2 (const void*							pNext_,
 											  VkRenderPassCreateFlags				flags_,
 											  deUint32								attachmentCount_,
-											  const VkAttachmentDescription2KHR*	pAttachments_,
+											  const VkAttachmentDescription2*		pAttachments_,
 											  deUint32								subpassCount_,
-											  const VkSubpassDescription2KHR*		pSubpasses_,
+											  const VkSubpassDescription2*			pSubpasses_,
 											  deUint32								dependencyCount_,
-											  const VkSubpassDependency2KHR*		pDependencies_,
+											  const VkSubpassDependency2*			pDependencies_,
 											  deUint32								correlatedViewMaskCount_,
 											  const deUint32*						pCorrelatedViewMasks_)
 {
-	sType					= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
+	sType					= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
 	pNext					= pNext_;
 	flags					= flags_;
 	attachmentCount			= attachmentCount_;
@@ -273,7 +273,7 @@
 
 Move<VkRenderPass>	RenderPassCreateInfo2::createRenderPass (const DeviceInterface& vk, VkDevice device) const
 {
-	return vk::createRenderPass2KHR(vk, device, this);
+	return vk::createRenderPass2(vk, device, this);
 }
 
 SubpassBeginInfo1::SubpassBeginInfo1 (const void*		pNext_,
@@ -288,7 +288,7 @@
 SubpassBeginInfo2::SubpassBeginInfo2 (const void*		pNext_,
 									  VkSubpassContents	contents_)
 {
-	sType		= VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR;
+	sType		= VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
 	pNext		= pNext_;
 	contents	= contents_;
 }
@@ -302,7 +302,7 @@
 
 SubpassEndInfo2::SubpassEndInfo2 (const void*	pNext_)
 {
-	sType	= VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR;
+	sType	= VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
 	pNext	= pNext_;
 }
 
@@ -341,7 +341,7 @@
 											 const VkRenderPassBeginInfo*	pRenderPassBegin,
 											 const SubpassBeginInfo*		pSubpassBeginInfo)
 {
-	vk.cmdBeginRenderPass2KHR(cmdBuffer, pRenderPassBegin, pSubpassBeginInfo);
+	vk.cmdBeginRenderPass2(cmdBuffer, pRenderPassBegin, pSubpassBeginInfo);
 }
 
 void RenderpassSubpass2::cmdNextSubpass (const DeviceInterface&		vk,
@@ -352,7 +352,7 @@
 	DE_ASSERT(pSubpassBeginInfo != DE_NULL);
 	DE_ASSERT(pSubpassEndInfo != DE_NULL);
 
-	vk.cmdNextSubpass2KHR(cmdBuffer, pSubpassBeginInfo, pSubpassEndInfo);
+	vk.cmdNextSubpass2(cmdBuffer, pSubpassBeginInfo, pSubpassEndInfo);
 }
 
 void RenderpassSubpass2::cmdEndRenderPass (const DeviceInterface&	vk,
@@ -361,7 +361,7 @@
 {
 	DE_ASSERT(pSubpassEndInfo != DE_NULL);
 
-	vk.cmdEndRenderPass2KHR(cmdBuffer, pSubpassEndInfo);
+	vk.cmdEndRenderPass2(cmdBuffer, pSubpassEndInfo);
 }
 
 } // renderpass
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.hpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.hpp
index 1e80c3e..9274146 100644
--- a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.hpp
+++ b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderPassUtil.hpp
@@ -49,7 +49,7 @@
 							 VkImageLayout					finalLayout);
 };
 
-class AttachmentDescription2 : public vk::VkAttachmentDescription2KHR
+class AttachmentDescription2 : public vk::VkAttachmentDescription2
 {
 public:
 	AttachmentDescription2	(const void*					pNext,
@@ -73,7 +73,7 @@
 							 VkImageAspectFlags	aspectMask);
 };
 
-class AttachmentReference2 : public vk::VkAttachmentReference2KHR
+class AttachmentReference2 : public vk::VkAttachmentReference2
 {
 public:
 	AttachmentReference2	(const void*		pNext,
@@ -99,7 +99,7 @@
 						 const deUint32*					pPreserveAttachments);
 };
 
-class SubpassDescription2 : public vk::VkSubpassDescription2KHR
+class SubpassDescription2 : public vk::VkSubpassDescription2
 {
 public:
 	SubpassDescription2	(const void*						pNext,
@@ -107,11 +107,11 @@
 						 VkPipelineBindPoint				pipelineBindPoint,
 						 deUint32							viewMask,
 						 deUint32							inputAttachmentCount,
-						 const VkAttachmentReference2KHR*	pInputAttachments,
+						 const VkAttachmentReference2*		pInputAttachments,
 						 deUint32							colorAttachmentCount,
-						 const VkAttachmentReference2KHR*	pColorAttachments,
-						 const VkAttachmentReference2KHR*	pResolveAttachments,
-						 const VkAttachmentReference2KHR*	pDepthStencilAttachment,
+						 const VkAttachmentReference2*		pColorAttachments,
+						 const VkAttachmentReference2*		pResolveAttachments,
+						 const VkAttachmentReference2*		pDepthStencilAttachment,
 						 deUint32							preserveAttachmentCount,
 						 const deUint32*					pPreserveAttachments);
 };
@@ -130,7 +130,7 @@
 						 deInt32				viewOffset);
 };
 
-class SubpassDependency2 : public vk::VkSubpassDependency2KHR
+class SubpassDependency2 : public vk::VkSubpassDependency2
 {
 public:
 	SubpassDependency2	(const void*			pNext,
@@ -162,17 +162,17 @@
 													 VkDevice device) const;
 };
 
-class RenderPassCreateInfo2 : public VkRenderPassCreateInfo2KHR
+class RenderPassCreateInfo2 : public VkRenderPassCreateInfo2
 {
 public:
 							RenderPassCreateInfo2	(const void*						pNext,
 													 VkRenderPassCreateFlags			flags,
 													 deUint32							attachmentCount,
-													 const VkAttachmentDescription2KHR*	pAttachments,
+													 const VkAttachmentDescription2*	pAttachments,
 													 deUint32							subpassCount,
-													 const VkSubpassDescription2KHR*	pSubpasses,
+													 const VkSubpassDescription2*		pSubpasses,
 													 deUint32							dependencyCount,
-													 const VkSubpassDependency2KHR*		pDependencies,
+													 const VkSubpassDependency2*		pDependencies,
 													 deUint32							correlatedViewMaskCount,
 													 const deUint32*					pCorrelatedViewMasks);
 
@@ -189,7 +189,7 @@
 	VkSubpassContents	contents;
 };
 
-class SubpassBeginInfo2 : public VkSubpassBeginInfoKHR
+class SubpassBeginInfo2 : public VkSubpassBeginInfo
 {
 public:
 						SubpassBeginInfo2	(const void*		pNext,
@@ -202,7 +202,7 @@
 						SubpassEndInfo1	(const void*	pNext);
 };
 
-class SubpassEndInfo2 : public VkSubpassEndInfoKHR
+class SubpassEndInfo2 : public VkSubpassEndInfo
 {
 public:
 						SubpassEndInfo2	(const void*	pNext);
diff --git a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt
index 96a490e..2a396a8 100644
--- a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt
@@ -26,6 +26,8 @@
 	vktPipelinePushConstantTests.hpp
 	vktPipelinePushDescriptorTests.cpp
 	vktPipelinePushDescriptorTests.hpp
+	vktPipelineSampleLocationsUtil.cpp
+	vktPipelineSampleLocationsUtil.hpp
 	vktPipelineSpecConstantTests.hpp
 	vktPipelineSpecConstantTests.cpp
 	vktPipelineSpecConstantUtil.hpp
@@ -52,8 +54,12 @@
 	vktPipelineMultisampleShaderBuiltInTests.hpp
 	vktPipelineMultisampleImageTests.cpp
 	vktPipelineMultisampleImageTests.hpp
+	vktPipelineMultisampleMixedAttachmentSamplesTests.cpp
+	vktPipelineMultisampleMixedAttachmentSamplesTests.hpp
 	vktPipelineMultisampleSampleLocationsExtTests.cpp
 	vktPipelineMultisampleSampleLocationsExtTests.hpp
+	vktPipelineMultisampleShaderFragmentMaskTests.cpp
+	vktPipelineMultisampleShaderFragmentMaskTests.hpp
 	vktPipelineInputAssemblyTests.cpp
 	vktPipelineInputAssemblyTests.hpp
 	vktPipelineReferenceRenderer.cpp
@@ -91,6 +97,8 @@
 	vktPipelineExecutablePropertiesTests.hpp
 	vktPipelineMaxVaryingsTests.cpp
 	vktPipelineMaxVaryingsTests.hpp
+	vktPipelineBlendOperationAdvancedTests.cpp
+	vktPipelineBlendOperationAdvancedTests.hpp
 	)
 
 set(DEQP_VK_PIPELINE_LIBS
@@ -101,6 +109,8 @@
 	)
 
 PCH(DEQP_VK_PIPELINE_SRCS ../pch.cpp)
+include_directories("../../../../amber/src/include")
+include_directories("../amber")
 
 add_library(deqp-vk-pipeline STATIC ${DEQP_VK_PIPELINE_SRCS})
 target_link_libraries(deqp-vk-pipeline ${DEQP_VK_PIPELINE_LIBS})
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.cpp
new file mode 100644
index 0000000..560c1e9
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.cpp
@@ -0,0 +1,2497 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Valve Corporation.
+ * Copyright (c) 2019 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 VK_EXT_blend_operation_advanced tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineBlendOperationAdvancedTests.hpp"
+#include "vktPipelineImageUtil.hpp"
+#include "vktPipelineReferenceRenderer.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkObjUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuImageCompare.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+using namespace vk;
+
+namespace
+{
+using tcu::Vec3;
+using tcu::Vec4;
+
+const deUint32 widthArea	= 32u;
+const deUint32 heightArea	= 32u;
+
+static const float A1 = 0.750f; // Between 1    and 0.5
+static const float A2 = 0.375f; // Between 0.5  and 0.25
+static const float A3 = 0.125f; // Between 0.25 and 0.0
+
+const Vec4 srcColors[] = {
+					   // Test that pre-multiplied is converted correctly.
+					   // Should not test invalid premultiplied colours (1, 1, 1, 0).
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+
+					   // Test clamping.
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+
+					   // Combinations that test other branches of blend equations.
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+					   { 1.000f, 0.750f, 0.500f, 1.00f },
+					   { 0.250f, 0.125f, 0.000f, 1.00f },
+
+					   // Above block with few different pre-multiplied alpha values.
+					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
+					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
+					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
+					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
+					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
+
+					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
+					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
+					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
+					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
+					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
+
+					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
+					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
+					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
+					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
+					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
+
+					   // Add some source colors with alpha component that is different than the respective destination color
+					   { 0.750f, 0.750f, 0.500f, 0.750f },
+					   { 0.250f, 0.500f, 0.500f, 0.750f },
+					   { 0.250f, 0.125f, 0.000f, 0.500f },
+					   { 0.250f, 0.250f, 0.500f, 0.500f },
+					   { 0.250f, 0.125f, 0.000f, 0.250f },
+					   { 0.125f, 0.125f, 0.125f, 0.250f }};
+
+const Vec4 dstColors[] = {
+					   // Test that pre-multiplied is converted correctly.
+					   // Should not test invalid premultiplied colours (1, 1, 1, 0).
+					   { 0.000f, 0.000f, 0.000f, 0.00f },
+					   { 0.000f, 0.000f, 0.000f, 0.00f },
+
+					   // Test clamping.
+					   { -0.125f, -0.125f, -0.125f, 1.00f },
+					   { -0.125f, -0.125f, -0.125f, 1.00f },
+					   {  1.125f,  1.125f,  1.125f, 1.00f },
+					   {  1.125f,  1.125f,  1.125f, 1.00f },
+
+					   // Combinations that test other branches of blend equations.
+					   { 1.000f, 1.000f, 1.000f, 1.00f },
+					   { 1.000f, 1.000f, 1.000f, 1.00f },
+					   { 0.500f, 0.500f, 0.500f, 1.00f },
+					   { 0.500f, 0.500f, 0.500f, 1.00f },
+					   { 0.250f, 0.250f, 0.250f, 1.00f },
+					   { 0.250f, 0.250f, 0.250f, 1.00f },
+					   { 0.125f, 0.125f, 0.125f, 1.00f },
+					   { 0.125f, 0.125f, 0.125f, 1.00f },
+					   { 0.000f, 0.000f, 0.000f, 1.00f },
+					   { 0.000f, 0.000f, 0.000f, 1.00f },
+
+					   // Above block with few different pre-multiplied alpha values.
+					   { 1.000f * A1, 1.000f * A1, 1.000f * A1, 1.00f * A1},
+					   { 1.000f * A1, 1.000f * A1, 1.000f * A1, 1.00f * A1},
+					   { 0.500f * A1, 0.500f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.500f * A1, 0.500f * A1, 0.500f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.250f * A1, 0.250f * A1, 1.00f * A1},
+					   { 0.250f * A1, 0.250f * A1, 0.250f * A1, 1.00f * A1},
+					   { 0.125f * A1, 0.125f * A1, 0.125f * A1, 1.00f * A1},
+					   { 0.125f * A1, 0.125f * A1, 0.125f * A1, 1.00f * A1},
+					   { 0.000f * A1, 0.000f * A1, 0.000f * A1, 1.00f * A1},
+					   { 0.000f * A1, 0.000f * A1, 0.000f * A1, 1.00f * A1},
+
+					   { 1.000f * A2, 1.000f * A2, 1.000f * A2, 1.00f * A2},
+					   { 1.000f * A2, 1.000f * A2, 1.000f * A2, 1.00f * A2},
+					   { 0.500f * A2, 0.500f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.500f * A2, 0.500f * A2, 0.500f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.250f * A2, 0.250f * A2, 1.00f * A2},
+					   { 0.250f * A2, 0.250f * A2, 0.250f * A2, 1.00f * A2},
+					   { 0.125f * A2, 0.125f * A2, 0.125f * A2, 1.00f * A2},
+					   { 0.125f * A2, 0.125f * A2, 0.125f * A2, 1.00f * A2},
+					   { 0.000f * A2, 0.000f * A2, 0.000f * A2, 1.00f * A2},
+					   { 0.000f * A2, 0.000f * A2, 0.000f * A2, 1.00f * A2},
+
+					   { 1.000f * A3, 1.000f * A3, 1.000f * A3, 1.00f * A3},
+					   { 1.000f * A3, 1.000f * A3, 1.000f * A3, 1.00f * A3},
+					   { 0.500f * A3, 0.500f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.500f * A3, 0.500f * A3, 0.500f * A3, 1.00f * A3},
+					   { 0.250f * A3, 0.250f * A3, 0.250f * A3, 1.00f * A3 },
+					   { 0.250f * A3, 0.250f * A3, 0.250f * A3, 1.00f * A3 },
+					   { 0.125f * A3, 0.125f * A3, 0.125f * A3, 1.00f * A3 },
+					   { 0.125f * A3, 0.125f * A3, 0.125f * A3, 1.00f * A3 },
+					   { 0.000f * A3, 0.000f * A3, 0.000f * A3, 1.00f * A3 },
+					   { 0.000f * A3, 0.000f * A3, 0.000f * A3, 1.00f * A3 },
+
+					   // Add some source colors with alpha component that is different than the respective source color
+					   { 1.000f, 1.000f, 1.000f, 1.000f },
+					   { 0.250f, 0.250f, 0.250f, 0.500f },
+					   { 0.500f, 0.500f, 0.500f, 0.750f },
+					   { 0.250f, 0.250f, 0.250f, 0.250f },
+					   { 0.250f, 0.250f, 0.250f, 0.500f },
+					   { 0.125f, 0.125f, 0.125f, 0.125f }};
+
+const	Vec4	clearColorVec4  (1.0f, 1.0f, 1.0f, 1.0f);
+
+enum TestMode
+{
+	TEST_MODE_GENERIC = 0,
+	TEST_MODE_COHERENT = 1,
+};
+
+struct BlendOperationAdvancedParam
+{
+	TestMode						testMode;
+	deUint32						testNumber;
+	std::vector<VkBlendOp>			blendOps;
+	deBool							coherentOperations;
+	deBool							independentBlend;
+	deUint32						colorAttachmentsCount;
+	VkBool32						premultipliedSrcColor;
+	VkBool32						premultipliedDstColor;
+	VkBlendOverlapEXT				overlap;
+};
+
+// helper functions
+const std::string generateTestName (struct BlendOperationAdvancedParam param)
+{
+	std::ostringstream result;
+
+	result << ((param.testMode == TEST_MODE_COHERENT && !param.coherentOperations) ? "barrier_" : "");
+	result << "color_attachments_" << param.colorAttachmentsCount;
+	result << "_" << de::toLower(getBlendOverlapEXTStr(param.overlap).toString().substr(3));
+	result << (!param.premultipliedSrcColor ? "_nonpremultipliedsrc" : "");
+	result << (!param.premultipliedDstColor ? "_nonpremultiplieddst" : "");
+	result << "_" << param.testNumber;
+	return result.str();
+}
+
+const std::string generateTestDescription ()
+{
+	std::string result("Test advanced blend operations");
+	return result;
+}
+
+Vec3 calculateWeightingFactors(BlendOperationAdvancedParam param,
+									float alphaSrc, float alphaDst)
+{
+	Vec3 p = Vec3(0.0f, 0.0f, 0.0f);
+	switch(param.overlap)
+	{
+	case VK_BLEND_OVERLAP_UNCORRELATED_EXT:
+		p.x() = alphaSrc * alphaDst;
+		p.y() = alphaSrc * (1.0f - alphaDst);
+		p.z() = alphaDst * (1.0f - alphaSrc);
+		break;
+	case VK_BLEND_OVERLAP_CONJOINT_EXT:
+		p.x() = deFloatMin(alphaSrc, alphaDst);
+		p.y() = deFloatMax(alphaSrc - alphaDst, 0.0f);
+		p.z() = deFloatMax(alphaDst - alphaSrc, 0.0f);
+		break;
+	case VK_BLEND_OVERLAP_DISJOINT_EXT:
+		p.x() = deFloatMax(alphaSrc + alphaDst - 1.0f, 0.0f);
+		p.y() = deFloatMin(alphaSrc, 1.0f - alphaDst);
+		p.z() = deFloatMin(alphaDst, 1.0f - alphaSrc);
+		break;
+	default:
+		DE_FATAL("Unsupported Advanced Blend Overlap Mode");
+	};
+	return p;
+}
+
+	Vec3 calculateXYZFactors(VkBlendOp op)
+{
+	Vec3 xyz = Vec3(0.0f, 0.0f, 0.0f);
+	switch (op)
+	{
+	case VK_BLEND_OP_ZERO_EXT:
+		xyz = Vec3(0.0f, 0.0f, 0.0f);
+		break;
+
+	case VK_BLEND_OP_DST_ATOP_EXT:
+	case VK_BLEND_OP_SRC_EXT:
+		xyz = Vec3(1.0f, 1.0f, 0.0f);
+		break;
+
+	case VK_BLEND_OP_DST_EXT:
+		xyz = Vec3(1.0f, 0.0f, 1.0f);
+		break;
+
+	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
+	case VK_BLEND_OP_HSL_COLOR_EXT:
+	case VK_BLEND_OP_HSL_SATURATION_EXT:
+	case VK_BLEND_OP_HSL_HUE_EXT:
+	case VK_BLEND_OP_HARDMIX_EXT:
+	case VK_BLEND_OP_PINLIGHT_EXT:
+	case VK_BLEND_OP_LINEARLIGHT_EXT:
+	case VK_BLEND_OP_VIVIDLIGHT_EXT:
+	case VK_BLEND_OP_LINEARBURN_EXT:
+	case VK_BLEND_OP_LINEARDODGE_EXT:
+	case VK_BLEND_OP_EXCLUSION_EXT:
+	case VK_BLEND_OP_DIFFERENCE_EXT:
+	case VK_BLEND_OP_SOFTLIGHT_EXT:
+	case VK_BLEND_OP_HARDLIGHT_EXT:
+	case VK_BLEND_OP_COLORBURN_EXT:
+	case VK_BLEND_OP_COLORDODGE_EXT:
+	case VK_BLEND_OP_LIGHTEN_EXT:
+	case VK_BLEND_OP_DARKEN_EXT:
+	case VK_BLEND_OP_OVERLAY_EXT:
+	case VK_BLEND_OP_SCREEN_EXT:
+	case VK_BLEND_OP_MULTIPLY_EXT:
+	case VK_BLEND_OP_SRC_OVER_EXT:
+	case VK_BLEND_OP_DST_OVER_EXT:
+		xyz = Vec3(1.0f, 1.0f, 1.0f);
+		break;
+
+	case VK_BLEND_OP_SRC_IN_EXT:
+	case VK_BLEND_OP_DST_IN_EXT:
+		xyz = Vec3(1.0f, 0.0f, 0.0f);
+		break;
+
+	case VK_BLEND_OP_SRC_OUT_EXT:
+		xyz = Vec3(0.0f, 1.0f, 0.0f);
+		break;
+
+	case VK_BLEND_OP_DST_OUT_EXT:
+		xyz = Vec3(0.0f, 0.0f, 1.0f);
+		break;
+
+	case VK_BLEND_OP_INVERT_RGB_EXT:
+	case VK_BLEND_OP_INVERT_EXT:
+	case VK_BLEND_OP_SRC_ATOP_EXT:
+		xyz = Vec3(1.0f, 0.0f, 1.0f);
+		break;
+
+	case VK_BLEND_OP_XOR_EXT:
+		xyz = Vec3(0.0f, 1.0f, 1.0f);
+		break;
+
+	default:
+		DE_FATAL("Unsupported f/X/Y/Z Advanced Blend Operations Mode");
+	};
+
+	return xyz;
+}
+
+float blendOpOverlay(float src, float dst)
+{
+	if (dst <= 0.5f)
+		return (2.0f * src * dst);
+	else
+		return (1.0f - (2.0f * (1.0f - src) * (1.0f - dst)));
+}
+
+float blendOpColorDodge(float src, float dst)
+{
+	if (dst <= 0.0f)
+		return 0.0f;
+	else if (src < 1.0f)
+		return deFloatMin(1.0f, (dst / (1.0f - src)));
+	else
+		return 1.0f;
+}
+
+float blendOpColorBurn(float src, float dst)
+{
+	if (dst >= 1.0f)
+		return 1.0f;
+	else if (src > 0.0f)
+		return 1.0f - deFloatMin(1.0f, (1.0f - dst) / src);
+	else
+		return 0.0f;
+}
+
+float blendOpHardlight(float src, float dst)
+{
+	if (src <= 0.5f)
+		return 2.0f * src * dst;
+	else
+		return 1.0f - (2.0f * (1.0f - src) * (1.0f - dst));
+}
+
+float blendOpSoftlight(float src, float dst)
+{
+	if (src <= 0.5f)
+		return dst - ((1.0f - (2.0f * src)) * dst * (1.0f - dst));
+	else if (dst <= 0.25f)
+		return dst + (((2.0f * src) - 1.0f) * dst * ((((16.0f * dst) - 12.0f) * dst) + 3.0f));
+	else
+		return dst + (((2.0f * src) - 1.0f) * (deFloatSqrt(dst) - dst));
+}
+
+float blendOpLinearDodge(float src, float dst)
+{
+	if ((src + dst) <= 1.0f)
+		return src + dst;
+	else
+		return 1.0f;
+}
+
+float blendOpLinearBurn(float src, float dst)
+{
+	if ((src + dst) > 1.0f)
+		return src + dst - 1.0f;
+	else
+		return 0.0f;
+}
+
+float blendOpVividLight(float src, float dst)
+{
+	if (src <= 0.0f)
+		return 0.0f;
+	if (src < 0.5f)
+		return 1.0f - (deFloatMin(1.0f, (1.0f - dst) / (2.0f * src)));
+	if (src < 1.0f)
+		return deFloatMin(1.0f, dst / (2.0f * (1.0f - src)));
+	else
+		return 1.0f;
+}
+
+float blendOpLinearLight(float src, float dst)
+{
+	if ((2.0f * src + dst) > 2.0f)
+		return 1.0f;
+	if ((2.0f * src + dst) <= 1.0f)
+		return 0.0f;
+	return (2.0f * src) + dst - 1.0f;
+}
+
+float blendOpPinLight(float src, float dst)
+{
+	if (((2.0f * src - 1.0f) > dst) && src < 0.5f)
+		return 0.0f;
+	if (((2.0f * src - 1.0f) > dst) && src >= 0.5f)
+		return 2.0f * src - 1.0f;
+	if (((2.0f * src - 1.0f) <= dst) && src < (0.5f * dst))
+		return 2.0f * src;
+	if (((2.0f * src - 1.0f) <= dst) && src >= (0.5f * dst))
+		return dst;
+	return 0.0f;
+}
+
+float blendOpHardmix(float src, float dst)
+{
+	if ((src + dst) < 1.0f)
+		return 0.0f;
+	else
+		return 1.0f;
+}
+
+float minv3(Vec3 c)
+{
+	return deFloatMin(deFloatMin(c.x(), c.y()), c.z());
+}
+
+float maxv3(Vec3 c)
+{
+	return deFloatMax(deFloatMax(c.x(), c.y()), c.z());
+}
+
+float lumv3(Vec3 c)
+{
+	return dot(c, Vec3(0.3f, 0.59f, 0.11f));
+}
+
+float satv3(Vec3 c)
+{
+	return maxv3(c) - minv3(c);
+}
+
+// If any color components are outside [0,1], adjust the color to
+// get the components in range.
+Vec3 clipColor(Vec3 color)
+{
+	float lum = lumv3(color);
+	float mincol = minv3(color);
+	float maxcol = maxv3(color);
+
+	if (mincol < 0.0)
+	{
+		color = lum + ((color - lum) * lum) / (lum - mincol);
+	}
+	if (maxcol > 1.0)
+	{
+		color = lum + ((color - lum) * (1.0f - lum)) / (maxcol - lum);
+	}
+	return color;
+}
+
+// Take the base RGB color <cbase> and override its luminosity
+// with that of the RGB color <clum>.
+Vec3 setLum(Vec3 cbase, Vec3 clum)
+{
+	float lbase = lumv3(cbase);
+	float llum = lumv3(clum);
+	float ldiff = llum - lbase;
+
+	Vec3 color = cbase + Vec3(ldiff);
+	return clipColor(color);
+}
+
+// Take the base RGB color <cbase> and override its saturation with
+// that of the RGB color <csat>.  The override the luminosity of the
+// result with that of the RGB color <clum>.
+Vec3 setLumSat(Vec3 cbase, Vec3 csat, Vec3 clum)
+{
+	float minbase = minv3(cbase);
+	float sbase = satv3(cbase);
+	float ssat = satv3(csat);
+	Vec3 color;
+
+	if (sbase > 0)
+	{
+		// Equivalent (modulo rounding errors) to setting the
+		// smallest (R,G,B) component to 0, the largest to <ssat>,
+		// and interpolating the "middle" component based on its
+		// original value relative to the smallest/largest.
+		color = (cbase - minbase) * ssat / sbase;
+	} else {
+		color = Vec3(0.0f);
+	}
+	return setLum(color, clum);
+}
+
+Vec3 calculateFFunction(VkBlendOp op,
+						Vec3 src, Vec3 dst)
+{
+	Vec3 f = Vec3(0.0f, 0.0f, 0.0f);
+
+	switch (op)
+	{
+	case VK_BLEND_OP_XOR_EXT:
+	case VK_BLEND_OP_SRC_OUT_EXT:
+	case VK_BLEND_OP_DST_OUT_EXT:
+	case VK_BLEND_OP_ZERO_EXT:
+		f = Vec3(0.0f, 0.0f, 0.0f);
+		break;
+
+	case VK_BLEND_OP_SRC_ATOP_EXT:
+	case VK_BLEND_OP_SRC_IN_EXT:
+	case VK_BLEND_OP_SRC_OVER_EXT:
+	case VK_BLEND_OP_SRC_EXT:
+		f = src;
+		break;
+
+	case VK_BLEND_OP_DST_ATOP_EXT:
+	case VK_BLEND_OP_DST_IN_EXT:
+	case VK_BLEND_OP_DST_OVER_EXT:
+	case VK_BLEND_OP_DST_EXT:
+		f = dst;
+		break;
+
+	case VK_BLEND_OP_MULTIPLY_EXT:
+		f = src * dst;
+		break;
+
+	case VK_BLEND_OP_SCREEN_EXT:
+		f = src + dst - (src*dst);
+		break;
+
+	case VK_BLEND_OP_OVERLAY_EXT:
+		f.x() = blendOpOverlay(src.x(), dst.x());
+		f.y() = blendOpOverlay(src.y(), dst.y());
+		f.z() = blendOpOverlay(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_DARKEN_EXT:
+		f.x() = deFloatMin(src.x(), dst.x());
+		f.y() = deFloatMin(src.y(), dst.y());
+		f.z() = deFloatMin(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_LIGHTEN_EXT:
+		f.x() = deFloatMax(src.x(), dst.x());
+		f.y() = deFloatMax(src.y(), dst.y());
+		f.z() = deFloatMax(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_COLORDODGE_EXT:
+		f.x() = blendOpColorDodge(src.x(), dst.x());
+		f.y() = blendOpColorDodge(src.y(), dst.y());
+		f.z() = blendOpColorDodge(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_COLORBURN_EXT:
+		f.x() = blendOpColorBurn(src.x(), dst.x());
+		f.y() = blendOpColorBurn(src.y(), dst.y());
+		f.z() = blendOpColorBurn(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_HARDLIGHT_EXT:
+		f.x() = blendOpHardlight(src.x(), dst.x());
+		f.y() = blendOpHardlight(src.y(), dst.y());
+		f.z() = blendOpHardlight(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_SOFTLIGHT_EXT:
+		f.x() = blendOpSoftlight(src.x(), dst.x());
+		f.y() = blendOpSoftlight(src.y(), dst.y());
+		f.z() = blendOpSoftlight(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_DIFFERENCE_EXT:
+		f.x() = deFloatAbs(dst.x() - src.x());
+		f.y() = deFloatAbs(dst.y() - src.y());
+		f.z() = deFloatAbs(dst.z() - src.z());
+		break;
+
+
+	case VK_BLEND_OP_EXCLUSION_EXT:
+		f = src + dst - (2.0f * src * dst);
+		break;
+
+	case VK_BLEND_OP_INVERT_EXT:
+		f = 1.0f - dst;
+		break;
+
+	case VK_BLEND_OP_INVERT_RGB_EXT:
+		f = src * (1.0f - dst);
+		break;
+
+	case VK_BLEND_OP_LINEARDODGE_EXT:
+		f.x() = blendOpLinearDodge(src.x(), dst.x());
+		f.y() = blendOpLinearDodge(src.y(), dst.y());
+		f.z() = blendOpLinearDodge(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_LINEARBURN_EXT:
+		f.x() = blendOpLinearBurn(src.x(), dst.x());
+		f.y() = blendOpLinearBurn(src.y(), dst.y());
+		f.z() = blendOpLinearBurn(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_VIVIDLIGHT_EXT:
+		f.x() = blendOpVividLight(src.x(), dst.x());
+		f.y() = blendOpVividLight(src.y(), dst.y());
+		f.z() = blendOpVividLight(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_LINEARLIGHT_EXT:
+		f.x() = blendOpLinearLight(src.x(), dst.x());
+		f.y() = blendOpLinearLight(src.y(), dst.y());
+		f.z() = blendOpLinearLight(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_PINLIGHT_EXT:
+		f.x() = blendOpPinLight(src.x(), dst.x());
+		f.y() = blendOpPinLight(src.y(), dst.y());
+		f.z() = blendOpPinLight(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_HARDMIX_EXT:
+		f.x() = blendOpHardmix(src.x(), dst.x());
+		f.y() = blendOpHardmix(src.y(), dst.y());
+		f.z() = blendOpHardmix(src.z(), dst.z());
+		break;
+
+	case VK_BLEND_OP_HSL_HUE_EXT:
+		f = setLumSat(src, dst, dst);
+		break;
+
+	case VK_BLEND_OP_HSL_SATURATION_EXT:
+		f = setLumSat(dst, src, dst);
+		break;
+
+	case VK_BLEND_OP_HSL_COLOR_EXT:
+		f = setLum(src, dst);
+		break;
+
+	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
+		f = setLum(dst, src);
+		break;
+
+	default:
+		DE_FATAL("Unsupported f/X/Y/Z Advanced Blend Operations Mode");
+	};
+
+	return f;
+}
+
+Vec4 additionalRGBBlendOperations(VkBlendOp op,
+								  Vec4 src, Vec4 dst)
+{
+	Vec4 res = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
+
+	switch (op)
+	{
+	case VK_BLEND_OP_PLUS_EXT:
+		res = src + dst;
+		break;
+
+	case VK_BLEND_OP_PLUS_CLAMPED_EXT:
+		res.x() = deFloatMin(1.0f, src.x() + dst.x());
+		res.y() = deFloatMin(1.0f, src.y() + dst.y());
+		res.z() = deFloatMin(1.0f, src.z() + dst.z());
+		res.w() = deFloatMin(1.0f, src.w() + dst.w());
+		break;
+
+	case VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT:
+		res.x() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.x() + dst.x());
+		res.y() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.y() + dst.y());
+		res.z() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.z() + dst.z());
+		res.w() = deFloatMin(1.0f, src.w() + dst.w());
+		break;
+
+	case VK_BLEND_OP_PLUS_DARKER_EXT:
+		res.x() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.x()) + (dst.w() - dst.x())));
+		res.y() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.y()) + (dst.w() - dst.y())));
+		res.z() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.z()) + (dst.w() - dst.z())));
+		res.w() = deFloatMin(1.0f, src.w() + dst.w());
+		break;
+
+	case VK_BLEND_OP_MINUS_EXT:
+		res = dst - src;
+		break;
+
+	case VK_BLEND_OP_MINUS_CLAMPED_EXT:
+		res.x() = deFloatMax(0.0f, dst.x() - src.x());
+		res.y() = deFloatMax(0.0f, dst.y() - src.y());
+		res.z() = deFloatMax(0.0f, dst.z() - src.z());
+		res.w() = deFloatMax(0.0f, dst.w() - src.w());
+		break;
+
+	case VK_BLEND_OP_CONTRAST_EXT:
+		res.x() = (dst.w() / 2.0f) + 2.0f * (dst.x() - (dst.w() / 2.0f)) * (src.x() - (src.w() / 2.0f));
+		res.y() = (dst.w() / 2.0f) + 2.0f * (dst.y() - (dst.w() / 2.0f)) * (src.y() - (src.w() / 2.0f));
+		res.z() = (dst.w() / 2.0f) + 2.0f * (dst.z() - (dst.w() / 2.0f)) * (src.z() - (src.w() / 2.0f));
+		res.w() = dst.w();
+		break;
+
+	case VK_BLEND_OP_INVERT_OVG_EXT:
+		res.x() = src.w() * (1.0f - dst.x()) + (1.0f - src.w()) * dst.x();
+		res.y() = src.w() * (1.0f - dst.y()) + (1.0f - src.w()) * dst.y();
+		res.z() = src.w() * (1.0f - dst.z()) + (1.0f - src.w()) * dst.z();
+		res.w() = src.w() + dst.w() - src.w() * dst.w();
+		break;
+
+	case VK_BLEND_OP_RED_EXT:
+		res = dst;
+		res.x() = src.x();
+		break;
+
+	case VK_BLEND_OP_GREEN_EXT:
+		res = dst;
+		res.y() = src.y();
+		break;
+
+	case VK_BLEND_OP_BLUE_EXT:
+		res = dst;
+		res.z() = src.z();
+		break;
+
+	default:
+		DE_FATAL("Unsupported blend operation");
+	};
+	return res;
+}
+
+Vec4 calculateFinalColor(BlendOperationAdvancedParam param, VkBlendOp op,
+						 Vec4 source, Vec4 destination)
+{
+	Vec4 result = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
+	Vec3 srcColor = source.xyz();
+	Vec3 dstColor = destination.xyz();
+
+	// Calculate weighting factors
+	Vec3 p = calculateWeightingFactors(param, source.w(), destination.w());
+
+	if (op > VK_BLEND_OP_MAX && op < VK_BLEND_OP_PLUS_EXT)
+	{
+		{
+			// If srcPremultiplied is set to VK_TRUE, the fragment color components
+			// are considered to have been premultiplied by the A component prior to
+			// blending. The base source color (Rs',Gs',Bs') is obtained by dividing
+			// through by the A component.
+			if (param.premultipliedSrcColor)
+			{
+				if (source.w() != 0.0f)
+					srcColor = srcColor / source.w();
+				else
+					srcColor = Vec3(0.0f, 0.0f, 0.0f);
+			}
+			// If dstPremultiplied is set to VK_TRUE, the destination components are
+			// considered to have been premultiplied by the A component prior to
+			// blending. The base destination color (Rd',Gd',Bd') is obtained by dividing
+			// through by the A component.
+			if (param.premultipliedDstColor)
+			{
+				if (destination.w() != 0.0f)
+					dstColor = dstColor / destination.w();
+				else
+					dstColor = Vec3(0.0f, 0.0f, 0.0f);
+			}
+		}
+
+		// Calculate X, Y, Z terms of the equation
+		Vec3 xyz = calculateXYZFactors(op);
+		Vec3 fSrcDst = calculateFFunction(op, srcColor, dstColor);
+
+		result.x() = fSrcDst.x() * p.x() + xyz.y() * srcColor.x() * p.y() + xyz.z() * dstColor.x() * p.z();
+		result.y() = fSrcDst.y() * p.x() + xyz.y() * srcColor.y() * p.y() + xyz.z() * dstColor.y() * p.z();
+		result.z() = fSrcDst.z() * p.x() + xyz.y() * srcColor.z() * p.y() + xyz.z() * dstColor.z() * p.z();
+		result.w() = xyz.x() * p.x() + xyz.y() * p.y() + xyz.z() * p.z();
+	}
+	else if (op >= VK_BLEND_OP_PLUS_EXT && op < VK_BLEND_OP_MAX_ENUM)
+	{
+		// Premultiply colors for additional RGB blend operations. The formula is different than the rest of operations.
+		{
+			if (!param.premultipliedSrcColor)
+			{
+				srcColor = srcColor * source.w();
+			}
+
+			if (!param.premultipliedDstColor)
+			{
+				dstColor = dstColor * destination.w();
+			}
+
+		}
+		Vec4 src = Vec4(srcColor.x(), srcColor.y(), srcColor.z(), source.w());
+		Vec4 dst = Vec4(dstColor.x(), dstColor.y(), dstColor.z(), destination.w());
+		result = additionalRGBBlendOperations(op, src, dst);
+	}
+	else
+	{
+		DE_FATAL("Unsupported Blend Operation");
+	}
+	return result;
+}
+
+static inline void getCoordinates (deUint32 index, deInt32 &x, deInt32 &y)
+{
+	x = index % widthArea;
+	y = index / heightArea;
+}
+
+static inline std::vector<Vec4> createPoints (void)
+{
+	std::vector<Vec4> vertices;
+	vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
+	vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
+	vertices.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
+	vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
+	vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
+	vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
+	return vertices;
+}
+
+template <class Test>
+vkt::TestCase* newTestCase (tcu::TestContext&					testContext,
+							const BlendOperationAdvancedParam	testParam)
+{
+	return new Test(testContext,
+					generateTestName(testParam).c_str(),
+					generateTestDescription().c_str(),
+					testParam);
+}
+
+Move<VkRenderPass> makeTestRenderPass (BlendOperationAdvancedParam			param,
+									   const DeviceInterface&				vk,
+									   const VkDevice						device,
+									   const VkFormat						colorFormat,
+									   VkAttachmentLoadOp					colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR)
+{
+	const VkAttachmentDescription			colorAttachmentDescription			=
+	{
+		(VkAttachmentDescriptionFlags)0,				// VkAttachmentDescriptionFlags		flags
+		colorFormat,									// VkFormat							format
+		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits			samples
+		colorLoadOp,									// VkAttachmentLoadOp				loadOp
+		VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp				storeOp
+		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp				stencilLoadOp
+		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp				stencilStoreOp
+		(colorLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD) ?
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
+			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout					initialLayout
+		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout					finalLayout
+	};
+
+	std::vector<VkAttachmentDescription>	attachmentDescriptions;
+	std::vector<VkAttachmentReference>		colorAttachmentRefs;
+
+
+	for (deUint32 i = 0; i < param.colorAttachmentsCount; i++)
+	{
+		attachmentDescriptions.push_back(colorAttachmentDescription);
+		const VkAttachmentReference		colorAttachmentRef	=
+		{
+			i,											// deUint32		attachment
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
+		};
+
+		colorAttachmentRefs.push_back(colorAttachmentRef);
+	}
+
+	const VkSubpassDescription				subpassDescription					=
+	{
+		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags		flags
+		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint				pipelineBindPoint
+		0u,														// deUint32							inputAttachmentCount
+		DE_NULL,												// const VkAttachmentReference*		pInputAttachments
+		param.colorAttachmentsCount,							// deUint32							colorAttachmentCount
+		colorAttachmentRefs.data(),								// const VkAttachmentReference*		pColorAttachments
+		DE_NULL,												// const VkAttachmentReference*		pResolveAttachments
+		DE_NULL,												// const VkAttachmentReference*		pDepthStencilAttachment
+		0u,														// deUint32							preserveAttachmentCount
+		DE_NULL													// const deUint32*					pPreserveAttachments
+	};
+
+	const VkRenderPassCreateInfo			renderPassInfo						=
+	{
+		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,									// VkStructureType					sType
+		DE_NULL,																	// const void*						pNext
+		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
+		(deUint32)attachmentDescriptions.size(),									// deUint32							attachmentCount
+		attachmentDescriptions.data(),												// const VkAttachmentDescription*	pAttachments
+		1u,																			// deUint32							subpassCount
+		&subpassDescription,														// const VkSubpassDescription*		pSubpasses
+		0u,																			// deUint32							dependencyCount
+		DE_NULL																		// const VkSubpassDependency*		pDependencies
+	};
+
+	return createRenderPass(vk, device, &renderPassInfo, DE_NULL);
+}
+
+Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
+{
+	const DeviceInterface&	vk				 = context.getDeviceInterface();
+	const VkDevice			vkDevice		 = context.getDevice();
+	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+	const VkBufferCreateInfo vertexBufferParams =
+	{
+		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
+		DE_NULL,									// const void*			pNext;
+		0u,											// VkBufferCreateFlags	flags;
+		size,										// VkDeviceSize			size;
+		usage,										// VkBufferUsageFlags	usage;
+		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
+		1u,											// deUint32				queueFamilyCount;
+		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
+	};
+
+	Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
+
+	*pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
+	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
+
+	return vertexBuffer;
+}
+
+Move<VkImage> createImage2DAndBindMemory (Context&							context,
+										  VkFormat							format,
+										  deUint32							width,
+										  deUint32							height,
+										  VkImageUsageFlags					usage,
+										  VkSampleCountFlagBits				sampleCount,
+										  de::details::MovePtr<Allocation>* pAlloc)
+{
+	const DeviceInterface&	vk				 = context.getDeviceInterface();
+	const VkDevice			vkDevice		 = context.getDevice();
+	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+	const VkImageCreateInfo colorImageParams =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType		sType;
+		DE_NULL,																	// const void*			pNext;
+		0u,																			// VkImageCreateFlags	flags;
+		VK_IMAGE_TYPE_2D,															// VkImageType			imageType;
+		format,																		// VkFormat				format;
+		{ width, height, 1u },														// VkExtent3D			extent;
+		1u,																			// deUint32				mipLevels;
+		1u,																			// deUint32				arraySize;
+		sampleCount,																// deUint32				samples;
+		VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling		tiling;
+		usage,																		// VkImageUsageFlags	usage;
+		VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode		sharingMode;
+		1u,																			// deUint32				queueFamilyCount;
+		&queueFamilyIndex,															// const deUint32*		pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout		initialLayout;
+	};
+
+	Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
+
+	*pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
+	VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
+
+	return image;
+}
+
+// Test Classes
+class BlendOperationAdvancedTestInstance : public vkt::TestInstance
+{
+public:
+								BlendOperationAdvancedTestInstance		(Context&				context,
+																		 const BlendOperationAdvancedParam	param);
+	virtual						~BlendOperationAdvancedTestInstance		(void);
+	virtual tcu::TestStatus		iterate									(void);
+protected:
+			void				prepareRenderPass						(VkFramebuffer framebuffer, VkPipeline pipeline) const;
+			void				prepareCommandBuffer					(void) const;
+			void				buildPipeline							(VkBool32 premultiplySrc, VkBool32 premultiplyDst);
+			void				bindShaderStage							(VkShaderStageFlagBits					stage,
+																		 const char*							sourceName,
+																		 const char*							entryName);
+			deBool				verifyTestResult						(void);
+protected:
+	const BlendOperationAdvancedParam		m_param;
+	const tcu::UVec2						m_renderSize;
+	const VkFormat							m_colorFormat;
+	Move<VkPipelineLayout>					m_pipelineLayout;
+
+	Move<VkBuffer>							m_vertexBuffer;
+	de::MovePtr<Allocation>					m_vertexBufferMemory;
+	std::vector<Vec4>						m_vertices;
+
+	Move<VkRenderPass>						m_renderPass;
+	Move<VkCommandPool>						m_cmdPool;
+	Move<VkCommandBuffer>					m_cmdBuffer;
+	std::vector<Move<VkImage>>				m_colorImages;
+	std::vector<Move<VkImageView>>			m_colorAttachmentViews;
+	std::vector<de::MovePtr<Allocation>>	m_colorImageAllocs;
+	std::vector<VkImageMemoryBarrier>		m_imageLayoutBarriers;
+	Move<VkFramebuffer>						m_framebuffer;
+	Move<VkPipeline>						m_pipeline;
+
+	Move<VkShaderModule>					m_shaderModules[2];
+	deUint32								m_shaderStageCount;
+	VkPipelineShaderStageCreateInfo			m_shaderStageInfo[2];
+};
+
+void BlendOperationAdvancedTestInstance::bindShaderStage (VkShaderStageFlagBits	stage,
+														  const char*			sourceName,
+														  const char*			entryName)
+{
+	const DeviceInterface&	vk			= m_context.getDeviceInterface();
+	const VkDevice			vkDevice	= m_context.getDevice();
+
+	// Create shader module
+	deUint32*				code		= (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
+	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
+
+	const VkShaderModuleCreateInfo moduleCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,				// VkStructureType				sType;
+		DE_NULL,													// const void*					pNext;
+		0u,															// VkShaderModuleCreateFlags	flags;
+		codeSize,													// deUintptr					codeSize;
+		code,														// const deUint32*				pCode;
+	};
+
+	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
+
+	// Prepare shader stage info
+	m_shaderStageInfo[m_shaderStageCount].sType					= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+	m_shaderStageInfo[m_shaderStageCount].pNext					= DE_NULL;
+	m_shaderStageInfo[m_shaderStageCount].flags					= 0u;
+	m_shaderStageInfo[m_shaderStageCount].stage					= stage;
+	m_shaderStageInfo[m_shaderStageCount].module				= *m_shaderModules[m_shaderStageCount];
+	m_shaderStageInfo[m_shaderStageCount].pName					= entryName;
+	m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo	= DE_NULL;
+
+	m_shaderStageCount++;
+}
+
+void BlendOperationAdvancedTestInstance::buildPipeline (VkBool32 srcPremultiplied,
+													   VkBool32 dstPremultiplied)
+{
+	const DeviceInterface&		vk					= m_context.getDeviceInterface();
+	const VkDevice				vkDevice			= m_context.getDevice();
+
+	// Create pipeline
+	const VkVertexInputBindingDescription vertexInputBindingDescription =
+	{
+		0u,									// deUint32				binding;
+		sizeof(Vec4),						// deUint32				strideInBytes;
+		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
+	};
+
+	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
+	{
+		0u,									// deUint32 location;
+		0u,									// deUint32 binding;
+		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
+		0u									// deUint32 offsetInBytes;
+	};
+
+	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
+		1u,																// deUint32									vertexBindingDescriptionCount;
+		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		1u,																// deUint32									vertexAttributeDescriptionCount;
+		&vertexInputAttributeDescription,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+	};
+
+	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
+		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
+		VK_FALSE,														// VkBool32									primitiveRestartEnable;
+	};
+
+	const VkRect2D		scissor		= makeRect2D(m_renderSize);
+	VkViewport			viewport	= makeViewport(m_renderSize);
+
+	const VkPipelineViewportStateCreateInfo viewportStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineViewportStateCreateFlags		flags;
+		1u,																// deUint32									viewportCount;
+		&viewport,														// const VkViewport*						pViewports;
+		1u,																// deUint32									scissorCount;
+		&scissor														// const VkRect2D*							pScissors;
+	};
+
+	const VkPipelineRasterizationStateCreateInfo rasterStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
+		VK_FALSE,														// VkBool32									depthClampEnable;
+		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
+		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
+		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
+		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
+		VK_FALSE,														// VkBool32									depthBiasEnable;
+		0.0f,															// float									depthBiasConstantFactor;
+		0.0f,															// float									depthBiasClamp;
+		0.0f,															// float									depthBiasSlopeFactor;
+		1.0f,															// float									lineWidth;
+	};
+
+	const VkPipelineColorBlendAdvancedStateCreateInfoEXT blendAdvancedStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT,	// VkStructureType		sType;
+		DE_NULL,																// const void*			pNext;
+		srcPremultiplied,														// VkBool32				srcPremultiplied;
+		dstPremultiplied,														// VkBool32				dstPremultiplied;
+		m_param.overlap,														// VkBlendOverlapEXT	blendOverlap;
+	};
+
+	std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;
+
+	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+	{
+		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+		{
+			VK_TRUE,														// VkBool32									blendEnable;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcColorBlendFactor;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstColorBlendFactor;
+			m_param.blendOps[i],											// VkBlendOp								colorBlendOp;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcAlphaBlendFactor;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstAlphaBlendFactor;
+			m_param.blendOps[i],											// VkBlendOp								alphaBlendOp;
+			VK_COLOR_COMPONENT_R_BIT |
+			VK_COLOR_COMPONENT_G_BIT |
+			VK_COLOR_COMPONENT_B_BIT |
+			VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags					colorWriteMask;
+		};
+		colorBlendAttachmentStates.emplace_back(colorBlendAttachmentState);
+	}
+
+	const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+		&blendAdvancedStateParams,									// const void*									pNext;
+		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
+		VK_FALSE,													// VkBool32										logicOpEnable;
+		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+		(deUint32)colorBlendAttachmentStates.size(),				// deUint32										attachmentCount;
+		colorBlendAttachmentStates.data(),							// const VkPipelineColorBlendAttachmentState*	pAttachments;
+		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
+	};
+
+	const VkPipelineMultisampleStateCreateInfo  multisampleStateParams	=
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		0u,															// VkPipelineMultisampleStateCreateFlags		flags;
+		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits						rasterizationSamples;
+		VK_FALSE,													// VkBool32										sampleShadingEnable;
+		0.0f,														// float										minSampleShading;
+		DE_NULL,													// const VkSampleMask*							pSampleMask;
+		VK_FALSE,													// VkBool32										alphaToCoverageEnable;
+		VK_FALSE,													// VkBool32										alphaToOneEnable;
+	};
+
+	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		0u,															// VkPipelineDepthStencilStateCreateFlags		flags;
+		VK_FALSE,													// VkBool32										depthTestEnable;
+		VK_FALSE,													// VkBool32										depthWriteEnable;
+		VK_COMPARE_OP_NEVER,										// VkCompareOp									depthCompareOp;
+		VK_FALSE,													// VkBool32										depthBoundsTestEnable;
+		VK_FALSE,													// VkBool32										stencilTestEnable;
+		// VkStencilOpState front;
+		{
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
+			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
+			0u,						// deUint32		compareMask;
+			0u,						// deUint32		writeMask;
+			0u,						// deUint32		reference;
+		},
+		// VkStencilOpState back;
+		{
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
+			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
+			0u,						// deUint32		compareMask;
+			0u,						// deUint32		writeMask;
+			0u,						// deUint32		reference;
+		},
+		0.0f,														// float										minDepthBounds;
+		1.0f,														// float										maxDepthBounds;
+	};
+
+	const VkDynamicState dynamicState = VK_DYNAMIC_STATE_SCISSOR;
+	const VkPipelineDynamicStateCreateInfo dynamicStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
+		DE_NULL,												// const void*							pNext;
+		0u,														// VkPipelineDynamicStateCreateFlags	flags;
+		1u,														// uint32_t								dynamicStateCount;
+		&dynamicState											// const VkDynamicState*				pDynamicStates;
+	};
+
+	const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
+	{
+		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType										sType;
+		DE_NULL,											// const void*											pNext;
+		0u,													// VkPipelineCreateFlags								flags;
+		m_shaderStageCount,									// deUint32												stageCount;
+		m_shaderStageInfo,									// const VkPipelineShaderStageCreateInfo*				pStages;
+		&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*			pVertexInputState;
+		&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*		pInputAssemblyState;
+		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*			pTessellationState;
+		&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*				pViewportState;
+		&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*		pRasterState;
+		&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*			pMultisampleState;
+		&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*			pDepthStencilState;
+		&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*			pColorBlendState;
+		&dynamicStateParams,								// const VkPipelineDynamicStateCreateInfo*				pDynamicState;
+		*m_pipelineLayout,									// VkPipelineLayout										layout;
+		*m_renderPass,										// VkRenderPass											renderPass;
+		0u,													// deUint32												subpass;
+		DE_NULL,											// VkPipeline											basePipelineHandle;
+		0u,													// deInt32												basePipelineIndex;
+	};
+
+	m_pipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
+}
+
+void BlendOperationAdvancedTestInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline) const
+{
+	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
+
+	std::vector<VkClearValue>	attachmentClearValues;
+
+	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+		attachmentClearValues.emplace_back(makeClearValueColor(clearColorVec4));
+
+	beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
+					m_param.colorAttachmentsCount, attachmentClearValues.data());
+	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+	VkDeviceSize offsets = 0u;
+	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
+
+	// Draw all colors
+	deUint32 skippedColors = 0u;
+	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors); color++)
+	{
+		// Skip ill-formed colors when we have non-premultiplied destination colors.
+		if (m_param.premultipliedDstColor == VK_FALSE)
+		{
+			deBool skipColor = false;
+			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+			{
+				Vec4 calculatedColor = calculateFinalColor(m_param, m_param.blendOps[i], srcColors[color], dstColors[color]);
+				if (calculatedColor.w() <= 0.0f && calculatedColor != Vec4(0.0f))
+				{
+					// Skip ill-formed colors, because the spec says the result is undefined.
+					skippedColors++;
+					skipColor = true;
+					break;
+				}
+			}
+			if (skipColor)
+				continue;
+		}
+
+		deInt32 x = 0;
+		deInt32 y = 0;
+		getCoordinates(color, x, y);
+
+		// Set source color as push constant
+		vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(Vec4), &srcColors[color]);
+
+		VkRect2D scissor = makeRect2D(x, y, 1u, 1u);
+		vk.cmdSetScissor(*m_cmdBuffer, 0u, 1u, &scissor);
+
+		// To set destination color, we do clear attachment restricting the area to the respective pixel of each color attachment.
+		{
+			// Set destination color as push constant.
+			std::vector<VkClearAttachment> attachments;
+			VkClearValue clearValue = vk::makeClearValueColorVec4(dstColors[color]);
+
+			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+			{
+				VkClearAttachment	attachment	=
+				{
+					VK_IMAGE_ASPECT_COLOR_BIT,
+					i,
+					clearValue
+				};
+				attachments.emplace_back(attachment);
+			}
+
+			const VkClearRect rect =
+			{
+				scissor,
+				0u,
+				1u
+			};
+			vk.cmdClearAttachments(*m_cmdBuffer, (deUint32)attachments.size(), attachments.data(), 1u, &rect);
+		}
+
+		// Draw
+		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
+	}
+
+	// If we break this assert, then we are not testing anything in this test.
+	DE_ASSERT(skippedColors < DE_LENGTH_OF_ARRAY(srcColors));
+
+	// Log number of skipped colors
+	if (skippedColors != 0u)
+	{
+		tcu::TestLog& log = m_context.getTestContext().getLog();
+		log << tcu::TestLog::Message << "Skipped " << skippedColors << " out of " << DE_LENGTH_OF_ARRAY(srcColors) << " color cases due to ill-formed colors" << tcu::TestLog::EndMessage;
+	}
+	endRenderPass(vk, *m_cmdBuffer);
+}
+
+void BlendOperationAdvancedTestInstance::prepareCommandBuffer () const
+{
+	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
+
+
+	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
+
+	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
+						  0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageLayoutBarriers.size(), m_imageLayoutBarriers.data());
+
+	prepareRenderPass(*m_framebuffer, *m_pipeline);
+
+	endCommandBuffer(vk, *m_cmdBuffer);
+}
+
+BlendOperationAdvancedTestInstance::BlendOperationAdvancedTestInstance	(Context&							context,
+																		 const BlendOperationAdvancedParam	param)
+	: TestInstance			(context)
+	, m_param				(param)
+	, m_renderSize			(tcu::UVec2(widthArea, heightArea))
+	, m_colorFormat			(VK_FORMAT_R16G16B16A16_SFLOAT)
+	, m_shaderStageCount	(0)
+{
+	const DeviceInterface&		vk				 = m_context.getDeviceInterface();
+	const VkDevice				vkDevice		 = m_context.getDevice();
+	const deUint32				queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+	// Create vertex buffer and upload data
+	{
+		// Load vertices into vertex buffer
+		m_vertices		= createPoints();
+		DE_ASSERT((deUint32)m_vertices.size() == 6);
+
+		m_vertexBuffer	= createBufferAndBindMemory(m_context, m_vertices.size() * sizeof(Vec4), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
+		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vec4));
+		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
+	}
+
+	// Create render pass
+	m_renderPass = makeTestRenderPass(param, vk, vkDevice, m_colorFormat);
+
+	const VkComponentMapping	componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
+
+	// Create color images
+	for (deUint32 i = 0; i < param.colorAttachmentsCount; i++)
+	{
+		de::MovePtr<Allocation>	colorImageAlloc;
+		m_colorImageAllocs.emplace_back(colorImageAlloc);
+
+		Move<VkImage>			colorImage	= createImage2DAndBindMemory(m_context,
+																		 m_colorFormat,
+																		 m_renderSize.x(),
+																		 m_renderSize.y(),
+																		 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+																		 VK_SAMPLE_COUNT_1_BIT,
+																		 &m_colorImageAllocs.back());
+		m_colorImages.emplace_back(colorImage);
+
+		// Set up image layout transition barriers
+		{
+			VkImageMemoryBarrier colorImageBarrier =
+			{
+				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
+				DE_NULL,												// const void*				pNext;
+				0u,														// VkAccessFlags			srcAccessMask;
+				(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+				 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
+				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
+				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
+				VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
+				VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
+				*m_colorImages.back(),									// VkImage					image;
+				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
+			};
+
+			m_imageLayoutBarriers.emplace_back(colorImageBarrier);
+		}
+
+		// Create color attachment view
+		{
+			VkImageViewCreateInfo colorAttachmentViewParams =
+			{
+				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+				DE_NULL,										// const void*				pNext;
+				0u,												// VkImageViewCreateFlags	flags;
+				*m_colorImages.back(),							// VkImage					image;
+				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
+				m_colorFormat,									// VkFormat					format;
+				componentMappingRGBA,							// VkComponentMapping		components;
+				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
+			};
+
+			m_colorAttachmentViews.emplace_back(createImageView(vk, vkDevice, &colorAttachmentViewParams));
+		}
+	}
+
+	// Create framebuffer
+	{
+		std::vector<VkImageView>	imageViews;
+
+		for (auto& movePtr : m_colorAttachmentViews)
+			imageViews.push_back(movePtr.get());
+
+		const VkFramebufferCreateInfo framebufferParams =
+		{
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
+			DE_NULL,											// const void*					pNext;
+			0u,													// VkFramebufferCreateFlags		flags;
+			*m_renderPass,										// VkRenderPass					renderPass;
+			(deUint32)imageViews.size(),						// deUint32						attachmentCount;
+			imageViews.data(),									// const VkImageView*			pAttachments;
+			(deUint32)m_renderSize.x(),							// deUint32						width;
+			(deUint32)m_renderSize.y(),							// deUint32						height;
+			1u,													// deUint32						layers;
+		};
+
+		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
+	}
+
+	// Bind shader stages
+	{
+		bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "vert", "main");
+		bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "frag", "main");
+	}
+
+
+	// Create pipeline layout
+	{
+		const VkPushConstantRange pushConstantRange =
+		{
+			VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags
+			0,									// deUint32				offset
+			sizeof(Vec4)						// deUint32				size
+		};
+
+		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
+			DE_NULL,											// const void*						pNext;
+			0u,													// VkPipelineLayoutCreateFlags		flags;
+			0u,													// deUint32							setLayoutCount;
+			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
+			1u,													// deUint32							pushConstantRangeCount;
+			&pushConstantRange									// const VkPushConstantRange*		pPushConstantRanges;
+		};
+
+		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+	}
+
+	// Create pipeline
+	buildPipeline(m_param.premultipliedSrcColor, m_param.premultipliedDstColor);
+
+	// Create command pool
+	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
+
+	// Create command buffer
+	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+}
+
+BlendOperationAdvancedTestInstance::~BlendOperationAdvancedTestInstance (void)
+{
+}
+
+tcu::TestStatus BlendOperationAdvancedTestInstance::iterate (void)
+{
+	const DeviceInterface&	vk					= m_context.getDeviceInterface();
+	const VkDevice			vkDevice			= m_context.getDevice();
+	const VkQueue			queue				= m_context.getUniversalQueue();
+	tcu::TestLog&			log					= m_context.getTestContext().getLog();
+
+	// Log the blend operations to test
+	{
+		if (m_param.independentBlend)
+		{
+			for (deUint32 i = 0; (i < m_param.colorAttachmentsCount); i++)
+				log << tcu::TestLog::Message << "Color attachment " << i << " uses depth op: "<< de::toLower(getBlendOpStr(m_param.blendOps[i]).toString().substr(3)) << tcu::TestLog::EndMessage;
+
+		}
+		else
+		{
+			log << tcu::TestLog::Message << "All color attachments use depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << tcu::TestLog::EndMessage;
+
+		}
+	}
+	prepareCommandBuffer();
+	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
+
+	if (verifyTestResult() == DE_FALSE)
+		return tcu::TestStatus::fail("Image mismatch");
+
+	return tcu::TestStatus::pass("Result images matches references");
+}
+
+deBool BlendOperationAdvancedTestInstance::verifyTestResult ()
+{
+	deBool							compareOk			= DE_TRUE;
+	const DeviceInterface&			vk					= m_context.getDeviceInterface();
+	const VkDevice					vkDevice			= m_context.getDevice();
+	const VkQueue					queue				= m_context.getUniversalQueue();
+	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
+	Allocator&						allocator			= m_context.getDefaultAllocator();
+	std::vector<tcu::TextureLevel>	referenceImages;
+
+	for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
+	{
+		tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);
+		tcu::clear(refImage.getAccess(), clearColorVec4);
+		referenceImages.emplace_back(refImage);
+	}
+
+	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors); color++)
+	{
+		deBool skipColor = DE_FALSE;
+
+		// Check if any color attachment will generate an ill-formed color. If that's the case, skip that color in the verification.
+		for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
+		{
+			Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[colorAtt], srcColors[color], dstColors[color]);
+			if (m_param.premultipliedDstColor == VK_FALSE)
+			{
+				if (rectColor.w() > 0.0f)
+				{
+					rectColor.x() = rectColor.x() / rectColor.w();
+					rectColor.y() = rectColor.y() / rectColor.w();
+					rectColor.z() = rectColor.z() / rectColor.w();
+				}
+				else
+				{
+					// Skip the color check if it is ill-formed.
+					if (rectColor != Vec4(0.0f))
+					{
+						skipColor = DE_TRUE;
+						break;
+					}
+				}
+			}
+		}
+
+		// Skip ill-formed colors that appears in any color attachment.
+		if (skipColor)
+			continue;
+
+		// If we reach this point, the final color for all color attachment is not ill-formed.
+		for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
+		{
+			Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[colorAtt], srcColors[color], dstColors[color]);
+			if (m_param.premultipliedDstColor == VK_FALSE)
+			{
+				if (rectColor.w() > 0.0f)
+				{
+					rectColor.x() = rectColor.x() / rectColor.w();
+					rectColor.y() = rectColor.y() / rectColor.w();
+					rectColor.z() = rectColor.z() / rectColor.w();
+				}
+				else
+				{
+					// Ill-formed colors were already skipped
+					DE_ASSERT(rectColor == Vec4(0.0f));
+				}
+			}
+			deInt32 x = 0;
+			deInt32 y = 0;
+			getCoordinates(color, x, y);
+			tcu::clear(tcu::getSubregion(referenceImages[colorAtt].getAccess(), x, y, 1u, 1u), rectColor);
+		}
+	}
+
+	for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
+	{
+		// Compare image
+		de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImages[colorAtt], m_colorFormat, m_renderSize);
+		std::ostringstream name;
+		name << "Image comparison. Color attachment: "  << colorAtt << ". Depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[colorAtt]).toString().substr(3));
+
+		compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
+											   "FloatImageCompare",
+											   name.str().c_str(),
+											   referenceImages[colorAtt].getAccess(),
+											   result->getAccess(),
+											   Vec4(0.01f, 0.01f, 0.01f, 0.01f),
+											   tcu::COMPARE_LOG_RESULT);
+		if (!compareOk)
+			return DE_FALSE;
+	}
+	return DE_TRUE;
+}
+
+class BlendOperationAdvancedTest : public vkt::TestCase
+{
+public:
+							BlendOperationAdvancedTest	(tcu::TestContext&					testContext,
+														 const std::string&					name,
+														 const std::string&					description,
+														 const BlendOperationAdvancedParam	param)
+								: vkt::TestCase (testContext, name, description)
+								, m_param		(param)
+								{ }
+	virtual					~BlendOperationAdvancedTest	(void) { }
+	virtual void			initPrograms		(SourceCollections&	programCollection) const;
+	virtual TestInstance*	createInstance		(Context&				context) const;
+	virtual void			checkSupport		(Context& context) const;
+
+protected:
+		const BlendOperationAdvancedParam       m_param;
+};
+
+void BlendOperationAdvancedTest::checkSupport(Context& context) const
+{
+	const InstanceInterface&	vki				 = context.getInstanceInterface();
+
+	context.requireDeviceFunctionality("VK_EXT_blend_operation_advanced");
+
+	VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT blendProperties;
+	blendProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
+	blendProperties.pNext = DE_NULL;
+
+	VkPhysicalDeviceProperties2 properties2;
+	properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+	properties2.pNext = &blendProperties;
+	vki.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties2);
+
+	if (!blendProperties.advancedBlendAllOperations)
+	{
+		throw tcu::NotSupportedError("Unsupported all advanced blend operations");
+	}
+
+	if (m_param.colorAttachmentsCount > blendProperties.advancedBlendMaxColorAttachments)
+	{
+		std::ostringstream error;
+		error << "Unsupported number of color attachments (" << blendProperties.advancedBlendMaxColorAttachments << " < " << m_param.colorAttachmentsCount;
+		throw tcu::NotSupportedError(error.str().c_str());
+	}
+
+	if (m_param.overlap != VK_BLEND_OVERLAP_UNCORRELATED_EXT && !blendProperties.advancedBlendCorrelatedOverlap)
+	{
+		throw tcu::NotSupportedError("Unsupported blend correlated overlap");
+	}
+
+	if (m_param.colorAttachmentsCount > 1 && m_param.independentBlend && !blendProperties.advancedBlendIndependentBlend)
+	{
+		throw tcu::NotSupportedError("Unsupported independent blend");
+	}
+
+	if (!m_param.premultipliedSrcColor && !blendProperties.advancedBlendNonPremultipliedSrcColor)
+	{
+		throw tcu::NotSupportedError("Unsupported non-premultiplied source color");
+	}
+
+	if (!m_param.premultipliedDstColor && !blendProperties.advancedBlendNonPremultipliedDstColor)
+	{
+		throw tcu::NotSupportedError("Unsupported non-premultiplied destination color");
+	}
+
+	const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT blendFeatures = context.getBlendOperationAdvancedFeaturesEXT();
+	if (m_param.coherentOperations && !blendFeatures.advancedBlendCoherentOperations)
+	{
+		throw tcu::NotSupportedError("Unsupported required coherent operations");
+	}
+}
+
+void BlendOperationAdvancedTest::initPrograms (SourceCollections& programCollection) const
+{
+	programCollection.glslSources.add("vert") << glu::VertexSource(
+				"#version 310 es\n"
+				"layout(location = 0) in vec4 position;\n"
+				"void main (void)\n"
+				"{\n"
+				"  gl_Position = position;\n"
+				"}\n");
+
+	std::ostringstream fragmentSource;
+	fragmentSource << "#version 310 es\n";
+	fragmentSource << "layout(push_constant) uniform Color { highp vec4 color; };\n";
+	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+		fragmentSource << "layout(location = "<< i <<") out highp vec4 fragColor" << i <<";\n";
+	fragmentSource << "void main (void)\n";
+	fragmentSource << "{\n";
+	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+		fragmentSource << "  fragColor" << i <<" = color;\n";
+	fragmentSource << "}\n";
+	programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str().c_str());
+}
+
+class BlendOperationAdvancedTestCoherentInstance : public vkt::TestInstance
+{
+public:
+								BlendOperationAdvancedTestCoherentInstance		(Context&				context,
+																				 const BlendOperationAdvancedParam	param);
+	virtual						~BlendOperationAdvancedTestCoherentInstance		(void);
+	virtual tcu::TestStatus		iterate									(void);
+protected:
+			void				prepareRenderPass						(VkFramebuffer framebuffer, VkPipeline pipeline,
+																		 VkRenderPass renderpass, deBool secondDraw);
+	virtual	void				prepareCommandBuffer					(void);
+	virtual	void				buildPipeline							(void);
+	virtual	void				bindShaderStage							(VkShaderStageFlagBits					stage,
+																		 const char*							sourceName,
+																		 const char*							entryName);
+	virtual	tcu::TestStatus		verifyTestResult						(void);
+
+protected:
+	const BlendOperationAdvancedParam		m_param;
+	const tcu::UVec2						m_renderSize;
+	const VkFormat							m_colorFormat;
+	Move<VkPipelineLayout>					m_pipelineLayout;
+
+	Move<VkBuffer>							m_vertexBuffer;
+	de::MovePtr<Allocation>					m_vertexBufferMemory;
+	std::vector<Vec4>						m_vertices;
+
+	std::vector<Move<VkRenderPass>>			m_renderPasses;
+	Move<VkCommandPool>						m_cmdPool;
+	Move<VkCommandBuffer>					m_cmdBuffer;
+	Move<VkImage>							m_colorImage;
+	Move<VkImageView>						m_colorAttachmentView;
+	de::MovePtr<Allocation>					m_colorImageAlloc;
+	std::vector<VkImageMemoryBarrier>		m_imageLayoutBarriers;
+	std::vector<Move<VkFramebuffer>>		m_framebuffers;
+	std::vector<Move<VkPipeline>>			m_pipelines;
+
+	Move<VkShaderModule>					m_shaderModules[2];
+	deUint32								m_shaderStageCount;
+	VkPipelineShaderStageCreateInfo			m_shaderStageInfo[2];
+};
+
+BlendOperationAdvancedTestCoherentInstance::~BlendOperationAdvancedTestCoherentInstance (void)
+{
+}
+
+void BlendOperationAdvancedTestCoherentInstance::bindShaderStage (VkShaderStageFlagBits	stage,
+																 const char*			sourceName,
+																 const char*			entryName)
+{
+	const DeviceInterface&	vk			= m_context.getDeviceInterface();
+	const VkDevice			vkDevice	= m_context.getDevice();
+
+	// Create shader module
+	deUint32*				code		= (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
+	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
+
+	const VkShaderModuleCreateInfo moduleCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,				// VkStructureType				sType;
+		DE_NULL,													// const void*					pNext;
+		0u,															// VkShaderModuleCreateFlags	flags;
+		codeSize,													// deUintptr					codeSize;
+		code,														// const deUint32*				pCode;
+	};
+
+	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
+
+	// Prepare shader stage info
+	m_shaderStageInfo[m_shaderStageCount].sType					= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+	m_shaderStageInfo[m_shaderStageCount].pNext					= DE_NULL;
+	m_shaderStageInfo[m_shaderStageCount].flags					= 0u;
+	m_shaderStageInfo[m_shaderStageCount].stage					= stage;
+	m_shaderStageInfo[m_shaderStageCount].module				= *m_shaderModules[m_shaderStageCount];
+	m_shaderStageInfo[m_shaderStageCount].pName					= entryName;
+	m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo	= DE_NULL;
+
+	m_shaderStageCount++;
+}
+
+void BlendOperationAdvancedTestCoherentInstance::buildPipeline ()
+{
+	const DeviceInterface&		vk					= m_context.getDeviceInterface();
+	const VkDevice				vkDevice			= m_context.getDevice();
+
+	// Create pipeline
+	const VkVertexInputBindingDescription vertexInputBindingDescription =
+	{
+		0u,									// deUint32				binding;
+		sizeof(Vec4)		,				// deUint32				strideInBytes;
+		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
+	};
+
+	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
+	{
+		0u,									// deUint32 location;
+		0u,									// deUint32 binding;
+		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
+		0u									// deUint32 offsetInBytes;
+	};
+
+	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
+		1u,																// deUint32									vertexBindingDescriptionCount;
+		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		1u,																// deUint32									vertexAttributeDescriptionCount;
+		&vertexInputAttributeDescription,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+	};
+
+	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
+		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
+		VK_FALSE,														// VkBool32									primitiveRestartEnable;
+	};
+
+	const VkRect2D		scissor		= makeRect2D(m_renderSize);
+	VkViewport			viewport	= makeViewport(m_renderSize);
+
+	const VkPipelineViewportStateCreateInfo viewportStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineViewportStateCreateFlags		flags;
+		1u,																// deUint32									viewportCount;
+		&viewport,														// const VkViewport*						pViewports;
+		1u,																// deUint32									scissorCount;
+		&scissor														// const VkRect2D*							pScissors;
+	};
+
+	const VkPipelineRasterizationStateCreateInfo rasterStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
+		VK_FALSE,														// VkBool32									depthClampEnable;
+		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
+		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
+		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
+		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
+		VK_FALSE,														// VkBool32									depthBiasEnable;
+		0.0f,															// float									depthBiasConstantFactor;
+		0.0f,															// float									depthBiasClamp;
+		0.0f,															// float									depthBiasSlopeFactor;
+		1.0f,															// float									lineWidth;
+	};
+
+	const VkPipelineColorBlendAdvancedStateCreateInfoEXT blendAdvancedStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT,	// VkStructureType		sType;
+		DE_NULL,																// const void*			pNext;
+		VK_TRUE,																// VkBool32				srcPremultiplied;
+		VK_TRUE,																// VkBool32				dstPremultiplied;
+		m_param.overlap,														// VkBlendOverlapEXT	blendOverlap;
+	};
+
+	std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;
+
+	// One VkPipelineColorBlendAttachmentState for each pipeline, we only have one color attachment.
+	for (deUint32 i = 0; i < 2; i++)
+	{
+		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+		{
+			VK_TRUE,														// VkBool32									blendEnable;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcColorBlendFactor;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstColorBlendFactor;
+			m_param.blendOps[i],											// VkBlendOp								colorBlendOp;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcAlphaBlendFactor;
+			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstAlphaBlendFactor;
+			m_param.blendOps[i],											// VkBlendOp								alphaBlendOp;
+			VK_COLOR_COMPONENT_R_BIT |
+			VK_COLOR_COMPONENT_G_BIT |
+			VK_COLOR_COMPONENT_B_BIT |
+			VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags					colorWriteMask;
+		};
+		colorBlendAttachmentStates.emplace_back(colorBlendAttachmentState);
+	}
+
+	std::vector<VkPipelineColorBlendStateCreateInfo> colorBlendStateParams;
+	VkPipelineColorBlendStateCreateInfo colorBlendStateParam =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+		&blendAdvancedStateParams,									// const void*									pNext;
+		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
+		VK_FALSE,													// VkBool32										logicOpEnable;
+		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+		1u,															// deUint32										attachmentCount;
+		&colorBlendAttachmentStates[0],								// const VkPipelineColorBlendAttachmentState*	pAttachments;
+		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
+	};
+	colorBlendStateParams.emplace_back(colorBlendStateParam);
+
+	// For the second pipeline, the blendOp changed.
+	colorBlendStateParam.pAttachments = &colorBlendAttachmentStates[1];
+	colorBlendStateParams.emplace_back(colorBlendStateParam);
+
+	const VkPipelineMultisampleStateCreateInfo  multisampleStateParams	=
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		0u,															// VkPipelineMultisampleStateCreateFlags		flags;
+		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits						rasterizationSamples;
+		VK_FALSE,													// VkBool32										sampleShadingEnable;
+		0.0f,														// float										minSampleShading;
+		DE_NULL,													// const VkSampleMask*							pSampleMask;
+		VK_FALSE,													// VkBool32										alphaToCoverageEnable;
+		VK_FALSE,													// VkBool32										alphaToOneEnable;
+	};
+
+	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		0u,															// VkPipelineDepthStencilStateCreateFlags		flags;
+		VK_FALSE,													// VkBool32										depthTestEnable;
+		VK_FALSE,													// VkBool32										depthWriteEnable;
+		VK_COMPARE_OP_NEVER,										// VkCompareOp									depthCompareOp;
+		VK_FALSE,													// VkBool32										depthBoundsTestEnable;
+		VK_FALSE,													// VkBool32										stencilTestEnable;
+		// VkStencilOpState front;
+		{
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
+			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
+			0u,						// deUint32		compareMask;
+			0u,						// deUint32		writeMask;
+			0u,						// deUint32		reference;
+		},
+		// VkStencilOpState back;
+		{
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
+			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
+			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
+			0u,						// deUint32		compareMask;
+			0u,						// deUint32		writeMask;
+			0u,						// deUint32		reference;
+		},
+		0.0f,														// float										minDepthBounds;
+		1.0f,														// float										maxDepthBounds;
+	};
+
+	const VkDynamicState dynamicState = VK_DYNAMIC_STATE_SCISSOR;
+	const VkPipelineDynamicStateCreateInfo dynamicStateParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
+		DE_NULL,												// const void*							pNext;
+		0u,														// VkPipelineDynamicStateCreateFlags	flags;
+		1u,														// uint32_t								dynamicStateCount;
+		&dynamicState											// const VkDynamicState*				pDynamicStates;
+	};
+
+	VkGraphicsPipelineCreateInfo graphicsPipelineParams =
+	{
+		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType										sType;
+		DE_NULL,											// const void*											pNext;
+		0u,													// VkPipelineCreateFlags								flags;
+		m_shaderStageCount,									// deUint32												stageCount;
+		m_shaderStageInfo,									// const VkPipelineShaderStageCreateInfo*				pStages;
+		&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*			pVertexInputState;
+		&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*		pInputAssemblyState;
+		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*			pTessellationState;
+		&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*				pViewportState;
+		&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*		pRasterState;
+		&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*			pMultisampleState;
+		&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*			pDepthStencilState;
+		&colorBlendStateParams[0],							// const VkPipelineColorBlendStateCreateInfo*			pColorBlendState;
+		&dynamicStateParams,								// const VkPipelineDynamicStateCreateInfo*				pDynamicState;
+		*m_pipelineLayout,									// VkPipelineLayout										layout;
+		m_renderPasses[0].get(),							// VkRenderPass											renderPass;
+		0u,													// deUint32												subpass;
+		DE_NULL,											// VkPipeline											basePipelineHandle;
+		0u,													// deInt32												basePipelineIndex;
+	};
+
+	// Create first pipeline
+	m_pipelines.emplace_back(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams));
+	// Create second pipeline
+	graphicsPipelineParams.pColorBlendState = &colorBlendStateParams[1];
+	graphicsPipelineParams.renderPass = m_renderPasses[1].get();
+	m_pipelines.emplace_back(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams));
+}
+
+void BlendOperationAdvancedTestCoherentInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline, VkRenderPass renderpass, deBool secondDraw)
+{
+	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
+
+	VkClearValue	attachmentClearValue = makeClearValueColor(clearColorVec4);
+
+	beginRenderPass(vk, *m_cmdBuffer, renderpass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
+					(secondDraw ? 0u : 1u),
+					(secondDraw ? DE_NULL : &attachmentClearValue));
+
+	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+	VkDeviceSize offsets = 0u;
+	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
+
+	// There are two different renderpasses, each of them draw
+	// one half of the colors.
+	deBool skippedColors = 0u;
+	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors)/2; color++)
+	{
+		// Skip ill-formed colors when we have non-premultiplied destination colors.
+		if (m_param.premultipliedDstColor == VK_FALSE)
+		{
+			deBool skipColor = false;
+			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
+			{
+				Vec4 calculatedColor = calculateFinalColor(m_param, m_param.blendOps[i], srcColors[color], dstColors[color]);
+				if (calculatedColor.w() <= 0.0f && calculatedColor != Vec4(0.0f))
+				{
+					// Skip ill-formed colors, because the spec says the result is undefined.
+					skippedColors++;
+					skipColor = true;
+					break;
+				}
+			}
+			if (skipColor)
+				continue;
+		}
+		deInt32 x = 0;
+		deInt32 y = 0;
+		getCoordinates(color, x, y);
+
+		deUint32 index = secondDraw ? (color + DE_LENGTH_OF_ARRAY(srcColors) / 2) : color;
+
+		// Set source color as push constant
+		vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(Vec4), &srcColors[index]);
+		VkRect2D scissor = makeRect2D(x, y, 1u, 1u);
+		vk.cmdSetScissor(*m_cmdBuffer, 0u, 1u, &scissor);
+
+		// To set destination color, we do clear attachment restricting the area to the respective pixel of each color attachment.
+		// Only clear in the first draw, for the second draw the destination color is the result of the first draw's blend.
+		if (secondDraw == DE_FALSE)
+		{
+			std::vector<VkClearAttachment> attachments;
+			VkClearValue clearValue = vk::makeClearValueColorVec4(dstColors[index]);
+
+			const VkClearAttachment	attachment	=
+			{
+				VK_IMAGE_ASPECT_COLOR_BIT,
+				0u,
+				clearValue
+			};
+
+			const VkClearRect rect =
+			{
+				scissor,
+				0u,
+				1u
+			};
+			vk.cmdClearAttachments(*m_cmdBuffer, 1u, &attachment, 1u, &rect);
+		}
+
+		// Draw
+		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
+	}
+
+	// If we break this assert, then we are not testing anything in this test.
+	DE_ASSERT(skippedColors < (DE_LENGTH_OF_ARRAY(srcColors) / 2));
+
+	// Log number of skipped colors
+	if (skippedColors != 0u)
+	{
+		tcu::TestLog& log = m_context.getTestContext().getLog();
+		log << tcu::TestLog::Message << "Skipped " << skippedColors << " out of " << (DE_LENGTH_OF_ARRAY(srcColors) / 2) << " color cases due to ill-formed colors" << tcu::TestLog::EndMessage;
+	}
+	endRenderPass(vk, *m_cmdBuffer);
+}
+
+void BlendOperationAdvancedTestCoherentInstance::prepareCommandBuffer ()
+{
+	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
+
+	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
+
+	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
+						  0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageLayoutBarriers.size(), m_imageLayoutBarriers.data());
+
+	prepareRenderPass(m_framebuffers[0].get(), m_pipelines[0].get(), m_renderPasses[0].get(), false);
+
+	if (m_param.coherentOperations == DE_FALSE)
+	{
+		const VkImageMemoryBarrier colorImageBarrier =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
+			DE_NULL,												// const void*				pNext;
+			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			srcAccessMask;
+			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			oldLayout;
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
+			*m_colorImage,											// VkImage					image;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
+		};
+		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+							  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
+							  0u, DE_NULL, 0u, DE_NULL, 1u, &colorImageBarrier);
+	}
+
+	prepareRenderPass(m_framebuffers[1].get(), m_pipelines[1].get(), m_renderPasses[1].get(), true);
+
+	endCommandBuffer(vk, *m_cmdBuffer);
+}
+
+BlendOperationAdvancedTestCoherentInstance::BlendOperationAdvancedTestCoherentInstance	(Context&							context,
+																						 const BlendOperationAdvancedParam	param)
+	: TestInstance			(context)
+	, m_param				(param)
+	, m_renderSize			(tcu::UVec2(widthArea, heightArea))
+	, m_colorFormat			(VK_FORMAT_R16G16B16A16_SFLOAT)
+	, m_shaderStageCount	(0)
+{
+	const DeviceInterface&		vk				 = m_context.getDeviceInterface();
+	const VkDevice				vkDevice		 = m_context.getDevice();
+	const deUint32				queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+	// Create vertex buffer
+	{
+		m_vertices		= createPoints();
+		DE_ASSERT((deUint32)m_vertices.size() == 6);
+
+		m_vertexBuffer	= createBufferAndBindMemory(m_context, m_vertices.size() * sizeof(Vec4), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
+		// Load vertices into vertex buffer
+		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vec4));
+		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
+	}
+
+	// Create render passes
+	m_renderPasses.emplace_back(makeTestRenderPass(param, vk, vkDevice, m_colorFormat, VK_ATTACHMENT_LOAD_OP_CLEAR));
+	m_renderPasses.emplace_back(makeTestRenderPass(param, vk, vkDevice, m_colorFormat, VK_ATTACHMENT_LOAD_OP_LOAD));
+
+	const VkComponentMapping	componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
+
+	// Create color image
+	m_colorImage	= createImage2DAndBindMemory(m_context,
+												 m_colorFormat,
+												 m_renderSize.x(),
+												 m_renderSize.y(),
+												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+												 VK_SAMPLE_COUNT_1_BIT,
+												 &m_colorImageAlloc);
+	// Set up image layout transition barriers
+	{
+		VkImageMemoryBarrier colorImageBarrier =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
+			DE_NULL,												// const void*				pNext;
+			0u,														// VkAccessFlags			srcAccessMask;
+			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
+			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
+			*m_colorImage,											// VkImage					image;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
+		};
+
+		m_imageLayoutBarriers.emplace_back(colorImageBarrier);
+	}
+
+	// Create color attachment view
+	{
+		VkImageViewCreateInfo colorAttachmentViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+			DE_NULL,										// const void*				pNext;
+			0u,												// VkImageViewCreateFlags	flags;
+			*m_colorImage,									// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
+			m_colorFormat,									// VkFormat					format;
+			componentMappingRGBA,							// VkComponentMapping		components;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
+		};
+
+		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
+	}
+
+	// Create framebuffers
+	{
+		VkFramebufferCreateInfo framebufferParams =
+		{
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
+			DE_NULL,											// const void*					pNext;
+			0u,													// VkFramebufferCreateFlags		flags;
+			m_renderPasses[0].get(),							// VkRenderPass					renderPass;
+			1u,													// deUint32						attachmentCount;
+			&m_colorAttachmentView.get(),						// const VkImageView*			pAttachments;
+			(deUint32)m_renderSize.x(),							// deUint32						width;
+			(deUint32)m_renderSize.y(),							// deUint32						height;
+			1u,													// deUint32						layers;
+		};
+
+		m_framebuffers.emplace_back(createFramebuffer(vk, vkDevice, &framebufferParams));
+		framebufferParams.renderPass = m_renderPasses[1].get();
+		m_framebuffers.emplace_back(createFramebuffer(vk, vkDevice, &framebufferParams));
+	}
+
+	// Bind shader stages
+	{
+		bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "vert", "main");
+		bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "frag", "main");
+	}
+
+
+	// Create pipeline layout
+	{
+		const VkPushConstantRange pushConstantRange =
+		{
+			VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags
+			0,									// deUint32				offset
+			sizeof(Vec4)						// deUint32				size
+		};
+
+		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
+			DE_NULL,											// const void*						pNext;
+			0u,													// VkPipelineLayoutCreateFlags		flags;
+			0u,													// deUint32							setLayoutCount;
+			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
+			1u,													// deUint32							pushConstantRangeCount;
+			&pushConstantRange									// const VkPushConstantRange*		pPushConstantRanges;
+		};
+
+		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+	}
+
+	// Create pipeline
+	buildPipeline();
+
+	// Create command pool
+	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
+
+	// Create command buffer
+	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+}
+
+tcu::TestStatus BlendOperationAdvancedTestCoherentInstance::iterate (void)
+{
+	const DeviceInterface&	vk					= m_context.getDeviceInterface();
+	const VkDevice			vkDevice			= m_context.getDevice();
+	const VkQueue			queue				= m_context.getUniversalQueue();
+	tcu::TestLog&			log					= m_context.getTestContext().getLog();
+
+	// Log the blend operations to test
+	{
+		DE_ASSERT(m_param.blendOps.size() == 2u);
+		log << tcu::TestLog::Message << "First depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << tcu::TestLog::EndMessage;
+		log << tcu::TestLog::Message << "Second depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[1]).toString().substr(3)) << tcu::TestLog::EndMessage;
+
+	}
+
+	prepareCommandBuffer();
+
+	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
+	return verifyTestResult();
+}
+
+tcu::TestStatus BlendOperationAdvancedTestCoherentInstance::verifyTestResult (void)
+{
+	deBool					compareOk			= DE_TRUE;
+	const DeviceInterface&	vk					= m_context.getDeviceInterface();
+	const VkDevice			vkDevice			= m_context.getDevice();
+	const VkQueue			queue				= m_context.getUniversalQueue();
+	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
+	Allocator&				allocator			= m_context.getDefaultAllocator();
+	tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);
+
+	tcu::clear(refImage.getAccess(), clearColorVec4);
+
+	// Generate reference image
+	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors)/2; color++)
+	{
+		deUint32 secondDrawColorIndex = color + DE_LENGTH_OF_ARRAY(srcColors)/2;
+		// Calculate first draw final color
+		Vec4 rectColorTmp = calculateFinalColor(m_param, m_param.blendOps[0], srcColors[color], dstColors[color]);
+
+		if (m_param.premultipliedDstColor == VK_FALSE)
+		{
+			if (rectColorTmp.w() > 0.0f)
+			{
+				rectColorTmp.x() = rectColorTmp.x() / rectColorTmp.w();
+				rectColorTmp.y() = rectColorTmp.y() / rectColorTmp.w();
+				rectColorTmp.z() = rectColorTmp.z() / rectColorTmp.w();
+			}
+			else
+			{
+				// Skip the color check if it is ill-formed.
+				if (rectColorTmp != Vec4(0.0f))
+					continue;
+			}
+		}
+		// Calculate second draw final color
+		Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[1], srcColors[secondDrawColorIndex], rectColorTmp);
+		if (m_param.premultipliedDstColor == VK_FALSE)
+		{
+			if (rectColor.w() > 0.0f)
+			{
+				rectColor.x() = rectColor.x() / rectColor.w();
+				rectColor.y() = rectColor.y() / rectColor.w();
+				rectColor.z() = rectColor.z() / rectColor.w();
+			}
+			else
+			{
+				// Skip the color check if it is ill-formed.
+				if (rectColor != Vec4(0.0f))
+					continue;
+			}
+		}
+
+		deInt32 x = 0;
+		deInt32 y = 0;
+		getCoordinates(color, x, y);
+		tcu::clear(tcu::getSubregion(refImage.getAccess(), x, y, 1u, 1u), rectColor);
+	}
+
+	de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
+	std::ostringstream name;
+	name << "Image comparison. Depth ops: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << " and " << de::toLower(getBlendOpStr(m_param.blendOps[1]).toString().substr(3));
+	compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
+										   "FloatImageCompare",
+										   name.str().c_str(),
+										   refImage.getAccess(),
+										   result->getAccess(),
+										   Vec4(0.01f, 0.01f, 0.01f, 0.01f),
+										   tcu::COMPARE_LOG_RESULT);
+	if (!compareOk)
+		return tcu::TestStatus::fail("Image mismatch");
+
+	return tcu::TestStatus::pass("Result images matches references");
+}
+
+TestInstance* BlendOperationAdvancedTest::createInstance (Context& context) const
+{
+	if (m_param.testMode == TEST_MODE_GENERIC)
+		return new BlendOperationAdvancedTestInstance(context, m_param);
+	else
+		return new BlendOperationAdvancedTestCoherentInstance(context, m_param);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createBlendOperationAdvancedTests (tcu::TestContext& testCtx)
+{
+	enum nonpremultiplyEnum
+	{
+		PREMULTIPLY_SRC = 1u,
+		PREMULTIPLY_DST = 2u
+	};
+	deUint32	premultiplyModes[] = { 0u, PREMULTIPLY_SRC, PREMULTIPLY_DST, PREMULTIPLY_SRC | PREMULTIPLY_DST };
+	deUint32	colorAttachmentCounts[] = { 1u, 2u, 4u, 8u, 16u };
+	deBool		coherentOps[] = { DE_FALSE, DE_TRUE };
+	VkBlendOp	blendOps[] =
+	{
+		VK_BLEND_OP_ZERO_EXT, VK_BLEND_OP_SRC_EXT, VK_BLEND_OP_DST_EXT,	VK_BLEND_OP_SRC_OVER_EXT, VK_BLEND_OP_DST_OVER_EXT,
+		VK_BLEND_OP_SRC_IN_EXT, VK_BLEND_OP_DST_IN_EXT, VK_BLEND_OP_SRC_OUT_EXT, VK_BLEND_OP_DST_OUT_EXT, VK_BLEND_OP_SRC_ATOP_EXT,
+		VK_BLEND_OP_DST_ATOP_EXT, VK_BLEND_OP_XOR_EXT, VK_BLEND_OP_MULTIPLY_EXT, VK_BLEND_OP_SCREEN_EXT, VK_BLEND_OP_OVERLAY_EXT,
+		VK_BLEND_OP_DARKEN_EXT, VK_BLEND_OP_LIGHTEN_EXT, VK_BLEND_OP_COLORDODGE_EXT, VK_BLEND_OP_COLORBURN_EXT, VK_BLEND_OP_HARDLIGHT_EXT,
+		VK_BLEND_OP_SOFTLIGHT_EXT, VK_BLEND_OP_DIFFERENCE_EXT, VK_BLEND_OP_EXCLUSION_EXT, VK_BLEND_OP_INVERT_EXT, VK_BLEND_OP_INVERT_RGB_EXT,
+		VK_BLEND_OP_LINEARDODGE_EXT, VK_BLEND_OP_LINEARBURN_EXT, VK_BLEND_OP_VIVIDLIGHT_EXT, VK_BLEND_OP_LINEARLIGHT_EXT, VK_BLEND_OP_PINLIGHT_EXT,
+		VK_BLEND_OP_HARDMIX_EXT, VK_BLEND_OP_HSL_HUE_EXT, VK_BLEND_OP_HSL_SATURATION_EXT, VK_BLEND_OP_HSL_COLOR_EXT, VK_BLEND_OP_HSL_LUMINOSITY_EXT,
+		VK_BLEND_OP_PLUS_EXT, VK_BLEND_OP_PLUS_CLAMPED_EXT, VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT, VK_BLEND_OP_PLUS_DARKER_EXT, VK_BLEND_OP_MINUS_EXT,
+		VK_BLEND_OP_MINUS_CLAMPED_EXT, VK_BLEND_OP_CONTRAST_EXT, VK_BLEND_OP_INVERT_OVG_EXT, VK_BLEND_OP_RED_EXT, VK_BLEND_OP_GREEN_EXT, VK_BLEND_OP_BLUE_EXT,
+	};
+
+	de::MovePtr<tcu::TestCaseGroup> tests (new tcu::TestCaseGroup(testCtx, "blend_operation_advanced", "VK_EXT_blend_operation_advanced tests"));
+	de::Random						rnd				(deStringHash(tests->getName()));
+
+	de::MovePtr<tcu::TestCaseGroup> opsTests (new tcu::TestCaseGroup(testCtx, "ops", "Test each blend operation advance op"));
+
+
+	for (deUint32 colorAttachmentCount = 0u; colorAttachmentCount < DE_LENGTH_OF_ARRAY(colorAttachmentCounts); colorAttachmentCount++)
+	{
+		for (deUint32 overlap = 0; overlap <= VK_BLEND_OVERLAP_CONJOINT_EXT; overlap++)
+		{
+			for (deUint32 premultiply = 0u; premultiply < DE_LENGTH_OF_ARRAY(premultiplyModes); premultiply++)
+			{
+				deUint32 testNumber = 0u;
+				for (deUint64 blendOp = 0u; blendOp < DE_LENGTH_OF_ARRAY(blendOps); blendOp++)
+				{
+					deBool isAdditionalRGBBlendOp = blendOps[blendOp] >= VK_BLEND_OP_PLUS_EXT && blendOps[blendOp] < VK_BLEND_OP_MAX_ENUM;
+
+					// Additional RGB Blend operations are not affected by the blend overlap modes
+					if (isAdditionalRGBBlendOp && overlap != VK_BLEND_OVERLAP_UNCORRELATED_EXT)
+						continue;
+
+					BlendOperationAdvancedParam testParams;
+					testParams.testMode					= TEST_MODE_GENERIC;
+					testParams.overlap					= (VkBlendOverlapEXT) overlap;
+					testParams.coherentOperations		= DE_FALSE;
+					testParams.colorAttachmentsCount	= colorAttachmentCounts[colorAttachmentCount];
+					testParams.independentBlend			= DE_FALSE;
+					testParams.premultipliedSrcColor	= (premultiplyModes[premultiply] & PREMULTIPLY_SRC) ? VK_TRUE : VK_FALSE;
+					testParams.premultipliedDstColor	= (premultiplyModes[premultiply] & PREMULTIPLY_DST) ? VK_TRUE : VK_FALSE;
+					testParams.testNumber				= testNumber++;
+
+					for (deUint32 numColorAtt = 0; numColorAtt < colorAttachmentCounts[colorAttachmentCount]; numColorAtt++)
+						testParams.blendOps.push_back(blendOps[blendOp]);
+					opsTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
+				}
+			}
+		}
+	}
+	tests->addChild(opsTests.release());
+
+	// Independent Blend Tests: test more than one color attachment.
+	de::MovePtr<tcu::TestCaseGroup> independentTests (new tcu::TestCaseGroup(testCtx, "independent", "Test independent blend feature"));
+	deUint32 testNumber = 0u;
+
+	for (deUint32 colorAttachmentCount = 1u; colorAttachmentCount < DE_LENGTH_OF_ARRAY(colorAttachmentCounts); colorAttachmentCount++)
+	{
+		BlendOperationAdvancedParam testParams;
+		testParams.testMode					= TEST_MODE_GENERIC;
+		testParams.overlap					= VK_BLEND_OVERLAP_UNCORRELATED_EXT;
+		testParams.coherentOperations		= DE_FALSE;
+		testParams.colorAttachmentsCount	= colorAttachmentCounts[colorAttachmentCount];
+		testParams.independentBlend			= DE_TRUE;
+		testParams.premultipliedSrcColor	= VK_TRUE;
+		testParams.premultipliedDstColor	= VK_TRUE;
+		testParams.testNumber				= testNumber++;
+
+		for (deUint32 numColorAtt = 0; numColorAtt < colorAttachmentCounts[colorAttachmentCount]; numColorAtt++)
+		{
+			deUint32 i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
+			testParams.blendOps.push_back(blendOps[i]);
+		}
+		independentTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
+	}
+
+	tests->addChild(independentTests.release());
+
+	// Coherent tests, do two consecutive advanced blending operations on the same color attachment.
+	de::MovePtr<tcu::TestCaseGroup> coherentTests (new tcu::TestCaseGroup(testCtx, "coherent", "Test coherent memory"));
+	testNumber = 0u;
+
+	for (deUint32 coherent = 0u; coherent < DE_LENGTH_OF_ARRAY(coherentOps); coherent++)
+	{
+		BlendOperationAdvancedParam testParams;
+		testParams.testMode					= TEST_MODE_COHERENT;
+		testParams.overlap					= VK_BLEND_OVERLAP_UNCORRELATED_EXT;
+		testParams.coherentOperations		= coherentOps[coherent];
+		testParams.colorAttachmentsCount	= 1u;
+		testParams.independentBlend			= DE_FALSE;
+		testParams.premultipliedSrcColor	= VK_TRUE;
+		testParams.premultipliedDstColor	= VK_TRUE;
+		testParams.testNumber				= testNumber++;
+
+		// We do two consecutive advanced blending operations
+		deUint32 i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
+		testParams.blendOps.push_back(blendOps[i]);
+		i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
+		testParams.blendOps.push_back(blendOps[i]);
+
+		coherentTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
+	}
+	tests->addChild(coherentTests.release());
+
+
+	return tests.release();
+}
+
+} // pipeline
+
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.hpp
new file mode 100644
index 0000000..2ce7706
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.hpp
@@ -0,0 +1,40 @@
+#ifndef _VKTPIPELINEBLENDOPERATIONADVANCEDTESTS_HPP
+#define _VKTPIPELINEBLENDOPERATIONADVANCEDTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Valve Corporation.
+ * Copyright (c) 2019 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 VK_EXT_blend_operation_advanced tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+tcu::TestCaseGroup* createBlendOperationAdvancedTests (tcu::TestContext& testCtx);
+
+} // Draw
+} // vkt
+
+#endif // _VKTPIPELINEBLENDOPERATIONADVANCEDTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp
index 86899f7..1402ba8 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp
@@ -30,6 +30,8 @@
 #include "vktPipelineReferenceRenderer.hpp"
 #include "vktTestCase.hpp"
 #include "vkImageUtil.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkBufferWithMemory.hpp"
 #include "vkMemUtil.hpp"
 #include "vkPlatform.hpp"
 #include "vkPrograms.hpp"
@@ -50,6 +52,8 @@
 #include <set>
 #include <sstream>
 #include <vector>
+#include <algorithm>
+#include <iterator>
 
 namespace vkt
 {
@@ -127,8 +131,6 @@
 	virtual tcu::TestStatus				iterate					(void);
 
 private:
-	static float						getNormChannelThreshold	(const tcu::TextureFormat& format, int numBits);
-	static tcu::Vec4					getFormatThreshold		(const tcu::TextureFormat& format);
 	tcu::TestStatus						verifyImage				(void);
 
 	VkPipelineColorBlendAttachmentState	m_blendStates[BlendTest::QUAD_COUNT];
@@ -581,7 +583,7 @@
 	return verifyImage();
 }
 
-float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
+float getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
 {
 	switch (tcu::getTextureChannelClass(format.type))
 	{
@@ -595,7 +597,7 @@
 	return 0.0f;
 }
 
-tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format)
+tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
 {
 	using tcu::Vec4;
 	using tcu::TextureFormat;
@@ -660,6 +662,10 @@
 			threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
 			break;
 
+		case TextureFormat::UNORM_SHORT_1555:
+			threshold = Vec4(0.1f, getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5));
+			break;
+
 		default:
 			DE_ASSERT(false);
 	}
@@ -879,6 +885,373 @@
 		return tcu::TestStatus::fail("Image mismatch");
 }
 
+// Clamping tests for colors and constants.
+
+struct ClampTestParams
+{
+	vk::VkFormat	colorFormat;
+	tcu::Vec4		quadColor;
+	tcu::Vec4		blendConstants;
+};
+
+class ClampTest : public vkt::TestCase
+{
+public:
+										ClampTest				(tcu::TestContext&							testContext,
+																 const std::string&							name,
+																 const std::string&							description,
+																 const ClampTestParams&						testParams);
+	virtual								~ClampTest				(void) {}
+	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
+	virtual void						checkSupport			(Context& context) const;
+	virtual TestInstance*				createInstance			(Context& context) const;
+
+private:
+	const ClampTestParams				m_params;
+};
+
+class ClampTestInstance : public vkt::TestInstance
+{
+public:
+								ClampTestInstance		(Context& context, const ClampTestParams& testParams)
+									: vkt::TestInstance(context), m_params(testParams)
+									{}
+	virtual						~ClampTestInstance		(void) {}
+	virtual tcu::TestStatus		iterate					(void);
+
+private:
+	const ClampTestParams		m_params;
+};
+
+ClampTest::ClampTest (tcu::TestContext&			testContext,
+					  const std::string&		name,
+					  const std::string&		description,
+					  const ClampTestParams&	testParams)
+	: vkt::TestCase (testContext, name, description)
+	, m_params(testParams)
+{
+	// As per the spec:
+	//
+	//  If the color attachment is fixed-point, the components of the source and destination values and blend factors are each
+	//  clamped to [0,1] or [-1,1] respectively for an unsigned normalized or signed normalized color attachment prior to evaluating
+	//  the blend operations. If the color attachment is floating-point, no clamping occurs.
+	//
+	// We will only test signed and unsigned normalized formats, and avoid precision problems by having all channels have the same
+	// bit depth.
+	//
+	DE_ASSERT(isSnormFormat(m_params.colorFormat) || isUnormFormat(m_params.colorFormat));
+
+	const auto bitDepth = tcu::getTextureFormatBitDepth(mapVkFormat(m_params.colorFormat));
+	DE_UNREF(bitDepth); // For release builds.
+	DE_ASSERT(bitDepth[0] == bitDepth[1] && bitDepth[0] == bitDepth[2] && bitDepth[0] == bitDepth[3]);
+}
+
+void ClampTest::initPrograms (SourceCollections& sourceCollections) const
+{
+	std::ostringstream fragmentSource;
+
+	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
+		"#version 310 es\n"
+		"layout(location = 0) in highp vec4 position;\n"
+		"layout(location = 1) in highp vec4 color;\n"
+		"layout(location = 0) out highp vec4 vtxColor;\n"
+		"void main (void)\n"
+		"{\n"
+		"	gl_Position = position;\n"
+		"	vtxColor = color;\n"
+		"}\n");
+
+	fragmentSource << "#version 310 es\n"
+		"layout(location = 0) in highp vec4 vtxColor;\n"
+		"layout(location = 0) out highp vec4 fragColor;\n"
+		"void main (void)\n"
+		"{\n"
+		"	fragColor = vtxColor;\n"
+		"}\n";
+
+	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
+}
+
+void ClampTest::checkSupport (Context& context) const
+{
+	if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.colorFormat))
+		throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_params.colorFormat));
+}
+
+TestInstance* ClampTest::createInstance(Context& context) const
+{
+	return new ClampTestInstance(context, m_params);
+}
+
+tcu::TestStatus ClampTestInstance::iterate (void)
+{
+	const vk::DeviceInterface&	vkd					= m_context.getDeviceInterface();
+	const vk::VkDevice			device				= m_context.getDevice();
+	vk::Allocator&				allocator			= m_context.getDefaultAllocator();
+	const vk::VkQueue			queue				= m_context.getUniversalQueue();
+	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
+	const vk::VkExtent3D		renderSize			= { 32u, 32u, 1u };
+
+	// Image.
+	const vk::VkImageCreateInfo	imageCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
+		nullptr,																		// const void*				pNext;
+		0u,																				// VkImageCreateFlags		flags;
+		vk::VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
+		m_params.colorFormat,															// VkFormat					format;
+		renderSize,																		// VkExtent3D				extent;
+		1u,																				// deUint32					mipLevels;
+		1u,																				// deUint32					arrayLayers;
+		vk::VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
+		vk::VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
+		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
+		vk::VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
+		1u,																				// deUint32					queueFamilyIndexCount;
+		&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
+		vk::VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
+	};
+
+	vk::ImageWithMemory colorImage (vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any);
+
+	// Image view.
+	const vk::VkImageViewCreateInfo imageViewCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+		nullptr,											// const void*				pNext;
+		0u,													// VkImageViewCreateFlags	flags;
+		colorImage.get(),									// VkImage					image;
+		vk::VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
+		m_params.colorFormat,								// VkFormat					format;
+		{													// VkComponentMapping		components;
+			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
+			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
+			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
+			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
+		},
+		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
+	};
+
+	auto colorImageView = createImageView(vkd, device, &imageViewCreateInfo);
+
+	// Render pass.
+	auto renderPass = makeRenderPass(vkd, device, m_params.colorFormat);
+
+	// Frame buffer.
+	const vk::VkFramebufferCreateInfo framebufferParams =
+	{
+		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType			sType;
+		nullptr,											// const void*				pNext;
+		0u,													// VkFramebufferCreateFlags	flags;
+		renderPass.get(),									// VkRenderPass				renderPass;
+		1u,													// deUint32					attachmentCount;
+		&colorImageView.get(),								// const VkImageView*		pAttachments;
+		renderSize.width,									// deUint32					width;
+		renderSize.height,									// deUint32					height;
+		1u,													// deUint32					layers;
+	};
+
+	auto framebuffer = createFramebuffer(vkd, device, &framebufferParams);
+
+	// Pipeline layout.
+	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
+		nullptr,											// const void*						pNext;
+		0u,													// VkPipelineLayoutCreateFlags		flags;
+		0u,													// deUint32							setLayoutCount;
+		nullptr,											// const VkDescriptorSetLayout*		pSetLayouts;
+		0u,													// deUint32							pushConstantRangeCount;
+		nullptr,											// const VkPushConstantRange*		pPushConstantRanges;
+	};
+
+	auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
+
+	// Shader modules.
+	auto vertexShaderModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get("color_vert"), 0);
+	auto fragmentShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("color_frag"), 0);
+
+	// Graphics pipeline.
+	const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
+	{
+		0u,									// deUint32					binding;
+		sizeof(Vertex4RGBA),				// deUint32					strideInBytes;
+		vk::VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	inputRate;
+	};
+
+	const vk::VkVertexInputAttributeDescription	vertexInputAttributeDescriptions[2]	=
+	{
+		{
+			0u,									// deUint32	location;
+			0u,									// deUint32	binding;
+			vk::VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
+			0u									// deUint32	offset;
+		},
+		{
+			1u,														// deUint32	location;
+			0u,														// deUint32	binding;
+			vk::VK_FORMAT_R32G32B32A32_SFLOAT,						// VkFormat	format;
+			static_cast<deUint32>(offsetof(Vertex4RGBA, color)),	// deUint32	offset;
+		},
+	};
+
+	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
+	{
+		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,					// VkStructureType							sType;
+		nullptr,																		// const void*								pNext;
+		0u,																				// VkPipelineVertexInputStateCreateFlags	flags;
+		1u,																				// deUint32									vertexBindingDescriptionCount;
+		&vertexInputBindingDescription,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		static_cast<deUint32>(DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions)),	// deUint32									vertexAttributeDescriptionCount;
+		vertexInputAttributeDescriptions,												// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+	};
+
+	const std::vector<vk::VkViewport>	viewports	(1, makeViewport(renderSize));
+	const std::vector<vk::VkRect2D>		scissors	(1, makeRect2D(renderSize));
+
+	const vk::VkColorComponentFlags colorComponentFlags = (0u
+		| vk::VK_COLOR_COMPONENT_R_BIT
+		| vk::VK_COLOR_COMPONENT_G_BIT
+		| vk::VK_COLOR_COMPONENT_B_BIT
+		| vk::VK_COLOR_COMPONENT_A_BIT
+	);
+
+	// Color blend attachment state. Central aspect of the test.
+	const vk::VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+	{
+		VK_TRUE,							// VkBool32					blendEnable;
+		vk::VK_BLEND_FACTOR_CONSTANT_COLOR,	// VkBlendFactor			srcColorBlendFactor;
+		vk::VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
+		vk::VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
+		vk::VK_BLEND_FACTOR_CONSTANT_ALPHA,	// VkBlendFactor			srcAlphaBlendFactor;
+		vk::VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
+		vk::VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
+		colorComponentFlags,				// VkColorComponentFlags	colorWriteMask;
+	};
+
+	const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
+	{
+		vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+		nullptr,														// const void*									pNext;
+		0u,																// VkPipelineColorBlendStateCreateFlags			flags;
+		false,															// VkBool32										logicOpEnable;
+		vk::VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+		1u,																// deUint32										attachmentCount;
+		&colorBlendAttachmentState,										// const VkPipelineColorBlendAttachmentState*	pAttachments;
+		{																// float										blendConstants[4];
+			m_params.blendConstants[0],
+			m_params.blendConstants[1],
+			m_params.blendConstants[2],
+			m_params.blendConstants[3],
+		},
+	};
+
+	auto graphicsPipeline = makeGraphicsPipeline(
+		vkd,										// const DeviceInterface&                        vk
+		device,										// const VkDevice                                device
+		pipelineLayout.get(),						// const VkPipelineLayout                        pipelineLayout
+		vertexShaderModule.get(),					// const VkShaderModule                          vertexShaderModule
+		DE_NULL,									// const VkShaderModule                          tessellationControlModule
+		DE_NULL,									// const VkShaderModule                          tessellationEvalModule
+		DE_NULL,									// const VkShaderModule                          geometryShaderModule
+		fragmentShaderModule.get(),					// const VkShaderModule                          fragmentShaderModule
+		renderPass.get(),							// const VkRenderPass                            renderPass
+		viewports,									// const std::vector<VkViewport>&                viewports
+		scissors,									// const std::vector<VkRect2D>&                  scissors
+		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
+		0u,											// const deUint32                                subpass
+		0u,											// const deUint32                                patchControlPoints
+		&vertexInputStateParams,					// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
+		nullptr,									// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
+		nullptr,									// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
+		nullptr,									// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
+		&colorBlendStateParams);					// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
+
+	// Vertex buffer
+	auto						quadTexture = createFullscreenQuad();
+	std::vector<Vertex4RGBA>	vertices;
+
+	// Keep position but replace texture coordinates with our own color.
+	vertices.reserve(quadTexture.size());
+	std::transform(begin(quadTexture), end(quadTexture), std::back_inserter(vertices),
+		[this](const decltype(quadTexture)::value_type& v) { return Vertex4RGBA{ v.position, this->m_params.quadColor }; });
+
+	const vk::VkDeviceSize			vtxBufferSize		= static_cast<vk::VkDeviceSize>(vertices.size() * sizeof(decltype(vertices)::value_type));
+	const vk::VkBufferCreateInfo	bufferCreateInfo	=
+	{
+		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
+		nullptr,									// const void*			pNext;
+		0u,											// VkBufferCreateFlags	flags;
+		vtxBufferSize,								// VkDeviceSize			size;
+		vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
+		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
+		1u,											// deUint32				queueFamilyIndexCount;
+		&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
+	};
+
+	vk::BufferWithMemory vertexBuffer(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
+
+	// Upload vertex data
+	deMemcpy(vertexBuffer.getAllocation().getHostPtr(), vertices.data(), static_cast<size_t>(vtxBufferSize));
+	flushAlloc(vkd, device, vertexBuffer.getAllocation());
+
+	// Create command pool
+	auto cmdPool = createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
+
+	// Create and record command buffer
+	auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+	auto cmdBuffer		= cmdBufferPtr.get();
+
+	vk::VkClearValue clearValue;
+	clearValue.color.float32[0] = 0.0f;
+	clearValue.color.float32[1] = 0.0f;
+	clearValue.color.float32[2] = 0.0f;
+	clearValue.color.float32[3] = 1.0f;
+
+	const vk::VkDeviceSize vertexOffets[] = { 0u };
+
+	beginCommandBuffer(vkd, cmdBuffer, 0u);
+		beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(renderSize), clearValue);
+			vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
+			vkd.cmdBindVertexBuffers(cmdBuffer, 0, 1u, &vertexBuffer.get(), vertexOffets);
+			vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1, 0, 0);
+		endRenderPass(vkd, cmdBuffer);
+	endCommandBuffer(vkd, cmdBuffer);
+
+	// Submit commands.
+	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
+
+	// Calculate reference final color.
+	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_params.colorFormat);
+	const auto					formatInfo		= tcu::getTextureFormatInfo(tcuColorFormat);
+
+	tcu::Vec4 clampedBlendConstants	= m_params.blendConstants;
+	tcu::Vec4 clampedQuadColor		= m_params.quadColor;
+
+	for (int i = 0; i < tcu::Vec4::SIZE; ++i)
+	{
+		clampedBlendConstants[i]	= de::clamp(clampedBlendConstants[i],	formatInfo.valueMin[i], formatInfo.valueMax[i]);
+		clampedQuadColor[i]			= de::clamp(clampedQuadColor[i],		formatInfo.valueMin[i], formatInfo.valueMax[i]);
+	}
+
+	tcu::Vec4 referenceColor;
+	for (int i = 0; i < tcu::Vec4::SIZE; ++i)
+		referenceColor[i] = clampedBlendConstants[i] * clampedQuadColor[i];
+
+	// Compare result with reference color
+	const tcu::UVec2					renderSizeUV2		(renderSize.width, renderSize.height);
+	de::UniquePtr<tcu::TextureLevel>	result				(readColorAttachment(vkd, device, queue, queueFamilyIndex, allocator, colorImage.get(), m_params.colorFormat, renderSizeUV2).release());
+	const tcu::Vec4						threshold			(getFormatThreshold(tcuColorFormat));
+	const tcu::ConstPixelBufferAccess	pixelBufferAccess	= result->getAccess();
+
+	const bool compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "BlendClampCompare", "Blend clamping pixel comparison", referenceColor, pixelBufferAccess, threshold, tcu::COMPARE_LOG_ON_ERROR);
+
+	if (compareOk)
+		return tcu::TestStatus::pass("Pass");
+	else
+		return tcu::TestStatus::fail("Pixel mismatch");
+}
+
 } // anonymous
 
 std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
@@ -966,6 +1339,7 @@
 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
 		VK_FORMAT_R5G6B5_UNORM_PACK16,
 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
+		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
 		VK_FORMAT_R8_UNORM,
 		VK_FORMAT_R8_SNORM,
 		VK_FORMAT_R8_SRGB,
@@ -979,6 +1353,7 @@
 		VK_FORMAT_R8G8B8A8_SNORM,
 		VK_FORMAT_R8G8B8A8_SRGB,
 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
 		VK_FORMAT_R16_UNORM,
 		VK_FORMAT_R16_SNORM,
 		VK_FORMAT_R16_SFLOAT,
@@ -1003,6 +1378,7 @@
 
 	de::MovePtr<tcu::TestCaseGroup>		blendTests		(new tcu::TestCaseGroup(testCtx, "blend", "Blend tests"));
 	de::MovePtr<tcu::TestCaseGroup>		formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));
+	de::MovePtr<tcu::TestCaseGroup>		clampTests		(new tcu::TestCaseGroup(testCtx, "clamp", "Verifies clamping for normalized formats"));
 	BlendStateUniqueRandomIterator		blendStateItr	(blendStatesPerFormat, 123);
 
 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
@@ -1039,7 +1415,55 @@
 		formatTest->addChild(blendStateTests.release());
 		formatTests->addChild(formatTest.release());
 	}
+
+	// Subselection of formats that are easy to test for clamping.
+	const vk::VkFormat clampFormats[] =
+	{
+		vk::VK_FORMAT_R8G8B8A8_UNORM,
+		vk::VK_FORMAT_R8G8B8A8_SNORM,
+		vk::VK_FORMAT_B8G8R8A8_UNORM,
+		vk::VK_FORMAT_B8G8R8A8_SNORM,
+		vk::VK_FORMAT_R16G16B16A16_UNORM,
+		vk::VK_FORMAT_R16G16B16A16_SNORM,
+	};
+
+	for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(clampFormats); ++formatIdx)
+	{
+		const auto& format = clampFormats[formatIdx];
+		ClampTestParams testParams;
+
+		testParams.colorFormat = format;
+
+		if (isUnormFormat(format))
+		{
+			testParams.quadColor[0] = 2.0f;
+			testParams.quadColor[1] = 0.5f;
+			testParams.quadColor[2] = 1.0f;
+			testParams.quadColor[3] = -1.0f;
+
+			testParams.blendConstants[0] = 0.5f;
+			testParams.blendConstants[1] = 2.0f;
+			testParams.blendConstants[2] = -1.0f;
+			testParams.blendConstants[3] = 1.0f;
+		}
+		else
+		{
+			testParams.quadColor[0] = 2.0f;
+			testParams.quadColor[1] = 0.5f;
+			testParams.quadColor[2] = 1.0f;
+			testParams.quadColor[3] = -2.0f;
+
+			testParams.blendConstants[0] = 0.5f;
+			testParams.blendConstants[1] = 2.0f;
+			testParams.blendConstants[2] = -2.0f;
+			testParams.blendConstants[3] = 1.0f;
+		}
+
+		clampTests->addChild(new ClampTest(testCtx, getFormatCaseName(format), std::string("Using format ") + getFormatName(format), testParams));
+	}
+
 	blendTests->addChild(formatTests.release());
+	blendTests->addChild(clampTests.release());
 
 	return blendTests.release();
 }
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineCreationFeedbackTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineCreationFeedbackTests.cpp
index 4e95648..e59314b 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineCreationFeedbackTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineCreationFeedbackTests.cpp
@@ -140,27 +140,31 @@
 public:
 								CacheTestParam				(const VkShaderStageFlagBits*	shaders,
 															 deUint32						count,
-															 deBool							noCache);
+															 deBool							noCache,
+															 deBool							delayedDestroy);
 	virtual					~CacheTestParam					(void);
 	virtual const std::string	generateTestName			(void)			const;
 	virtual const std::string	generateTestDescription		(void)			const;
 	VkShaderStageFlagBits		getShaderFlag				(deUint32 ndx)	const	{ return m_shaders[ndx]; }
 	deUint32					getShaderCount				(void)			const	{ return (deUint32)m_shaderCount; }
 	deBool						isCacheDisabled				(void)			const	{ return m_noCache; }
+	deBool						isDelayedDestroy			(void)			const	{ return m_delayedDestroy; }
 
 protected:
 	VkShaderStageFlagBits		m_shaders[VK_MAX_SHADER_STAGES];
 	size_t						m_shaderCount;
 	bool						m_noCache;
+	bool						m_delayedDestroy;
 };
 
-CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool noCache)
+CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool noCache, deBool delayedDestroy)
 {
 	DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
 	for (deUint32 ndx = 0; ndx < count; ndx++)
 		m_shaders[ndx] = shaders[ndx];
-	m_shaderCount	= count;
-	m_noCache		= noCache;
+	m_shaderCount		= count;
+	m_noCache			= noCache;
+	m_delayedDestroy	= delayedDestroy;
 }
 
 CacheTestParam::~CacheTestParam (void)
@@ -171,12 +175,13 @@
 {
 	std::string result(getShaderFlagStr(m_shaders[0], false));
 	std::string cacheString [] = { "", "_no_cache" };
+	std::string delayedDestroyString [] = { "", "_delayed_destroy" };
 
 	for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
-		result += '_' + getShaderFlagStr(m_shaders[ndx], false) + cacheString[m_noCache ? 1 : 0];
+		result += '_' + getShaderFlagStr(m_shaders[ndx], false) + cacheString[m_noCache ? 1 : 0] + delayedDestroyString[m_delayedDestroy ? 1 : 0];
 
 	if (m_shaderCount == 1)
-		result += cacheString[m_noCache ? 1 : 0];
+		result += cacheString[m_noCache ? 1 : 0] + delayedDestroyString[m_delayedDestroy ? 1 : 0];
 
 	return result;
 }
@@ -186,6 +191,8 @@
 	std::string result("Get pipeline creation feedback with " + getShaderFlagStr(m_shaders[0], true));
 	if (m_noCache)
 		result += " with no cache";
+	if (m_delayedDestroy)
+		result += " with delayed destroy";
 
 	for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
 		result += ' ' + getShaderFlagStr(m_shaders[ndx], true);
@@ -802,9 +809,10 @@
 				break;
 			};
 		}
-		if (ndx == PIPELINE_CACHE_NDX_CACHED)
+		if (ndx == PIPELINE_CACHE_NDX_CACHED && !param->isDelayedDestroy())
 		{
-			// Destroy the NO_CACHE pipeline to check that the cached one really hits cache
+			// Destroy the NO_CACHE pipeline to check that the cached one really hits cache,
+			// except for the case where we're testing cache hit of a pipeline still active.
 			vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
 		}
 
@@ -819,7 +827,13 @@
 			// Destroy the pipeline as soon as it is created, except the NO_CACHE because
 			// it is needed as a base pipeline for the derivative case.
 			vk.destroyPipeline(vkDevice, m_pipeline[ndx], DE_NULL);
-		}
+
+			if (ndx == PIPELINE_CACHE_NDX_CACHED && param->isDelayedDestroy())
+			{
+				// Destroy the pipeline we didn't destroy earlier for the isDelayedDestroy case.
+				vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
+			}
+	}
 	}
 }
 
@@ -959,9 +973,9 @@
 	virtual					~ComputeCacheTestInstance	(void);
 protected:
 	virtual tcu::TestStatus verifyTestResult				(void);
-			void			buildDescriptorSets			(deUint32 ndx);
-			void			buildShader					(deUint32 ndx);
-			void			buildPipeline					(deUint32 ndx);
+			void			buildDescriptorSets				(deUint32 ndx);
+			void			buildShader						(deUint32 ndx);
+			void			buildPipeline					(const CacheTestParam*	param, deUint32 ndx);
 protected:
 	Move<VkBuffer>					m_inputBuf;
 	de::MovePtr<Allocation>		m_inputBufferAlloc;
@@ -1056,7 +1070,7 @@
 	m_computeShaderModule[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
 }
 
-void ComputeCacheTestInstance::buildPipeline (deUint32 ndx)
+void ComputeCacheTestInstance::buildPipeline (const CacheTestParam*	param, deUint32 ndx)
 {
 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
 	const VkDevice			vkDevice		 = m_context.getDevice();
@@ -1121,9 +1135,10 @@
 		pipelineCreateInfo.basePipelineIndex = -1;
 	}
 
-	if (ndx == PIPELINE_CACHE_NDX_CACHED)
+	if (ndx == PIPELINE_CACHE_NDX_CACHED && !param->isDelayedDestroy())
 	{
-		// Destroy the NO_CACHE pipeline to check that the cached one really hits cache
+		// Destroy the NO_CACHE pipeline to check that the cached one really hits cache,
+		// except for the case where we're testing cache hit of a pipeline still active.
 		vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
 	}
 
@@ -1134,6 +1149,12 @@
 		// Destroy the pipeline as soon as it is created, except the NO_CACHE because
 		// it is needed as a base pipeline for the derivative case.
 		vk.destroyPipeline(vkDevice, m_pipeline[ndx], DE_NULL);
+
+		if (ndx == PIPELINE_CACHE_NDX_CACHED && param->isDelayedDestroy())
+		{
+			// Destroy the pipeline we didn't destroy earlier for the isDelayedDestroy case.
+			vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
+		}
 	}
 }
 
@@ -1145,7 +1166,7 @@
 	{
 		buildDescriptorSets(ndx);
 		buildShader(ndx);
-		buildPipeline(ndx);
+		buildPipeline(param, ndx);
 	}
 }
 
@@ -1298,12 +1319,15 @@
 		};
 		const CacheTestParam testParams[] =
 		{
-			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE),
-			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE),
-			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE),
-			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE),
-			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE),
-			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
+			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
+			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
+			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
+			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
+			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
+			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
 		};
 
 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
@@ -1322,8 +1346,9 @@
 		};
 		const CacheTestParam testParams[] =
 		{
-			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE),
-			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
+			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
 		};
 
 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
index 58d9eb1..5ae09af 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
@@ -188,6 +188,7 @@
 
 void checkSupportImageSamplingInstance (Context& context, ImageSamplingInstanceParams params)
 {
+
 	if (de::abs(params.samplerParams.mipLodBias) > context.getDeviceProperties().limits.maxSamplerLodBias)
 		TCU_THROW(NotSupportedError, "Unsupported sampler Lod bias value");
 
@@ -208,9 +209,9 @@
 		context.requireDeviceFunctionality("VK_EXT_separate_stencil_usage");
 		context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
 
-		const VkImageStencilUsageCreateInfoEXT  stencilUsage	=
+		const VkImageStencilUsageCreateInfo  stencilUsage	=
 		{
-			VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT,
+			VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
 			DE_NULL,
 			VK_IMAGE_USAGE_TRANSFER_DST_BIT
 		};
@@ -339,7 +340,7 @@
 		{
 			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT:
 			{
-				VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT	physicalDeviceSamplerMinMaxProperties =
+				VkPhysicalDeviceSamplerFilterMinmaxProperties	physicalDeviceSamplerMinMaxProperties =
 				{
 					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT,
 					DE_NULL,
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp
index 221aff8..4d790a5 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp
@@ -642,6 +642,9 @@
 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
+		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+		VK_FORMAT_A2B10G10R10_UINT_PACK32,
+		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
 		VK_FORMAT_R16_UNORM,
 		VK_FORMAT_R16_SNORM,
 		VK_FORMAT_R16_USCALED,
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp
index 6652b4d..34c6eb4 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp
@@ -1179,7 +1179,7 @@
 {
 	DE_ASSERT(!isCompressed());
 
-	de::MovePtr<TestTexture>	texture	(new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight()));
+	de::MovePtr<TestTexture>	texture	(new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getNumLevels()));
 
 	copyToTexture(*texture);
 
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMakeUtil.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMakeUtil.hpp
index ad11c14..cc1e57d 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMakeUtil.hpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMakeUtil.hpp
@@ -81,6 +81,18 @@
 de::MovePtr<vk::Allocation>		bindImageDedicated		(const vk::InstanceInterface& vki, const vk::DeviceInterface& vkd, const vk::VkPhysicalDevice physDevice, const vk::VkDevice device, const vk::VkImage image, const vk::MemoryRequirement requirement);
 de::MovePtr<vk::Allocation>		bindBufferDedicated		(const vk::InstanceInterface& vki, const vk::DeviceInterface& vkd, const vk::VkPhysicalDevice physDevice, const vk::VkDevice device, const vk::VkBuffer buffer, const vk::MemoryRequirement requirement);
 
+template<typename T>
+inline const T* dataOrNullPtr(const std::vector<T>& v)
+{
+	return (v.empty() ? DE_NULL : &v[0]);
+}
+
+template<typename T>
+inline T* dataOrNullPtr(std::vector<T>& v)
+{
+	return (v.empty() ? DE_NULL : &v[0]);
+}
+
 } // pipeline
 } // vkt
 
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.cpp
new file mode 100644
index 0000000..0a3f96e
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.cpp
@@ -0,0 +1,2054 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_mixed_attachment_samples
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
+#include "vktPipelineSampleLocationsUtil.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vktTestCase.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkImageUtil.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
+#include "deRandom.hpp"
+#include "deMath.h"
+
+#include "tcuVector.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuRGBA.hpp"
+
+#include <string>
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace
+{
+using namespace vk;
+using de::UniquePtr;
+using de::MovePtr;
+using de::SharedPtr;
+using tcu::UVec2;
+using tcu::Vec2;
+using tcu::Vec4;
+
+bool compareGreenImage (tcu::TestLog& log, const char* name, const char* description, const tcu::ConstPixelBufferAccess& image)
+{
+	tcu::TextureLevel greenImage(image.getFormat(), image.getWidth(), image.getHeight());
+	tcu::clear(greenImage.getAccess(), tcu::RGBA::green().toIVec());
+	return tcu::intThresholdCompare(log, name, description, greenImage.getAccess(), image, tcu::UVec4(2u), tcu::COMPARE_LOG_RESULT);
+}
+
+VkImageAspectFlags getImageAspectFlags (const VkFormat format)
+{
+	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
+
+	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
+	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
+
+	DE_ASSERT(false);
+	return 0u;
+}
+
+struct CompareData
+{
+	Vec4		color;
+	float		depth;
+	deUint32	stencil;
+
+	// Pad to 2*16 bytes, in the shader the base alignment of this structure is 16 due to vec4
+	deUint32	padding[2];
+
+	CompareData() : color(Vec4(0.0f)), depth(0.0f), stencil(0u)
+	{
+		padding[0] = 0u;
+		padding[1] = 0u;
+
+		static_assert(sizeof(CompareData) == (2 * 16), "Wrong structure size, expected 16 bytes");
+	}
+};
+
+//! Make a dummy sampler.
+Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
+{
+	const VkSamplerCreateInfo samplerParams =
+	{
+		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			// VkStructureType         sType;
+		DE_NULL,										// const void*             pNext;
+		(VkSamplerCreateFlags)0,						// VkSamplerCreateFlags    flags;
+		VK_FILTER_NEAREST,								// VkFilter                magFilter;
+		VK_FILTER_NEAREST,								// VkFilter                minFilter;
+		VK_SAMPLER_MIPMAP_MODE_NEAREST,					// VkSamplerMipmapMode     mipmapMode;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeU;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeV;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeW;
+		0.0f,											// float                   mipLodBias;
+		VK_FALSE,										// VkBool32                anisotropyEnable;
+		1.0f,											// float                   maxAnisotropy;
+		VK_FALSE,										// VkBool32                compareEnable;
+		VK_COMPARE_OP_ALWAYS,							// VkCompareOp             compareOp;
+		0.0f,											// float                   minLod;
+		0.0f,											// float                   maxLod;
+		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		// VkBorderColor           borderColor;
+		VK_FALSE,										// VkBool32                unnormalizedCoordinates;
+	};
+	return createSampler(vk, device, &samplerParams);
+}
+
+Move<VkImage> makeImage (const DeviceInterface&			vk,
+						 const VkDevice					device,
+						 const VkFormat					format,
+						 const UVec2&					size,
+						 const VkSampleCountFlagBits	samples,
+						 const VkImageUsageFlags		usage)
+{
+	const VkImageCreateInfo imageParams =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
+		DE_NULL,										// const void*				pNext;
+		(VkImageCreateFlags)0,							// VkImageCreateFlags		flags;
+		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
+		format,											// VkFormat					format;
+		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
+		1u,												// deUint32					mipLevels;
+		1u,												// deUint32					arrayLayers;
+		samples,										// VkSampleCountFlagBits	samples;
+		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
+		usage,											// VkImageUsageFlags		usage;
+		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
+		0u,												// deUint32					queueFamilyIndexCount;
+		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
+	};
+	return createImage(vk, device, &imageParams);
+}
+
+inline bool isDepthFormat (const VkFormat format)
+{
+	return (getImageAspectFlags(format) & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
+}
+
+inline bool isStencilFormat (const VkFormat format)
+{
+	return (getImageAspectFlags(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
+}
+
+//! Create a test-specific MSAA pipeline
+Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&					vk,
+									   const VkDevice							device,
+									   const VkPipelineLayout					pipelineLayout,
+									   const VkRenderPass						renderPass,
+									   const VkShaderModule						vertexModule,
+									   const VkShaderModule						fragmentModule,
+									   const bool								useVertexInput,
+									   const deUint32							subpassNdx,
+									   const UVec2&								renderSize,
+									   const VkImageAspectFlags					depthStencilAspect,	//!< Used to determine which D/S tests to turn on
+									   const VkSampleCountFlagBits				numSamples,
+									   const bool								sampleShadingEnable,
+									   const VkSampleLocationsInfoEXT*			pSampleLocationsInfo = DE_NULL)
+{
+	std::vector<VkVertexInputBindingDescription>	vertexInputBindingDescriptions;
+	std::vector<VkVertexInputAttributeDescription>	vertexInputAttributeDescriptions;
+
+	// Vertex attributes: position and color
+	if (useVertexInput)
+	{
+		vertexInputBindingDescriptions.push_back  (makeVertexInputBindingDescription  (0u, 2 * sizeof(Vec4), VK_VERTEX_INPUT_RATE_VERTEX));
+		vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u));
+		vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(Vec4)));
+	}
+
+	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags	flags;
+		static_cast<deUint32>(vertexInputBindingDescriptions.size()),	// uint32_t									vertexBindingDescriptionCount;
+		dataOrNullPtr(vertexInputBindingDescriptions),					// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		static_cast<deUint32>(vertexInputAttributeDescriptions.size()),	// uint32_t									vertexAttributeDescriptionCount;
+		dataOrNullPtr(vertexInputAttributeDescriptions),				// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+	};
+
+	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
+		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
+		VK_FALSE,														// VkBool32									primitiveRestartEnable;
+	};
+
+	const VkViewport viewport =
+	{
+		0.0f, 0.0f,																	// x, y
+		static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),		// widht, height
+		0.0f, 1.0f																	// minDepth, maxDepth
+	};
+
+	const VkRect2D scissor =
+	{
+		makeOffset2D(0, 0),
+		makeExtent2D(renderSize.x(), renderSize.y()),
+	};
+
+	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
+		DE_NULL,														// const void*							pNext;
+		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags	flags;
+		1u,																// uint32_t								viewportCount;
+		&viewport,														// const VkViewport*					pViewports;
+		1u,																// uint32_t								scissorCount;
+		&scissor,														// const VkRect2D*						pScissors;
+	};
+
+	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags	flags;
+		VK_FALSE,													// VkBool32									depthClampEnable;
+		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
+		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
+		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
+		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
+		VK_FALSE,													// VkBool32									depthBiasEnable;
+		0.0f,														// float									depthBiasConstantFactor;
+		0.0f,														// float									depthBiasClamp;
+		0.0f,														// float									depthBiasSlopeFactor;
+		1.0f,														// float									lineWidth;
+	};
+
+	VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT,	// VkStructureType             sType;
+		DE_NULL,															// const void*                 pNext;
+		VK_TRUE,															// VkBool32                    sampleLocationsEnable;
+		VkSampleLocationsInfoEXT(),											// VkSampleLocationsInfoEXT    sampleLocationsInfo;
+	};
+
+	VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
+		numSamples,													// VkSampleCountFlagBits					rasterizationSamples;
+		sampleShadingEnable,										// VkBool32									sampleShadingEnable;
+		1.0f,														// float									minSampleShading;
+		DE_NULL,													// const VkSampleMask*						pSampleMask;
+		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
+		VK_FALSE													// VkBool32									alphaToOneEnable;
+	};
+
+	if (pSampleLocationsInfo)
+	{
+		pipelineSampleLocationsCreateInfo.sampleLocationsInfo	= *pSampleLocationsInfo;
+		pipelineMultisampleStateInfo.pNext						= &pipelineSampleLocationsCreateInfo;
+	}
+
+	// Simply increment the buffer
+	const VkStencilOpState stencilOpState = makeStencilOpState(
+		VK_STENCIL_OP_KEEP,						// stencil fail
+		VK_STENCIL_OP_INCREMENT_AND_CLAMP,		// depth & stencil pass
+		VK_STENCIL_OP_KEEP,						// depth only fail
+		VK_COMPARE_OP_ALWAYS,					// compare op
+		~0u,									// compare mask
+		~0u,									// write mask
+		0u);									// reference
+
+	// Always pass the depth test
+	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
+		(depthStencilAspect & VK_IMAGE_ASPECT_DEPTH_BIT) != 0u,		// VkBool32									depthTestEnable;
+		VK_TRUE,													// VkBool32									depthWriteEnable;
+		VK_COMPARE_OP_ALWAYS,										// VkCompareOp								depthCompareOp;
+		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
+		(depthStencilAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0u,	// VkBool32									stencilTestEnable;
+		stencilOpState,												// VkStencilOpState							front;
+		stencilOpState,												// VkStencilOpState							back;
+		0.0f,														// float									minDepthBounds;
+		1.0f,														// float									maxDepthBounds;
+	};
+
+	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+	const VkPipelineColorBlendAttachmentState defaultBlendAttachmentState =
+	{
+		VK_FALSE,				// VkBool32					blendEnable;
+		VK_BLEND_FACTOR_ONE,	// VkBlendFactor			srcColorBlendFactor;
+		VK_BLEND_FACTOR_ZERO,	// VkBlendFactor			dstColorBlendFactor;
+		VK_BLEND_OP_ADD,		// VkBlendOp				colorBlendOp;
+		VK_BLEND_FACTOR_ONE,	// VkBlendFactor			srcAlphaBlendFactor;
+		VK_BLEND_FACTOR_ZERO,	// VkBlendFactor			dstAlphaBlendFactor;
+		VK_BLEND_OP_ADD,		// VkBlendOp				alphaBlendOp;
+		colorComponentsAll,		// VkColorComponentFlags	colorWriteMask;
+	};
+
+	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
+		VK_FALSE,													// VkBool32										logicOpEnable;
+		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+		1u,															// deUint32										attachmentCount;
+		&defaultBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
+		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
+	};
+
+	const VkPipelineShaderStageCreateInfo pShaderStages[] =
+	{
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			DE_NULL,												// const void*							pNext;
+			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+			VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
+			vertexModule,											// VkShaderModule						module;
+			"main",													// const char*							pName;
+			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+		},
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			DE_NULL,												// const void*							pNext;
+			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+			VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
+			fragmentModule,											// VkShaderModule						module;
+			"main",													// const char*							pName;
+			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+		}
+	};
+
+	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+	{
+		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
+		DE_NULL,											// const void*										pNext;
+		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
+		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
+		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
+		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
+		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
+		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
+		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
+		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
+		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
+		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
+		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
+		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
+		pipelineLayout,										// VkPipelineLayout									layout;
+		renderPass,											// VkRenderPass										renderPass;
+		subpassNdx,											// deUint32											subpass;
+		DE_NULL,											// VkPipeline										basePipelineHandle;
+		-1,													// deInt32											basePipelineIndex;
+	};
+
+	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
+}
+
+//! Wrap float after an increment
+inline float wrapIncFloat (float a, float min, float max)
+{
+	return deFloatMax(min, deFloatMod(a, max));
+}
+
+//! Generate expected data for color, depth, and stencil samples of a given image.
+//! Samples are ordered starting at pixel (0, 0) - see compute shader source for reference.
+std::vector<CompareData> generateCompareData (const deUint32	seed,
+											  const UVec2&		imageSize,
+											  const deUint32	numCoverageSamples,
+											  const deUint32	numColorSamples,
+											  const deUint32	numDepthStencilSamples)
+{
+	std::vector<CompareData>	allData;
+	de::Random					rng (seed);
+
+	for (deUint32 y		 = 0u; y	  < imageSize.y();		++y)
+	for (deUint32 x		 = 0u; x	  < imageSize.x();		++x)
+	for (deUint32 sample = 0u; sample < numCoverageSamples; ++sample)
+	{
+		CompareData cd;
+
+		if (sample < numColorSamples)
+		{
+			for (int i = 0; i < 3; ++i)
+				cd.color[i]	= 0.1f * static_cast<float>(rng.getInt(1, 10));
+
+			cd.color.w() = 1.0f;
+		}
+
+		if (sample < numDepthStencilSamples)
+		{
+			const deUint32 globalSample = sample + numColorSamples * (x + imageSize.x() * y);
+			cd.depth	= wrapIncFloat(0.05f * static_cast<float>(1 + globalSample), 0.05f, 1.0f);
+			cd.stencil	= 1 + globalSample % numCoverageSamples;
+		}
+
+		allData.push_back(cd);
+	}
+
+	return allData;
+}
+
+//! NDC transformation algorithm for sample locations
+template<typename SampleAccessor>
+std::vector<Vec2> ndcTransformEachSampleInPixel (const UVec2& framebufferSize, const deUint32 numSamplesPerPixel, const SampleAccessor& access)
+{
+	std::vector<Vec2> locations;
+
+	for (deUint32 y			= 0; y			< framebufferSize.y();	++y)
+	for (deUint32 x			= 0; x			< framebufferSize.x();	++x)
+	for (deUint32 sampleNdx	= 0; sampleNdx	< numSamplesPerPixel;	++sampleNdx)
+	{
+		const Vec2& sp = access(x, y, sampleNdx);
+		const float	globalX  = sp.x() + static_cast<float>(x);
+		const float	globalY  = sp.y() + static_cast<float>(y);
+
+		// Transform to [-1, 1] space
+		locations.push_back(Vec2(-1.0f + 2.0f * (globalX / static_cast<float>(framebufferSize.x())),
+								 -1.0f + 2.0f * (globalY / static_cast<float>(framebufferSize.y()))));
+	}
+
+	return locations;
+}
+
+class AccessStandardSampleLocationsArray
+{
+public:
+	AccessStandardSampleLocationsArray (const Vec2* ptr) : m_pData (ptr) {}
+
+	const Vec2& operator ()(const deUint32 x, const deUint32 y, const deUint32 sampleNdx) const
+	{
+		DE_UNREF(x);
+		DE_UNREF(y);
+		return m_pData[sampleNdx];
+	}
+
+private:
+	const Vec2*	m_pData;
+};
+
+class AccessMultisamplePixelGrid
+{
+public:
+	AccessMultisamplePixelGrid (const MultisamplePixelGrid* ptr) : m_pGrid (ptr) {}
+
+	Vec2 operator ()(const deUint32 x, const deUint32 y, const deUint32 sampleNdx) const
+	{
+		const VkSampleLocationEXT& sp = m_pGrid->getSample(x, y, sampleNdx);
+		return Vec2(sp.x, sp.y);
+	}
+
+private:
+	const MultisamplePixelGrid*	m_pGrid;
+};
+
+//! Generate NDC space standard sample locations at each framebuffer pixel
+//! Data is filled starting at pixel (0,0) and for each pixel there are numSamples samples
+std::vector<Vec2> genFramebufferStandardSampleLocations (const VkSampleCountFlagBits numSamples, const UVec2& framebufferSize)
+{
+	static const Vec2 s_location_samples_1[] =
+	{
+		Vec2(0.5f, 0.5f),
+	};
+	static const Vec2 s_location_samples_2[] =
+	{
+		Vec2(0.75f, 0.75f),
+		Vec2(0.25f, 0.25f),
+	};
+	static const Vec2 s_location_samples_4[] =
+	{
+		Vec2(0.375f, 0.125f),
+		Vec2(0.875f, 0.375f),
+		Vec2(0.125f, 0.625f),
+		Vec2(0.625f, 0.875f),
+	};
+	static const Vec2 s_location_samples_8[] =
+	{
+		Vec2(0.5625f, 0.3125f),
+		Vec2(0.4375f, 0.6875f),
+		Vec2(0.8125f, 0.5625f),
+		Vec2(0.3125f, 0.1875f),
+		Vec2(0.1875f, 0.8125f),
+		Vec2(0.0625f, 0.4375f),
+		Vec2(0.6875f, 0.9375f),
+		Vec2(0.9375f, 0.0625f),
+	};
+	static const Vec2 s_location_samples_16[] =
+	{
+		Vec2(0.5625f, 0.5625f),
+		Vec2(0.4375f, 0.3125f),
+		Vec2(0.3125f, 0.6250f),
+		Vec2(0.7500f, 0.4375f),
+		Vec2(0.1875f, 0.3750f),
+		Vec2(0.6250f, 0.8125f),
+		Vec2(0.8125f, 0.6875f),
+		Vec2(0.6875f, 0.1875f),
+		Vec2(0.3750f, 0.8750f),
+		Vec2(0.5000f, 0.0625f),
+		Vec2(0.2500f, 0.1250f),
+		Vec2(0.1250f, 0.7500f),
+		Vec2(0.0000f, 0.5000f),
+		Vec2(0.9375f, 0.2500f),
+		Vec2(0.8750f, 0.9375f),
+		Vec2(0.0625f, 0.0000f),
+	};
+
+	const Vec2*	pSampleLocation = DE_NULL;
+
+	switch (numSamples)
+	{
+		case VK_SAMPLE_COUNT_1_BIT:		pSampleLocation = s_location_samples_1;		break;
+		case VK_SAMPLE_COUNT_2_BIT:		pSampleLocation = s_location_samples_2;		break;
+		case VK_SAMPLE_COUNT_4_BIT:		pSampleLocation = s_location_samples_4;		break;
+		case VK_SAMPLE_COUNT_8_BIT:		pSampleLocation = s_location_samples_8;		break;
+		case VK_SAMPLE_COUNT_16_BIT:	pSampleLocation = s_location_samples_16;	break;
+
+		default:
+			DE_ASSERT(0);
+			return std::vector<Vec2>();
+	}
+
+	return ndcTransformEachSampleInPixel(framebufferSize, static_cast<deUint32>(numSamples), AccessStandardSampleLocationsArray(pSampleLocation));
+}
+
+//! Generate NDC space custom sample locations at each framebuffer pixel, based on the given pixel grid
+std::vector<Vec2> getSampleLocations (const MultisamplePixelGrid& pixelGrid, const UVec2& framebufferSize)
+{
+	return ndcTransformEachSampleInPixel(framebufferSize, pixelGrid.samplesPerPixel(), AccessMultisamplePixelGrid(&pixelGrid));
+}
+
+struct PositionColor
+{
+	tcu::Vec4	position;
+	tcu::Vec4	color;
+
+	PositionColor (const tcu::Vec4& pos, const tcu::Vec4& col) : position(pos), color(col) {}
+};
+
+//! Generate subpixel triangles containing the sample position, based on compare data.
+//! Stencil values are created by overlapping triangles, so the stencil pipeline state must be set up accordingly.
+std::vector<PositionColor> generateSubpixelTriangles (const UVec2&						renderSize,
+													  const std::vector<CompareData>&	compareData,
+													  const std::vector<Vec2>&			sampleLocations)
+{
+	std::vector<PositionColor>	vertices;
+
+	// For each sample location (in the whole framebuffer), create a sub-pixel triangle that contains it.
+	// NDC viewport size is 2.0 in X and Y and NDC pixel width/height depends on the framebuffer resolution.
+	const Vec2			pixelSize	= Vec2(2.0f) / renderSize.cast<float>();
+	const Vec2			offset		= pixelSize / 16.0f;	// 4 bits precision
+
+	// Surround with a roughly centered triangle
+	const float y1 = 0.5f  * offset.y();
+	const float y2 = 0.35f * offset.y();
+	const float x1 = 0.5f  * offset.x();
+
+	DE_ASSERT(compareData.size() == sampleLocations.size());
+
+	for (std::size_t globalSampleNdx = 0; globalSampleNdx < sampleLocations.size(); ++globalSampleNdx)
+	{
+		const Vec2&			loc	= sampleLocations[globalSampleNdx];
+		const CompareData&	cd	= compareData	 [globalSampleNdx];
+
+		// Overdraw at the same position to get the desired stencil
+		// Draw at least once, if stencil is 0
+		for (deUint32 i = 0; i < deMaxu32(1u, cd.stencil); ++i)
+		{
+			vertices.push_back(PositionColor(Vec4(loc.x(),      loc.y() - y1, cd.depth, 1.0f), cd.color));
+			vertices.push_back(PositionColor(Vec4(loc.x() - x1, loc.y() + y2, cd.depth, 1.0f), cd.color));
+			vertices.push_back(PositionColor(Vec4(loc.x() + x1, loc.y() + y2, cd.depth, 1.0f), cd.color));
+		}
+	}
+
+	return vertices;
+}
+
+void reportSampleError (tcu::TestLog& log, const std::string& sampleDesc, UVec2& renderSize, const deUint32 numCoverageSamples, const deUint32 globalSampleNdx)
+{
+	const deUint32 pixelNdx	= globalSampleNdx / numCoverageSamples;
+	const deUint32 x		= pixelNdx % renderSize.x();
+	const deUint32 y		= pixelNdx / renderSize.x();
+	const deUint32 sample	= globalSampleNdx % numCoverageSamples;
+
+	log << tcu::TestLog::Message << "Incorrect " << sampleDesc << " sample (" << sample << ") at pixel (" << x << ", " << y << ")" << tcu::TestLog::EndMessage;
+}
+
+void checkSampleRequirements (Context&						context,
+							  const VkSampleCountFlagBits	numColorSamples,
+							  const VkSampleCountFlagBits	numDepthStencilSamples,
+							  const bool					requireStandardSampleLocations)
+{
+	const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
+
+	if ((limits.framebufferColorSampleCounts & numColorSamples) == 0u)
+		TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
+
+	if ((limits.framebufferDepthSampleCounts & numDepthStencilSamples) == 0u)
+		TCU_THROW(NotSupportedError, "framebufferDepthSampleCounts: sample count not supported");
+
+	if ((limits.framebufferStencilSampleCounts & numDepthStencilSamples) == 0u)
+		TCU_THROW(NotSupportedError, "framebufferStencilSampleCounts: sample count not supported");
+
+	if ((limits.sampledImageColorSampleCounts & numColorSamples) == 0u)
+		TCU_THROW(NotSupportedError, "sampledImageColorSampleCounts: sample count not supported");
+
+	if ((limits.sampledImageDepthSampleCounts & numDepthStencilSamples) == 0u)
+		TCU_THROW(NotSupportedError, "sampledImageDepthSampleCounts: sample count not supported");
+
+	if ((limits.sampledImageStencilSampleCounts & numDepthStencilSamples) == 0u)
+		TCU_THROW(NotSupportedError, "sampledImageStencilSampleCounts: sample count not supported");
+
+	// This is required to output geometry that is covering a specific sample
+	if (requireStandardSampleLocations && !limits.standardSampleLocations)
+		TCU_THROW(NotSupportedError, "standardSampleLocations: not supported");
+}
+
+void checkImageRequirements (Context&						context,
+							 const VkFormat					format,
+							 const VkFormatFeatureFlags		requiredFeatureFlags,
+							 const VkImageUsageFlags		requiredUsageFlags,
+							 const VkSampleCountFlagBits	requiredSampleCount = VK_SAMPLE_COUNT_1_BIT)
+{
+	const InstanceInterface&	vki				= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
+	VkImageFormatProperties		imageProperties;
+
+	const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
+
+	if ((formatProperties.optimalTilingFeatures & requiredFeatureFlags) != requiredFeatureFlags)
+		TCU_THROW(NotSupportedError, (de::toString(format) + ": format features not supported").c_str());
+
+	const VkResult result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, requiredUsageFlags, (VkImageCreateFlags)0, &imageProperties);
+
+	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
+		TCU_THROW(NotSupportedError, (de::toString(format) + ": format not supported").c_str());
+
+	if ((imageProperties.sampleCounts & requiredSampleCount) != requiredSampleCount)
+		TCU_THROW(NotSupportedError, (de::toString(format) + ": sample count not supported").c_str());
+}
+
+//! Used after a render pass color output (draw or resolve)
+void recordCopyOutputImageToBuffer (const DeviceInterface&	vk,
+									const VkCommandBuffer	cmdBuffer,
+									const UVec2&			imageSize,
+									const VkImage			srcImage,
+									const VkBuffer			dstBuffer)
+{
+	// Image read barrier after color output
+	{
+		const VkImageMemoryBarrier barrier =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
+			DE_NULL,																// const void*                pNext;
+			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              srcAccessMask;
+			VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags              dstAccessMask;
+			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,									// VkImageLayout              oldLayout;
+			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,									// VkImageLayout              newLayout;
+			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
+			srcImage,																// VkImage                    image;
+			makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u),	// VkImageSubresourceRange    subresourceRange;
+		};
+
+		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+	}
+	// Resolve image -> host buffer
+	{
+		const VkBufferImageCopy region =
+		{
+			0ull,																// VkDeviceSize                bufferOffset;
+			0u,																	// uint32_t                    bufferRowLength;
+			0u,																	// uint32_t                    bufferImageHeight;
+			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	// VkImageSubresourceLayers    imageSubresource;
+			makeOffset3D(0, 0, 0),												// VkOffset3D                  imageOffset;
+			makeExtent3D(imageSize.x(), imageSize.y(), 1u),						// VkExtent3D                  imageExtent;
+		};
+
+		vk.cmdCopyImageToBuffer(cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuffer, 1u, &region);
+	}
+	// Buffer write barrier
+	{
+		const VkBufferMemoryBarrier barrier =
+		{
+			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
+			DE_NULL,										// const void*        pNext;
+			VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags      srcAccessMask;
+			VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
+			dstBuffer,										// VkBuffer           buffer;
+			0ull,											// VkDeviceSize       offset;
+			VK_WHOLE_SIZE,									// VkDeviceSize       size;
+		};
+
+		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+							  0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
+	}
+}
+
+namespace VerifySamples
+{
+
+//! The parameters that define a test case
+struct TestParams
+{
+	struct SampleCount
+	{
+		VkSampleCountFlagBits	numCoverageSamples;				//!< VkPipelineMultisampleStateCreateInfo::rasterizationSamples
+		VkSampleCountFlagBits	numColorSamples;				//!< VkAttachmentDescription::samples and VkImageCreateInfo::samples
+		VkSampleCountFlagBits	numDepthStencilSamples;			//!< VkAttachmentDescription::samples and VkImageCreateInfo::samples
+	};
+
+	VkFormat					colorFormat;					//!< Color attachment format
+	VkFormat					depthStencilFormat;				//!< D/S attachment format. Will test both aspects if it's a mixed format
+	bool						useProgrammableSampleLocations;	//!< Try to use VK_EXT_sample_locations if available
+	std::vector<SampleCount>	perSubpassSamples;				//!< Will use multiple subpasses if more than one element
+
+	TestParams (void)
+		: colorFormat						()
+		, depthStencilFormat				()
+		, useProgrammableSampleLocations	()
+	{
+	}
+};
+
+//! Common data used by the test
+struct WorkingData
+{
+	struct PerSubpass
+	{
+		deUint32						numVertices;				//!< Number of vertices defined in the vertex buffer
+		Move<VkBuffer>					vertexBuffer;
+		MovePtr<Allocation>				vertexBufferAlloc;
+		Move<VkImage>					colorImage;					//!< Color image
+		Move<VkImageView>				colorImageView;				//!< Color attachment
+		MovePtr<Allocation>				colorImageAlloc;
+		Move<VkImage>					depthStencilImage;			//!< Depth stencil image
+		Move<VkImageView>				depthStencilImageView;		//!< Depth stencil attachment
+		Move<VkImageView>				depthOnlyImageView;			//!< Depth aspect for shader read
+		Move<VkImageView>				stencilOnlyImageView;		//!< Stencil aspect for shader read
+		MovePtr<Allocation>				depthStencilImageAlloc;
+		Move<VkBuffer>					compareBuffer;				//!< Buffer used to verify the images - comparison data
+		MovePtr<Allocation>				compareBufferAlloc;
+		VkDeviceSize					compareBufferSize;
+		Move<VkBuffer>					resultBuffer;				//!< Buffer used to verify the images - results
+		MovePtr<Allocation>				resultBufferAlloc;
+		VkDeviceSize					resultBufferSize;
+		deUint32						numResultElements;			//!< Number of checksums in the result buffer
+		MovePtr<MultisamplePixelGrid>	pixelGrid;					//!< Programmable locations
+
+		PerSubpass (void)
+			: numVertices		()
+			, compareBufferSize	()
+			, resultBufferSize	()
+			, numResultElements	()
+		{
+		}
+	};
+
+	UVec2											renderSize;					//!< Size of the framebuffer
+	VkPhysicalDeviceSampleLocationsPropertiesEXT	sampleLocationsProperties;	//!< Used with VK_EXT_sample_locations
+
+	std::vector<de::SharedPtr<PerSubpass> >			perSubpass;					//!< Test may use more than one set of data
+
+	WorkingData (void)
+		: sampleLocationsProperties ()
+	{
+	}
+};
+
+void addVerificationComputeShader (SourceCollections&			programCollection,
+								   const VkSampleCountFlagBits	numCoverageSamples,
+								   const VkSampleCountFlagBits	numColorSamples,
+								   const VkSampleCountFlagBits	numDepthStencilSamples,
+								   const VkFormat				depthStencilFormat,
+								   const std::string&			nameSuffix)
+{
+		const bool			isColorMS			= (numColorSamples		  != VK_SAMPLE_COUNT_1_BIT);
+		const bool			isDepthStencilMS	= (numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT);
+		const std::string	colorBit			= de::toString(static_cast<deUint32>(VK_IMAGE_ASPECT_COLOR_BIT)) + "u";
+		const std::string	depthBit			= de::toString(static_cast<deUint32>(VK_IMAGE_ASPECT_DEPTH_BIT)) + "u";
+		const std::string	stencilBit			= de::toString(static_cast<deUint32>(VK_IMAGE_ASPECT_STENCIL_BIT)) + "u";
+
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "struct CompareData {\n"
+			<< "    vec4  color;\n"
+			<< "    float depth;\n"
+			<< "    uint  stencil;\n"
+			<< "};\n"
+			<< "\n"
+			<< "layout(local_size_x = " << static_cast<deUint32>(numCoverageSamples) << ") in;\n"
+			// Always use this descriptor layout and ignore unused bindings
+			<< "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n"
+			<< "    uint values[];\n"
+			<< "} sb_out;\n"
+			<< "layout(set = 0, binding = 1, std430) readonly buffer InputCompare {\n"
+			<< "    CompareData	data[];\n"
+			<< "} sb_cmp;\n"
+			<< "layout(set = 0, binding = 2) uniform sampler2D" << (isColorMS ? "MS" : "") << "  colorImage;\n"
+			<< "layout(set = 0, binding = 3) uniform sampler2D" << (isDepthStencilMS ? "MS" : "") <<"  depthImage;\n"
+			<< "layout(set = 0, binding = 4) uniform usampler2D" << (isDepthStencilMS ? "MS" : "") <<" stencilImage;\n"
+			<< "\n"
+			<< "void main (void)\n"
+			<< "{\n"
+
+		// Data for each sample in each pixel is laid out linearly (e.g 2 samples):
+		// [pixel(0, 0) sample(0)][pixel(0, 0) sample(1)][pixel(1, 0) sample(0)][pixel(1, 0) sample(1)]...
+
+			<< "    uint  globalIndex = gl_LocalInvocationID.x + gl_WorkGroupSize.x * (gl_WorkGroupID.x + gl_WorkGroupID.y * gl_NumWorkGroups.x);\n"
+			<< "    ivec2 position    = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
+			<< "    int   sampleNdx   = int(gl_LocalInvocationID.x);\n"
+			<< "    uint  result      = 0u;\n"
+			<< "\n"
+			<< "    // Verify color samples\n"
+			<< "    if (sampleNdx < " << static_cast<deUint32>(numColorSamples) << ")\n"
+			<< "    {\n"
+			<< "        vec4 color     = texelFetch(colorImage, position, sampleNdx);\n"	// for non-MS (1 sample) case, sampleNdx = 0 and will instead be LOD = 0
+			<< "        vec4 diff      = abs(color - sb_cmp.data[globalIndex].color);\n"
+			<< "        vec4 threshold = vec4(0.02);\n"
+			<< "\n"
+			<< "        if (all(lessThan(diff, threshold)))\n"
+			<< "            result |= " << colorBit << ";\n"
+			<< "    }\n"
+			<< "    else\n"
+			<< "        result |= " << colorBit << ";\n"	// Pass, if sample doesn't exist
+			<< "\n";
+
+		if (isDepthFormat(depthStencilFormat))
+		{
+			src << "    // Verify depth samples\n"
+				<< "    if (sampleNdx < " << static_cast<deUint32>(numDepthStencilSamples) << ")\n"
+				<< "    {\n"
+				<< "        float depth     = texelFetch(depthImage, position, sampleNdx).r;\n"
+				<< "        float diff      = abs(depth - sb_cmp.data[globalIndex].depth);\n"
+				<< "        float threshold = 0.002;\n"
+				<< "\n"
+				<< "        if (diff < threshold)\n"
+				<< "            result |= " << depthBit << ";\n"
+				<< "    }\n"
+				<< "    else\n"
+				<< "        result |= " << depthBit << ";\n"
+				<< "\n";
+		}
+
+		if (isStencilFormat(depthStencilFormat))
+		{
+			src << "    // Verify stencil samples\n"
+				<< "    if (sampleNdx < " << static_cast<deUint32>(numDepthStencilSamples) << ")\n"
+				<< "    {\n"
+				<< "        uint stencil   = texelFetch(stencilImage, position, sampleNdx).r;\n"
+				<< "        uint diff      = stencil - sb_cmp.data[globalIndex].stencil;\n"
+				<< "\n"
+				<< "        if (diff == 0u)\n"
+				<< "            result |= " << stencilBit << ";\n"
+				<< "    }\n"
+				<< "    else\n"
+				<< "        result |= " << stencilBit << ";\n"
+				<< "\n";
+		}
+
+		src << "    sb_out.values[globalIndex] = result;\n"
+			<< "}\n";
+		programCollection.glslSources.add("comp" + nameSuffix) << glu::ComputeSource(src.str());
+}
+
+//! Get a compact sample count string in format X_Y_Z
+std::string getSampleCountString (const TestParams::SampleCount& samples)
+{
+	std::ostringstream str;
+
+	str << static_cast<deUint32>(samples.numCoverageSamples) << "_"
+		<< static_cast<deUint32>(samples.numColorSamples)	 << "_"
+		<< static_cast<deUint32>(samples.numDepthStencilSamples);
+
+	return str.str();
+}
+
+void initPrograms (SourceCollections& programCollection, const TestParams params)
+{
+	// Vertex shader - position and color
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "layout(location = 0) in  vec4 in_position;\n"
+			<< "layout(location = 1) in  vec4 in_color;\n"
+			<< "layout(location = 0) out vec4 o_color;\n"
+			<< "\n"
+			<< "out gl_PerVertex {\n"
+			<< "    vec4 gl_Position;\n"
+			<< "};\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    gl_Position = in_position;\n"
+			<< "    o_color     = in_color;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+	}
+
+	// Fragment shader - output color from VS
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "layout(location = 0) in  vec4 in_color;\n"
+			<< "layout(location = 0) out vec4 o_color;\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    o_color = in_color;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+	}
+
+	// Compute shader - image verification
+	for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+	{
+		const TestParams::SampleCount&	samples	= params.perSubpassSamples[subpassNdx];
+		addVerificationComputeShader(programCollection,
+									 samples.numCoverageSamples,
+									 samples.numColorSamples,
+									 samples.numDepthStencilSamples,
+									 params.depthStencilFormat,
+									 "_" + getSampleCountString(samples));
+	}
+}
+
+//! A simple color, depth/stencil draw. Subpasses (if more than one) are independent
+void draw (Context& context, const TestParams& params, WorkingData& wd)
+{
+	const DeviceInterface&	vk				= context.getDeviceInterface();
+	const VkDevice			device			= context.getDevice();
+	const deUint32			numSubpasses	= static_cast<deUint32>(wd.perSubpass.size());
+
+	Move<VkRenderPass>							renderPass;
+	Move<VkFramebuffer>							framebuffer;
+	std::vector<VkSampleLocationsInfoEXT>		perSubpassSampleLocationsInfo;
+	std::vector<VkAttachmentSampleLocationsEXT>	attachmentSampleLocations;
+	std::vector<VkSubpassSampleLocationsEXT>	subpassSampleLocations;
+
+	if (params.useProgrammableSampleLocations)
+	for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
+	{
+		perSubpassSampleLocationsInfo.push_back(makeSampleLocationsInfo(*wd.perSubpass[subpassNdx]->pixelGrid));
+	}
+
+	// Create a render pass and a framebuffer
+	{
+		std::vector<VkSubpassDescription>		subpasses;
+		std::vector<VkImageView>				attachments;
+		std::vector<VkAttachmentDescription>	attachmentDescriptions;
+		std::vector<VkAttachmentReference>		attachmentReferences;
+
+		// Reserve capacity to avoid invalidating pointers to elements
+		attachmentReferences.reserve(numSubpasses * 2);
+
+		for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
+		{
+			attachments.push_back(wd.perSubpass[subpassNdx]->colorImageView.get());
+			attachments.push_back(wd.perSubpass[subpassNdx]->depthStencilImageView.get());
+
+			attachmentDescriptions.push_back(makeAttachmentDescription(
+				(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags		flags;
+				params.colorFormat,												// VkFormat							format;
+				params.perSubpassSamples[subpassNdx].numColorSamples,			// VkSampleCountFlagBits			samples;
+				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp				loadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp				storeOp;
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,								// VkAttachmentLoadOp				stencilLoadOp;
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,								// VkAttachmentStoreOp				stencilStoreOp;
+				VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout					initialLayout;
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL						// VkImageLayout					finalLayout;
+			));
+
+			attachmentDescriptions.push_back(makeAttachmentDescription(
+				(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags		flags;
+				params.depthStencilFormat,										// VkFormat							format;
+				params.perSubpassSamples[subpassNdx].numDepthStencilSamples,	// VkSampleCountFlagBits			samples;
+				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp				loadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp				storeOp;
+				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp				stencilLoadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp				stencilStoreOp;
+				VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout					initialLayout;
+				VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL					// VkImageLayout					finalLayout;
+			));
+
+			attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()),	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
+			const VkAttachmentReference* colorRef = &attachmentReferences.back();
+
+			attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()),	VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
+			const VkAttachmentReference* depthStencilRef = &attachmentReferences.back();
+
+			if (params.useProgrammableSampleLocations)
+			{
+				const VkAttachmentSampleLocationsEXT newAttachmentSampleLocations =
+				{
+					attachmentReferences.back().attachment,			// uint32_t                    attachmentIndex;
+					perSubpassSampleLocationsInfo[subpassNdx],		// VkSampleLocationsInfoEXT    sampleLocationsInfo;
+				};
+				attachmentSampleLocations.push_back(newAttachmentSampleLocations);
+
+				const VkSubpassSampleLocationsEXT newSubpassSampleLocations =
+				{
+					subpassNdx,										// uint32_t                    subpassIndex;
+					perSubpassSampleLocationsInfo[subpassNdx],		// VkSampleLocationsInfoEXT    sampleLocationsInfo;
+				};
+				subpassSampleLocations.push_back(newSubpassSampleLocations);
+			}
+
+			const VkSubpassDescription subpassDescription =
+			{
+				(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags       flags;
+				VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint             pipelineBindPoint;
+				0u,													// uint32_t                        inputAttachmentCount;
+				DE_NULL,											// const VkAttachmentReference*    pInputAttachments;
+				1u,													// uint32_t                        colorAttachmentCount;
+				colorRef,											// const VkAttachmentReference*    pColorAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pResolveAttachments;
+				depthStencilRef,									// const VkAttachmentReference*    pDepthStencilAttachment;
+				0u,													// uint32_t                        preserveAttachmentCount;
+				DE_NULL,											// const uint32_t*                 pPreserveAttachments;
+			};
+
+			subpasses.push_back(subpassDescription);
+		}
+
+		// Assume there are no dependencies between subpasses
+		const VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
+			DE_NULL,												// const void*						pNext;
+			(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
+			static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
+			dataOrNullPtr(attachmentDescriptions),					// const VkAttachmentDescription*	pAttachments;
+			static_cast<deUint32>(subpasses.size()),				// deUint32							subpassCount;
+			dataOrNullPtr(subpasses),								// const VkSubpassDescription*		pSubpasses;
+			0u,														// deUint32							dependencyCount;
+			DE_NULL,												// const VkSubpassDependency*		pDependencies;
+		};
+
+		renderPass  = createRenderPass(vk, device, &renderPassInfo);
+		framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), wd.renderSize.x(), wd.renderSize.y());
+	}
+
+	const Unique<VkShaderModule>	vertexModule	(createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
+	const Unique<VkShaderModule>	fragmentModule	(createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
+	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device));
+
+	typedef SharedPtr<Unique<VkPipeline> > PipelineSp;
+	std::vector<PipelineSp> pipelines;
+
+	for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
+	{
+		const VkSampleLocationsInfoEXT* pSampleLocationsInfo = (params.useProgrammableSampleLocations ? &perSubpassSampleLocationsInfo[subpassNdx] : DE_NULL);
+
+		pipelines.push_back(PipelineSp(new Unique<VkPipeline>(
+			makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, /*use vertex input*/ true, subpassNdx,
+								 wd.renderSize, getImageAspectFlags(params.depthStencilFormat), params.perSubpassSamples[subpassNdx].numCoverageSamples,
+								 /*use sample shading*/ true, pSampleLocationsInfo))));
+	}
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	{
+		std::vector<VkClearValue> clearValues;
+
+		for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
+		{
+			clearValues.push_back(makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f));
+			clearValues.push_back(makeClearValueDepthStencil(1.0f, 0u));
+		}
+
+		const VkRect2D renderArea =
+		{
+			{ 0u, 0u },
+			{ wd.renderSize.x(), wd.renderSize.y() }
+		};
+
+		VkRenderPassBeginInfo renderPassBeginInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			// VkStructureType         sType;
+			DE_NULL,											// const void*             pNext;
+			*renderPass,										// VkRenderPass            renderPass;
+			*framebuffer,										// VkFramebuffer           framebuffer;
+			renderArea,											// VkRect2D                renderArea;
+			static_cast<deUint32>(clearValues.size()),			// uint32_t                clearValueCount;
+			dataOrNullPtr(clearValues),							// const VkClearValue*     pClearValues;
+		};
+
+		if (params.useProgrammableSampleLocations)
+		{
+			const VkRenderPassSampleLocationsBeginInfoEXT renderPassSampleLocationsBeginInfo =
+			{
+				VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT,	// VkStructureType                          sType;
+				DE_NULL,														// const void*                              pNext;
+				static_cast<deUint32>(attachmentSampleLocations.size()),		// uint32_t                                 attachmentInitialSampleLocationsCount;
+				dataOrNullPtr(attachmentSampleLocations),						// const VkAttachmentSampleLocationsEXT*    pAttachmentInitialSampleLocations;
+				static_cast<deUint32>(subpassSampleLocations.size()),			// uint32_t                                 postSubpassSampleLocationsCount;
+				dataOrNullPtr(subpassSampleLocations),							// const VkSubpassSampleLocationsEXT*       pPostSubpassSampleLocations;
+			};
+
+			renderPassBeginInfo.pNext = &renderPassSampleLocationsBeginInfo;
+
+			vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+		}
+		else
+			vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+	}
+
+	for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
+	{
+		if (subpassNdx != 0)
+			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
+
+		const VkDeviceSize vertexBufferOffset = 0ull;
+		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.perSubpass[subpassNdx]->vertexBuffer.get(), &vertexBufferOffset);
+
+		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
+
+		vk.cmdDraw(*cmdBuffer, wd.perSubpass[subpassNdx]->numVertices, 1u, 0u, 0u);
+	}
+
+	vk.cmdEndRenderPass(*cmdBuffer);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+}
+
+void dispatchImageCheck (Context& context, const TestParams& params, WorkingData& wd, const deUint32 subpassNdx)
+{
+	const DeviceInterface&		vk			= context.getDeviceInterface();
+	const VkDevice				device		= context.getDevice();
+	WorkingData::PerSubpass&	subpassData	= *wd.perSubpass[subpassNdx];
+
+	const Unique<VkSampler>	defaultSampler	(makeSampler(vk, device));
+
+	// Create descriptor set
+
+	const Unique<VkDescriptorSetLayout> descriptorSetLayout(
+		DescriptorSetLayoutBuilder()
+		.addSingleBinding		(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			VK_SHADER_STAGE_COMPUTE_BIT)
+		.addSingleBinding		(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			VK_SHADER_STAGE_COMPUTE_BIT)
+		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	VK_SHADER_STAGE_COMPUTE_BIT, &defaultSampler.get())
+		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	VK_SHADER_STAGE_COMPUTE_BIT, &defaultSampler.get())
+		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	VK_SHADER_STAGE_COMPUTE_BIT, &defaultSampler.get())
+		.build(vk, device));
+
+	const Unique<VkDescriptorPool> descriptorPool(
+		DescriptorPoolBuilder()
+		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
+		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3u)
+		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
+
+	const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
+
+	{
+		const VkDescriptorBufferInfo	compareBufferInfo	= makeDescriptorBufferInfo(*subpassData.compareBuffer, 0ull, subpassData.compareBufferSize);
+		const VkDescriptorBufferInfo	resultBufferInfo	= makeDescriptorBufferInfo(*subpassData.resultBuffer, 0ull, subpassData.resultBufferSize);
+		const VkDescriptorImageInfo		colorImageInfo		= makeDescriptorImageInfo(DE_NULL, *subpassData.colorImageView,			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+		const VkDescriptorImageInfo		depthImageInfo		= makeDescriptorImageInfo(DE_NULL, *subpassData.depthOnlyImageView,		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+		const VkDescriptorImageInfo		stencilImageInfo	= makeDescriptorImageInfo(DE_NULL, *subpassData.stencilOnlyImageView,	VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+
+		DescriptorSetUpdateBuilder	builder;
+
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo);
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &compareBufferInfo);
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo);
+
+		if (subpassData.depthOnlyImageView)
+			builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo);
+
+		if (subpassData.stencilOnlyImageView)
+			builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &stencilImageInfo);
+
+		builder.update(vk, device);
+	}
+
+	// Pipeline
+
+	const std::string				shaderName		("comp_" + getSampleCountString(params.perSubpassSamples[subpassNdx]));
+	const Unique<VkShaderModule>	shaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get(shaderName), 0u));
+	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device, *descriptorSetLayout));
+	const Unique<VkPipeline>		pipeline		(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule, DE_NULL));
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
+
+	vk.cmdDispatch(*cmdBuffer, wd.renderSize.x(), wd.renderSize.y(), 1u);
+
+	{
+		const VkBufferMemoryBarrier barrier =
+		{
+			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
+			DE_NULL,										// const void*        pNext;
+			VK_ACCESS_SHADER_WRITE_BIT,						// VkAccessFlags      srcAccessMask;
+			VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
+			*subpassData.resultBuffer,						// VkBuffer           buffer;
+			0ull,											// VkDeviceSize       offset;
+			VK_WHOLE_SIZE,									// VkDeviceSize       size;
+		};
+
+		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0,
+			(const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
+	}
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+
+	invalidateMappedMemoryRange(vk, device, subpassData.resultBufferAlloc->getMemory(), subpassData.resultBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+}
+
+void createPerSubpassData (Context& context, const TestParams& params, WorkingData& wd, const deUint32 subpassNdx)
+{
+	const DeviceInterface&			vk			= context.getDeviceInterface();
+	const VkDevice					device		= context.getDevice();
+	MovePtr<Allocator>				allocator   = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())));
+	const TestParams::SampleCount&	samples		= params.perSubpassSamples[subpassNdx];
+	WorkingData::PerSubpass&		subpassData	= *wd.perSubpass[subpassNdx];
+
+	// Create images
+	{
+
+		const VkImageUsageFlags	colorImageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT		  | VK_IMAGE_USAGE_SAMPLED_BIT;
+		const VkImageUsageFlags depthStencilImageUsageFlags	= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+
+		checkImageRequirements (context,
+								params.colorFormat,
+								VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,
+								colorImageUsageFlags,
+								samples.numColorSamples);
+
+		subpassData.colorImage		= makeImage(vk, device, params.colorFormat, wd.renderSize, samples.numColorSamples, colorImageUsageFlags);
+		subpassData.colorImageAlloc	= bindImage(vk, device, *allocator, *subpassData.colorImage, MemoryRequirement::Any);
+		subpassData.colorImageView	= makeImageView(vk, device, *subpassData.colorImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
+
+		checkImageRequirements (context,
+								params.depthStencilFormat,
+								VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,
+								depthStencilImageUsageFlags,
+								samples.numDepthStencilSamples);
+
+		subpassData.depthStencilImage		= makeImage(vk, device, params.depthStencilFormat, wd.renderSize, samples.numDepthStencilSamples, depthStencilImageUsageFlags);
+		subpassData.depthStencilImageAlloc	= bindImage(vk, device, *allocator, *subpassData.depthStencilImage, MemoryRequirement::Any);
+		subpassData.depthStencilImageView	= makeImageView(vk, device, *subpassData.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(getImageAspectFlags(params.depthStencilFormat), 0u, 1u, 0u, 1u));
+
+		if (isDepthFormat(params.depthStencilFormat))
+			subpassData.depthOnlyImageView	= makeImageView(vk, device, *subpassData.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u));
+
+		if (isStencilFormat(params.depthStencilFormat))
+			subpassData.stencilOnlyImageView	= makeImageView(vk, device, *subpassData.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u));
+	}
+
+	// Create vertex and comparison buffers
+	{
+		const deUint32					seed		= 123 + 19 * subpassNdx;
+		const std::vector<CompareData>	compareData	= generateCompareData(seed, wd.renderSize, samples.numCoverageSamples, samples.numColorSamples, samples.numDepthStencilSamples);
+
+		subpassData.compareBufferSize	= static_cast<VkDeviceSize>(sizeof(CompareData) * compareData.size());
+		subpassData.compareBuffer		= makeBuffer(vk, device, subpassData.compareBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+		subpassData.compareBufferAlloc	= bindBuffer(vk, device, *allocator, *subpassData.compareBuffer, MemoryRequirement::HostVisible);
+
+		deMemcpy(subpassData.compareBufferAlloc->getHostPtr(), dataOrNullPtr(compareData), static_cast<std::size_t>(subpassData.compareBufferSize));
+		flushMappedMemoryRange(vk, device, subpassData.compareBufferAlloc->getMemory(), subpassData.compareBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+
+		subpassData.numResultElements	= static_cast<deUint32>(compareData.size());
+		subpassData.resultBufferSize	= static_cast<VkDeviceSize>(sizeof(deUint32) * compareData.size());
+		subpassData.resultBuffer		= makeBuffer(vk, device, subpassData.resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+		subpassData.resultBufferAlloc	= bindBuffer(vk, device, *allocator, *subpassData.resultBuffer, MemoryRequirement::HostVisible);
+
+		deMemset(subpassData.resultBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(subpassData.resultBufferSize));
+		flushMappedMemoryRange(vk, device, subpassData.resultBufferAlloc->getMemory(), subpassData.resultBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+
+		std::vector<PositionColor> vertices;
+
+		if (params.useProgrammableSampleLocations)
+		{
+			subpassData.pixelGrid = MovePtr<MultisamplePixelGrid>(new MultisamplePixelGrid(UVec2(wd.sampleLocationsProperties.maxSampleLocationGridSize.width,
+																								 wd.sampleLocationsProperties.maxSampleLocationGridSize.height),
+																						   samples.numCoverageSamples));
+
+			const deUint32 locationsSeed = 211 + 4 * subpassNdx;
+			fillSampleLocationsRandom(*subpassData.pixelGrid, wd.sampleLocationsProperties.sampleLocationSubPixelBits, locationsSeed);
+			vertices = generateSubpixelTriangles(wd.renderSize, compareData, getSampleLocations(*subpassData.pixelGrid, wd.renderSize));
+		}
+		else
+		{
+			const std::vector<Vec2>	locations = genFramebufferStandardSampleLocations(samples.numCoverageSamples, wd.renderSize);
+			vertices = generateSubpixelTriangles(wd.renderSize, compareData, locations);
+		}
+
+		const VkDeviceSize	vertexBufferSize = static_cast<VkDeviceSize>(sizeof(vertices[0]) * vertices.size());
+		subpassData.numVertices			= static_cast<deUint32>(vertices.size());
+		subpassData.vertexBuffer			= makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
+		subpassData.vertexBufferAlloc	= bindBuffer(vk, device, *allocator, *subpassData.vertexBuffer, MemoryRequirement::HostVisible);
+
+		deMemcpy(subpassData.vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize));
+		flushMappedMemoryRange(vk, device, subpassData.vertexBufferAlloc->getMemory(), subpassData.vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+	}
+}
+
+void checkRequirements (Context& context, TestParams params)
+{
+	context.requireDeviceFunctionality("VK_AMD_mixed_attachment_samples");
+
+	if (params.useProgrammableSampleLocations)
+		context.requireDeviceFunctionality("VK_EXT_sample_locations");
+
+	for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+	{
+		const TestParams::SampleCount& samples = params.perSubpassSamples[subpassNdx];
+		checkSampleRequirements(context, samples.numColorSamples, samples.numDepthStencilSamples, !params.useProgrammableSampleLocations);
+	}
+}
+
+//! Verify the values of all samples in all attachments.
+tcu::TestStatus test (Context& context, const TestParams params)
+{
+	WorkingData wd;
+	wd.renderSize	= UVec2(2, 2);	// Use a very small image, as we will verify all samples for all pixels
+
+	// Query state related to programmable sample locations
+	if (params.useProgrammableSampleLocations)
+	{
+		const InstanceInterface&	vki				= context.getInstanceInterface();
+		const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
+
+		wd.sampleLocationsProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT;
+		wd.sampleLocationsProperties.pNext = DE_NULL;
+
+		VkPhysicalDeviceProperties2 properties =
+		{
+			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,	    // VkStructureType               sType;
+			&wd.sampleLocationsProperties,							// void*                         pNext;
+			VkPhysicalDeviceProperties(),							// VkPhysicalDeviceProperties    properties;
+		};
+
+		vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
+
+		for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+		{
+			if ((wd.sampleLocationsProperties.sampleLocationSampleCounts & params.perSubpassSamples[subpassNdx].numCoverageSamples) == 0u)
+				TCU_THROW(NotSupportedError, "VkSampleLocationsPropertiesAMD: sample count not supported");
+		}
+	}
+
+	// Create subpass data
+	for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+	{
+		wd.perSubpass.push_back(SharedPtr<WorkingData::PerSubpass>(new WorkingData::PerSubpass()));
+		createPerSubpassData(context, params, wd, subpassNdx);
+	}
+
+	// Draw test geometry
+	draw (context, params, wd);
+
+	// Verify images with a compute shader
+	for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+		dispatchImageCheck (context, params, wd, subpassNdx);
+
+	// Test checksums
+	for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(params.perSubpassSamples.size()); ++subpassNdx)
+	{
+		const deUint32*	const	pSampleChecksumBase	= static_cast<deUint32*>(wd.perSubpass[subpassNdx]->resultBufferAlloc->getHostPtr());
+		const bool				hasDepth			= isDepthFormat(params.depthStencilFormat);
+		const bool				hasStencil			= isStencilFormat(params.depthStencilFormat);
+		bool					allOk				= true;
+
+		context.getTestContext().getLog() << tcu::TestLog::Message << "Verify images in subpass " << subpassNdx << tcu::TestLog::EndMessage;
+
+		for (deUint32 globalSampleNdx = 0; globalSampleNdx < wd.perSubpass[subpassNdx]->numResultElements; ++globalSampleNdx)
+		{
+			const TestParams::SampleCount&	samples	 = params.perSubpassSamples[subpassNdx];
+			const deUint32					checksum = pSampleChecksumBase[globalSampleNdx];
+
+			if ((checksum & VK_IMAGE_ASPECT_COLOR_BIT) == 0u)
+			{
+				reportSampleError(context.getTestContext().getLog(), "color", wd.renderSize, samples.numCoverageSamples, globalSampleNdx);
+				allOk = false;
+			}
+
+			if (hasDepth && ((checksum & VK_IMAGE_ASPECT_DEPTH_BIT) == 0u))
+			{
+				reportSampleError(context.getTestContext().getLog(), "depth", wd.renderSize, samples.numCoverageSamples, globalSampleNdx);
+				allOk = false;
+			}
+
+			if (hasStencil && ((checksum & VK_IMAGE_ASPECT_STENCIL_BIT) == 0u))
+			{
+				reportSampleError(context.getTestContext().getLog(), "stencil", wd.renderSize, samples.numCoverageSamples, globalSampleNdx);
+				allOk = false;
+			}
+		}
+
+		if (!allOk)
+			return tcu::TestStatus::fail("Multisampled image has incorrect samples");
+	}
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+} // VerifySamples
+
+namespace ShaderBuiltins
+{
+
+struct TestParams
+{
+	VkSampleCountFlagBits		numCoverageSamples;			//!< VkPipelineMultisampleStateCreateInfo::rasterizationSamples
+	VkSampleCountFlagBits		numColorSamples;			//!< VkAttachmentDescription::samples and VkImageCreateInfo::samples
+	VkSampleCountFlagBits		numDepthStencilSamples;		//!< VkAttachmentDescription::samples and VkImageCreateInfo::samples
+	VkFormat					colorFormat;				//!< Color attachment format
+	VkFormat					depthStencilFormat;			//!< D/S attachment format. Will test both aspects if it's a mixed format
+};
+
+struct WorkingData
+{
+	UVec2						renderSize;					//!< Size of the framebuffer
+	deUint32					numVertices;				//!< Number of vertices defined in the vertex buffer
+	Move<VkBuffer>				vertexBuffer;
+	MovePtr<Allocation>			vertexBufferAlloc;
+	Move<VkImage>				colorImage;					//!< Color image
+	Move<VkImageView>			colorImageView;				//!< Color attachment
+	MovePtr<Allocation>			colorImageAlloc;
+	Move<VkImage>				depthStencilImage;			//!< Depth stencil image
+	Move<VkImageView>			depthStencilImageView;		//!< Depth stencil attachment
+	Move<VkImageView>			depthOnlyImageView;			//!< Depth aspect for shader read
+	Move<VkImageView>			stencilOnlyImageView;		//!< Stencil aspect for shader read
+	MovePtr<Allocation>			depthStencilImageAlloc;
+	Move<VkImage>				resolveImage;				//!< Resolve image
+	Move<VkImageView>			resolveImageView;			//!< Resolve attachment
+	MovePtr<Allocation>			resolveImageAlloc;
+	Move<VkBuffer>				colorBuffer;				//!< Buffer used to copy resolve output
+	MovePtr<Allocation>			colorBufferAlloc;
+	VkDeviceSize				colorBufferSize;
+
+	WorkingData (void)
+		: numVertices		()
+	{
+	}
+};
+
+void initPrograms (SourceCollections& programCollection, const TestParams params)
+{
+	// Vertex shader - no vertex data
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "out gl_PerVertex {\n"
+			<< "    vec4 gl_Position;\n"
+			<< "};\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			// Specify an oversized triangle covering the whole viewport.
+			<< "    switch (gl_VertexIndex)\n"
+			<< "    {\n"
+			<< "        case 0:\n"
+			<< "            gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "        case 1:\n"
+			<< "            gl_Position = vec4(-1.0,  3.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "        case 2:\n"
+			<< "            gl_Position = vec4( 3.0, -1.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "    }\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+	}
+
+	// Fragment shader
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "layout(location = 0) out vec4 o_color;\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    vec4 col = vec4(0.0, 0.0, 0.0, 1.0);\n"
+			<< "\n";
+
+		if (params.numColorSamples == VK_SAMPLE_COUNT_1_BIT)
+		{
+			const deUint32 expectedMask = ((1u << static_cast<deUint32>(params.numCoverageSamples)) - 1u);
+
+			// Expect all covered samples to be lit, the rest is zero
+			src << "    if (gl_SampleMaskIn[0] == " << expectedMask << ")\n"
+				<< "        col.g = 1.0;\n"
+				<< "    else\n"
+				<< "        col.r = 1.0;\n";
+		}
+		else
+		{
+			// Expect only a matching sample to be lit
+			src << "    if (gl_SampleMaskIn[0] == (1 << gl_SampleID))\n"
+				<< "        col.g = 1.0;\n"
+				<< "    else\n"
+				<< "        col.r = 1.0;\n"
+				<< "\n"
+				<< "    if (gl_SampleID >= " << static_cast<deUint32>(params.numColorSamples) << ")  // number of color samples, should not happen\n"
+				<< "        col.b = 1.0;\n";
+		}
+
+		src << "\n"
+			<< "    o_color = col;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+	}
+}
+
+//! A simple color, depth/stencil draw. Single subpass, no vertex input
+void drawResolve (Context& context, const TestParams& params, WorkingData& wd)
+{
+	const DeviceInterface&	vk			= context.getDeviceInterface();
+	const VkDevice			device		= context.getDevice();
+	const bool				needResolve	= (params.numColorSamples != VK_SAMPLE_COUNT_1_BIT);
+
+	Move<VkRenderPass>		renderPass;
+	Move<VkFramebuffer>		framebuffer;
+
+	// Create a render pass and a framebuffer
+	{
+		std::vector<VkImageView>				attachments;
+		std::vector<VkAttachmentDescription>	attachmentDescriptions;
+
+		attachments.push_back(*wd.colorImageView);
+		attachments.push_back(*wd.depthStencilImageView);
+
+		attachmentDescriptions.push_back(makeAttachmentDescription(
+			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags;
+			params.colorFormat,										// VkFormat							format;
+			params.numColorSamples,									// VkSampleCountFlagBits			samples;
+			VK_ATTACHMENT_LOAD_OP_CLEAR,							// VkAttachmentLoadOp				loadOp;
+			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp;
+			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp;
+			VK_ATTACHMENT_STORE_OP_DONT_CARE,						// VkAttachmentStoreOp				stencilStoreOp;
+			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout;
+			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL					// VkImageLayout					finalLayout;
+		));
+
+		attachmentDescriptions.push_back(makeAttachmentDescription(
+			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags;
+			params.depthStencilFormat,								// VkFormat							format;
+			params.numDepthStencilSamples,							// VkSampleCountFlagBits			samples;
+			VK_ATTACHMENT_LOAD_OP_CLEAR,							// VkAttachmentLoadOp				loadOp;
+			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp;
+			VK_ATTACHMENT_LOAD_OP_CLEAR,							// VkAttachmentLoadOp				stencilLoadOp;
+			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp;
+			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout;
+			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL		// VkImageLayout					finalLayout;
+		));
+
+		if (needResolve)
+		{
+			attachments.push_back(*wd.resolveImageView);
+
+			attachmentDescriptions.push_back(makeAttachmentDescription(
+				(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
+				params.colorFormat,									// VkFormat							format;
+				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				loadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
+				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
+				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL				// VkImageLayout					finalLayout;
+			));
+		}
+
+		const VkAttachmentReference	colorRef		= makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+		const VkAttachmentReference	depthStencilRef	= makeAttachmentReference(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+		const VkAttachmentReference	resolveRef		= makeAttachmentReference(2u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+		const VkSubpassDescription subpassDescription =
+		{
+			(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags       flags;
+			VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint             pipelineBindPoint;
+			0u,														// uint32_t                        inputAttachmentCount;
+			DE_NULL,												// const VkAttachmentReference*    pInputAttachments;
+			1u,														// uint32_t                        colorAttachmentCount;
+			&colorRef,												// const VkAttachmentReference*    pColorAttachments;
+			(needResolve ? &resolveRef : DE_NULL),					// const VkAttachmentReference*    pResolveAttachments;
+			&depthStencilRef,										// const VkAttachmentReference*    pDepthStencilAttachment;
+			0u,														// uint32_t                        preserveAttachmentCount;
+			DE_NULL,												// const uint32_t*                 pPreserveAttachments;
+		};
+
+		// Assume there are no dependencies between subpasses
+		VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
+			DE_NULL,												// const void*						pNext;
+			(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
+			static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
+			dataOrNullPtr(attachmentDescriptions),					// const VkAttachmentDescription*	pAttachments;
+			1u,														// deUint32							subpassCount;
+			&subpassDescription,									// const VkSubpassDescription*		pSubpasses;
+			0u,														// deUint32							dependencyCount;
+			DE_NULL,												// const VkSubpassDependency*		pDependencies;
+		};
+
+		renderPass  = createRenderPass(vk, device, &renderPassInfo);
+		framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), wd.renderSize.x(), wd.renderSize.y());
+	}
+
+	const Unique<VkShaderModule>	vertexModule	(createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
+	const Unique<VkShaderModule>	fragmentModule	(createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
+	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device));
+	const bool						useVertexInput	= false;
+	const bool						sampleShading	= (params.numColorSamples != VK_SAMPLE_COUNT_1_BIT);
+	const deUint32					subpassNdx		= 0u;
+	const Unique<VkPipeline>		pipeline		(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, useVertexInput, subpassNdx,
+																		  wd.renderSize, getImageAspectFlags(params.depthStencilFormat), params.numCoverageSamples, sampleShading));
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	{
+		std::vector<VkClearValue> clearValues;
+		clearValues.push_back(makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f));
+		clearValues.push_back(makeClearValueDepthStencil(1.0f, 0u));
+
+		const VkRect2D renderArea =
+		{
+			{ 0u, 0u },
+			{ wd.renderSize.x(), wd.renderSize.y() }
+		};
+
+		const VkRenderPassBeginInfo renderPassBeginInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			// VkStructureType         sType;
+			DE_NULL,											// const void*             pNext;
+			*renderPass,										// VkRenderPass            renderPass;
+			*framebuffer,										// VkFramebuffer           framebuffer;
+			renderArea,											// VkRect2D                renderArea;
+			static_cast<deUint32>(clearValues.size()),			// uint32_t                clearValueCount;
+			dataOrNullPtr(clearValues),							// const VkClearValue*     pClearValues;
+		};
+		vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+	}
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
+	vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
+
+	vk.cmdEndRenderPass(*cmdBuffer);
+
+	if (needResolve)
+		recordCopyOutputImageToBuffer(vk, *cmdBuffer, wd.renderSize, *wd.resolveImage, *wd.colorBuffer);
+	else
+		recordCopyOutputImageToBuffer(vk, *cmdBuffer, wd.renderSize, *wd.colorImage, *wd.colorBuffer);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+}
+
+void checkRequirements (Context& context, TestParams params)
+{
+	context.requireDeviceFunctionality("VK_AMD_mixed_attachment_samples");
+
+	checkSampleRequirements(context, params.numColorSamples, params.numDepthStencilSamples, false /* require standard sample locations */);
+}
+
+//! Verify the values of shader builtins
+tcu::TestStatus test (Context& context, const TestParams params)
+{
+	WorkingData				wd;
+	const DeviceInterface&	vk			= context.getDeviceInterface();
+	const VkDevice			device		= context.getDevice();
+	MovePtr<Allocator>		allocator	= MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())));
+
+	wd.renderSize	= UVec2(16, 16);
+
+	// Create images and a color buffer
+	{
+
+		const VkImageUsageFlags	colorImageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+		const VkImageUsageFlags depthStencilImageUsageFlags	= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+
+		checkImageRequirements (context,
+								params.colorFormat,
+								VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT,
+								colorImageUsageFlags,
+								params.numColorSamples);
+
+		wd.colorImage		= makeImage(vk, device, params.colorFormat, wd.renderSize, params.numColorSamples, colorImageUsageFlags);
+		wd.colorImageAlloc	= bindImage(vk, device, *allocator, *wd.colorImage, MemoryRequirement::Any);
+		wd.colorImageView	= makeImageView(vk, device, *wd.colorImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
+
+		if (params.numColorSamples != VK_SAMPLE_COUNT_1_BIT)
+		{
+			wd.resolveImage			= makeImage(vk, device, params.colorFormat, wd.renderSize, VK_SAMPLE_COUNT_1_BIT, colorImageUsageFlags);
+			wd.resolveImageAlloc	= bindImage(vk, device, *allocator, *wd.resolveImage, MemoryRequirement::Any);
+			wd.resolveImageView		= makeImageView(vk, device, *wd.resolveImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
+		}
+
+		// Resolve result
+		wd.colorBufferSize	= static_cast<VkDeviceSize>(tcu::getPixelSize(mapVkFormat(params.colorFormat)) * wd.renderSize.x() * wd.renderSize.y());
+		wd.colorBuffer		= makeBuffer(vk, device, wd.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+		wd.colorBufferAlloc	= bindBuffer(vk, device, *allocator, *wd.colorBuffer, MemoryRequirement::HostVisible);
+
+		deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize));
+		flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+
+		checkImageRequirements (context,
+								params.depthStencilFormat,
+								VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
+								depthStencilImageUsageFlags,
+								params.numDepthStencilSamples);
+
+		wd.depthStencilImage		= makeImage(vk, device, params.depthStencilFormat, wd.renderSize, params.numDepthStencilSamples, depthStencilImageUsageFlags);
+		wd.depthStencilImageAlloc	= bindImage(vk, device, *allocator, *wd.depthStencilImage, MemoryRequirement::Any);
+		wd.depthStencilImageView	= makeImageView(vk, device, *wd.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(getImageAspectFlags(params.depthStencilFormat), 0u, 1u, 0u, 1u));
+
+		if (isDepthFormat(params.depthStencilFormat))
+			wd.depthOnlyImageView	= makeImageView(vk, device, *wd.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u));
+
+		if (isStencilFormat(params.depthStencilFormat))
+			wd.stencilOnlyImageView	= makeImageView(vk, device, *wd.depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, params.depthStencilFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u));
+	}
+
+	// Draw, resolve, and copy to color buffer (see the fragment shader for details)
+	drawResolve(context, params, wd);
+
+	// Verify resolved image
+	{
+		const tcu::ConstPixelBufferAccess image (tcu::ConstPixelBufferAccess(mapVkFormat(params.colorFormat), tcu::IVec3(wd.renderSize.x(), wd.renderSize.y(), 1),wd.colorBufferAlloc->getHostPtr()));
+
+		if (compareGreenImage(context.getTestContext().getLog(), "resolve0", "Resolved test image", image))
+			return tcu::TestStatus::pass("Pass");
+		else
+			return tcu::TestStatus::fail("Some samples were incorrect");
+	}
+}
+
+} // ShaderBuiltins
+
+std::string getSampleCountGroupName(const VkSampleCountFlagBits coverageCount,
+									const VkSampleCountFlagBits colorCount,
+									const VkSampleCountFlagBits depthStencilCount)
+{
+	std::ostringstream str;
+	str << "coverage_"		 << static_cast<deUint32>(coverageCount)
+		<< "_color_"		 << static_cast<deUint32>(colorCount)
+		<< "_depth_stencil_" << static_cast<deUint32>(depthStencilCount);
+	return str.str();
+}
+
+std::string getFormatShortString (const VkFormat format)
+{
+	std::string s(de::toLower(getFormatName(format)));
+	return s.substr(10);
+}
+
+std::string getFormatCaseName (const VkFormat colorFormat,
+							   const VkFormat depthStencilFormat)
+{
+	std::ostringstream str;
+	str << getFormatShortString(colorFormat) << "_" << getFormatShortString(depthStencilFormat);
+	return str.str();
+}
+
+void createMixedAttachmentSamplesTestsInGroup (tcu::TestCaseGroup* rootGroup)
+{
+	const VkFormat colorFormatRange[] =
+	{
+		VK_FORMAT_R8G8B8A8_UNORM,
+		// If you add more, make sure it is handled in the test/shader
+	};
+
+	const VkFormat depthStencilFormatRange[] =
+	{
+		VK_FORMAT_D16_UNORM,
+		VK_FORMAT_X8_D24_UNORM_PACK32,
+		VK_FORMAT_D32_SFLOAT,
+		VK_FORMAT_S8_UINT,
+		VK_FORMAT_D16_UNORM_S8_UINT,
+		VK_FORMAT_D24_UNORM_S8_UINT,
+		VK_FORMAT_D32_SFLOAT_S8_UINT,
+	};
+
+	// Minimal set of formats to cover depth and stencil
+	const VkFormat depthStencilReducedFormatRange[] =
+	{
+		VK_FORMAT_D16_UNORM,				//!< Must be supported
+		VK_FORMAT_D24_UNORM_S8_UINT,		//!< Either this, or the next one must be supported
+		VK_FORMAT_D32_SFLOAT_S8_UINT,
+	};
+
+	struct SampleCase
+	{
+		VkSampleCountFlagBits	colorSamples;
+		VkSampleCountFlagBits	depthStencilSamples;
+	};
+
+	// Currently supported EQAA cases
+	static const SampleCase	singlePassCases[] =
+	{
+		// Less color than depth/stencil
+		{ VK_SAMPLE_COUNT_1_BIT,	VK_SAMPLE_COUNT_2_BIT  },
+		{ VK_SAMPLE_COUNT_1_BIT,	VK_SAMPLE_COUNT_4_BIT  },
+		{ VK_SAMPLE_COUNT_1_BIT,	VK_SAMPLE_COUNT_8_BIT  },
+		{ VK_SAMPLE_COUNT_1_BIT,	VK_SAMPLE_COUNT_16_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT,	VK_SAMPLE_COUNT_4_BIT  },
+		{ VK_SAMPLE_COUNT_2_BIT,	VK_SAMPLE_COUNT_8_BIT  },
+		{ VK_SAMPLE_COUNT_2_BIT,	VK_SAMPLE_COUNT_16_BIT },
+		{ VK_SAMPLE_COUNT_4_BIT,	VK_SAMPLE_COUNT_8_BIT  },
+		{ VK_SAMPLE_COUNT_4_BIT,	VK_SAMPLE_COUNT_16_BIT },
+		{ VK_SAMPLE_COUNT_8_BIT,	VK_SAMPLE_COUNT_16_BIT },
+	};
+
+	// Multi-subpass cases
+
+	static const SampleCase caseSubpassIncreaseColor_1[] =
+	{
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+	};
+	static const SampleCase caseSubpassIncreaseColor_2[] =
+	{
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_8_BIT },
+		{ VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT },
+	};
+	static const SampleCase caseSubpassDecreaseColor_1[] =
+	{
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT },
+	};
+	static const SampleCase caseSubpassDecreaseColor_2[] =
+	{
+		{ VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_8_BIT },
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT },
+	};
+	static const SampleCase caseSubpassIncreaseCoverage_1[] =
+	{
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_2_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+	};
+	static const SampleCase caseSubpassIncreaseCoverage_2[] =
+	{
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_2_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+		{ VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT },
+	};
+	static const SampleCase caseSubpassDecreaseCoverage_1[] =
+	{
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_2_BIT },
+	};
+	static const SampleCase caseSubpassDecreaseCoverage_2[] =
+	{
+		{ VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT },
+		{ VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT },
+		{ VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_2_BIT },
+	};
+
+	static const struct
+	{
+		const char* const	caseName;
+		const deUint32		numSampleCases;
+		const SampleCase*	pSampleCase;
+	} subpassCases[] =
+	{
+		{ "multi_subpass_decrease_color_4",		DE_LENGTH_OF_ARRAY(caseSubpassDecreaseColor_1),		caseSubpassDecreaseColor_1 },
+		{ "multi_subpass_decrease_color_8",		DE_LENGTH_OF_ARRAY(caseSubpassDecreaseColor_2),		caseSubpassDecreaseColor_2 },
+		{ "multi_subpass_decrease_coverage_4",	DE_LENGTH_OF_ARRAY(caseSubpassDecreaseCoverage_1),	caseSubpassDecreaseCoverage_1 },
+		{ "multi_subpass_decrease_coverage_8",	DE_LENGTH_OF_ARRAY(caseSubpassDecreaseCoverage_2),	caseSubpassDecreaseCoverage_2 },
+		{ "multi_subpass_increase_color_4",		DE_LENGTH_OF_ARRAY(caseSubpassIncreaseColor_1),		caseSubpassIncreaseColor_1 },
+		{ "multi_subpass_increase_color_8",		DE_LENGTH_OF_ARRAY(caseSubpassIncreaseColor_2),		caseSubpassIncreaseColor_2 },
+		{ "multi_subpass_increase_coverage_4",	DE_LENGTH_OF_ARRAY(caseSubpassIncreaseCoverage_1),	caseSubpassIncreaseCoverage_1 },
+		{ "multi_subpass_increase_coverage_8",	DE_LENGTH_OF_ARRAY(caseSubpassIncreaseCoverage_2),	caseSubpassIncreaseCoverage_2 },
+	};
+
+	// Test 1: Per-sample expected value check
+	{
+		MovePtr<tcu::TestCaseGroup> standardLocationsGroup		(new tcu::TestCaseGroup(rootGroup->getTestContext(), "verify_standard_locations", ""));
+		MovePtr<tcu::TestCaseGroup> programmableLocationsGroup	(new tcu::TestCaseGroup(rootGroup->getTestContext(), "verify_programmable_locations", ""));
+
+		tcu::TestCaseGroup* locationsGroups[2] =
+		{
+			standardLocationsGroup.get(),
+			programmableLocationsGroup.get()
+		};
+
+		for (deUint32 groupNdx = 0u; groupNdx < DE_LENGTH_OF_ARRAY(locationsGroups); ++groupNdx)
+		{
+			// Single subpass cases
+			for (deUint32 caseNdx = 0u; caseNdx < DE_LENGTH_OF_ARRAY(singlePassCases); ++caseNdx)
+			{
+				VerifySamples::TestParams::SampleCount	samples;
+				samples.numColorSamples					= singlePassCases[caseNdx].colorSamples;
+				samples.numDepthStencilSamples			= singlePassCases[caseNdx].depthStencilSamples;
+				samples.numCoverageSamples				= de::max(samples.numColorSamples, samples.numDepthStencilSamples);
+
+				VerifySamples::TestParams params;
+				params.perSubpassSamples.push_back(samples);
+				params.useProgrammableSampleLocations	= (locationsGroups[groupNdx] == programmableLocationsGroup.get());
+
+				MovePtr<tcu::TestCaseGroup> sampleCaseGroup(new tcu::TestCaseGroup(
+					rootGroup->getTestContext(), getSampleCountGroupName(samples.numCoverageSamples, samples.numColorSamples, samples.numDepthStencilSamples).c_str(), ""));
+
+				for (const VkFormat *pDepthStencilFormat = depthStencilFormatRange; pDepthStencilFormat != DE_ARRAY_END(depthStencilFormatRange); ++pDepthStencilFormat)
+				for (const VkFormat *pColorFormat		 = colorFormatRange;		pColorFormat		!= DE_ARRAY_END(colorFormatRange);		  ++pColorFormat)
+				{
+					params.colorFormat			= *pColorFormat;
+					params.depthStencilFormat	= *pDepthStencilFormat;
+
+					addFunctionCaseWithPrograms(
+						sampleCaseGroup.get(),
+						getFormatCaseName(params.colorFormat, params.depthStencilFormat).c_str(),
+						"",
+						VerifySamples::checkRequirements,
+						VerifySamples::initPrograms,
+						VerifySamples::test, params);
+				}
+
+				locationsGroups[groupNdx]->addChild(sampleCaseGroup.release());
+			}
+
+			// Multi subpass cases
+			for (deUint32 caseNdx = 0u; caseNdx < DE_LENGTH_OF_ARRAY(subpassCases); ++caseNdx)
+			{
+				VerifySamples::TestParams params;
+				params.useProgrammableSampleLocations = (locationsGroups[groupNdx] == programmableLocationsGroup.get());
+
+				for (deUint32 subpassNdx = 0; subpassNdx < subpassCases[caseNdx].numSampleCases; ++subpassNdx)
+				{
+					VerifySamples::TestParams::SampleCount	samples;
+					samples.numColorSamples					= subpassCases[caseNdx].pSampleCase[subpassNdx].colorSamples;
+					samples.numDepthStencilSamples			= subpassCases[caseNdx].pSampleCase[subpassNdx].depthStencilSamples;
+					samples.numCoverageSamples				= de::max(samples.numColorSamples, samples.numDepthStencilSamples);
+					params.perSubpassSamples.push_back(samples);
+				}
+
+				MovePtr<tcu::TestCaseGroup> sampleCaseGroup(new tcu::TestCaseGroup(rootGroup->getTestContext(), subpassCases[caseNdx].caseName, ""));
+
+				for (const VkFormat *pDepthStencilFormat = depthStencilReducedFormatRange;	pDepthStencilFormat != DE_ARRAY_END(depthStencilReducedFormatRange); ++pDepthStencilFormat)
+				for (const VkFormat *pColorFormat		 = colorFormatRange;				pColorFormat		!= DE_ARRAY_END(colorFormatRange);				 ++pColorFormat)
+				{
+					params.colorFormat			= *pColorFormat;
+					params.depthStencilFormat	= *pDepthStencilFormat;
+
+					addFunctionCaseWithPrograms(
+						sampleCaseGroup.get(),
+						getFormatCaseName(params.colorFormat, params.depthStencilFormat).c_str(),
+						"",
+						VerifySamples::checkRequirements,
+						VerifySamples::initPrograms,
+						VerifySamples::test, params);
+				}
+
+				locationsGroups[groupNdx]->addChild(sampleCaseGroup.release());
+			}
+		}
+
+		rootGroup->addChild(standardLocationsGroup.release());
+		rootGroup->addChild(programmableLocationsGroup.release());
+	}
+
+	// Test 2: Shader built-ins check
+	{
+		MovePtr<tcu::TestCaseGroup> builtinsGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), "shader_builtins", ""));
+
+		for (deUint32 caseNdx = 0u; caseNdx < DE_LENGTH_OF_ARRAY(singlePassCases); ++caseNdx)
+		{
+			ShaderBuiltins::TestParams params;
+			params.numColorSamples			= singlePassCases[caseNdx].colorSamples;
+			params.numDepthStencilSamples	= singlePassCases[caseNdx].depthStencilSamples;
+			params.numCoverageSamples		= de::max(params.numColorSamples, params.numDepthStencilSamples);
+
+			MovePtr<tcu::TestCaseGroup> sampleCaseGroup(new tcu::TestCaseGroup(
+				rootGroup->getTestContext(), getSampleCountGroupName(params.numCoverageSamples, params.numColorSamples, params.numDepthStencilSamples).c_str(), ""));
+
+			for (const VkFormat *pDepthStencilFormat = depthStencilReducedFormatRange;  pDepthStencilFormat != DE_ARRAY_END(depthStencilReducedFormatRange); ++pDepthStencilFormat)
+			for (const VkFormat *pColorFormat		 = colorFormatRange;				pColorFormat		!= DE_ARRAY_END(colorFormatRange);				 ++pColorFormat)
+			{
+				params.colorFormat			= *pColorFormat;
+				params.depthStencilFormat	= *pDepthStencilFormat;
+
+				addFunctionCaseWithPrograms(
+					sampleCaseGroup.get(),
+					getFormatCaseName(params.colorFormat, params.depthStencilFormat).c_str(),
+					"",
+					ShaderBuiltins::checkRequirements,
+					ShaderBuiltins::initPrograms,
+					ShaderBuiltins::test,
+					params);
+			}
+
+			builtinsGroup->addChild(sampleCaseGroup.release());
+		}
+
+		rootGroup->addChild(builtinsGroup.release());
+	}
+}
+
+} // anonymous ns
+
+tcu::TestCaseGroup* createMultisampleMixedAttachmentSamplesTests (tcu::TestContext& testCtx)
+{
+	return createTestGroup(testCtx, "mixed_attachment_samples", "Test a graphics pipeline with varying sample count per color and depth/stencil attachments", createMixedAttachmentSamplesTestsInGroup);
+}
+
+} // pipeline
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.hpp
new file mode 100644
index 0000000..7653090
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleMixedAttachmentSamplesTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTPIPELINEMULTISAMPLEMIXEDATTACHMENTSAMPLESTESTS_HPP
+#define _VKTPIPELINEMULTISAMPLEMIXEDATTACHMENTSAMPLESTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_mixed_attachment_samples
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+tcu::TestCaseGroup* createMultisampleMixedAttachmentSamplesTests (tcu::TestContext& testCtx);
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLEMIXEDATTACHMENTSAMPLESTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleSampleLocationsExtTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleSampleLocationsExtTests.cpp
index 6067bd2..80861fa 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleSampleLocationsExtTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleSampleLocationsExtTests.cpp
@@ -23,6 +23,7 @@
  *//*--------------------------------------------------------------------*/
 
 #include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
+#include "vktPipelineSampleLocationsUtil.hpp"
 #include "vktPipelineMakeUtil.hpp"
 #include "vktTestCase.hpp"
 #include "vktTestGroupUtil.hpp"
@@ -211,72 +212,11 @@
 	return sampleLocationsProperties;
 }
 
-//! Specify sample locations in a pixel grid
-class MultisamplePixelGrid
-{
-public:
-	MultisamplePixelGrid (const tcu::UVec2& gridSize, const VkSampleCountFlagBits numSamples)
-		: m_gridSize		(gridSize)
-		, m_numSamples		(numSamples)
-		, m_sampleLocations	(gridSize.x() * gridSize.y() * numSamples)
-	{
-		DE_ASSERT(gridSize.x() > 0 && gridSize.y() > 0);
-		DE_ASSERT(numSamples   > 1);
-	}
-
-	//! If grid x,y is larger than gridSize, then each coordinate is wrapped, x' = x % size_x
-	const VkSampleLocationEXT& getSample (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
-	{
-		return m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)];
-	}
-
-	void setSample (const deUint32 gridX, const deUint32 gridY, const deUint32 sampleNdx, const VkSampleLocationEXT& location)
-	{
-		DE_ASSERT(gridX < m_gridSize.x());
-		DE_ASSERT(gridY < m_gridSize.y());
-
-		m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)] = location;
-	}
-
-	const tcu::UVec2&			size				(void) const	{ return m_gridSize; }
-	VkSampleCountFlagBits		samplesPerPixel		(void) const	{ return m_numSamples; }
-	const VkSampleLocationEXT*	sampleLocations		(void) const	{ return dataOrNullPtr(m_sampleLocations); }
-	VkSampleLocationEXT*		sampleLocations		(void)			{ return dataOrNullPtr(m_sampleLocations); }
-	deUint32					sampleLocationCount	(void) const	{ return static_cast<deUint32>(m_sampleLocations.size()); }
-
-private:
-	deUint32 getSampleIndex (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
-	{
-		gridX %= m_gridSize.x();
-		gridY %= m_gridSize.y();
-		return (gridY * m_gridSize.x() + gridX) * static_cast<deUint32>(m_numSamples) + sampleNdx;
-	}
-
-	tcu::UVec2							m_gridSize;
-	VkSampleCountFlagBits				m_numSamples;
-	std::vector<VkSampleLocationEXT>	m_sampleLocations;
-};
-
 inline deUint32 numSamplesPerPixel (const MultisamplePixelGrid& pixelGrid)
 {
 	return static_cast<deUint32>(pixelGrid.samplesPerPixel());
 }
 
-//! References the data inside MultisamplePixelGrid
-inline VkSampleLocationsInfoEXT makeSampleLocationsInfo (const MultisamplePixelGrid& pixelGrid)
-{
-	const VkSampleLocationsInfoEXT info =
-	{
-		VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,				// VkStructureType               sType;
-		DE_NULL,													// const void*                   pNext;
-		pixelGrid.samplesPerPixel(),								// VkSampleCountFlagBits         sampleLocationsPerPixel;
-		makeExtent2D(pixelGrid.size().x(), pixelGrid.size().y()),	// VkExtent2D                    sampleLocationGridSize;
-		pixelGrid.sampleLocationCount(),							// uint32_t                      sampleLocationsCount;
-		pixelGrid.sampleLocations(),								// const VkSampleLocationEXT*    pSampleLocations;
-	};
-	return info;
-}
-
 inline VkSampleLocationsInfoEXT makeEmptySampleLocationsInfo ()
 {
 	const VkSampleLocationsInfoEXT info =
@@ -348,38 +288,6 @@
 	log << tcu::TestLog::EndSection;
 }
 
-//! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
-void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed = 142u)
-{
-	const deUint32	numLocations	= 1u << subPixelBits;
-	de::Random		rng				(seed);
-
-	for (deUint32 gridY = 0; gridY < grid.size().y(); ++gridY)
-	for (deUint32 gridX = 0; gridX < grid.size().x(); ++gridX)
-	{
-		std::set<UVec2, LessThan<UVec2> >	takenLocationIndices;
-		for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(grid); /* no increment */)
-		{
-			const UVec2 locationNdx (rng.getUint32() % numLocations,
-									 rng.getUint32() % numLocations);
-
-			if (takenLocationIndices.find(locationNdx) == takenLocationIndices.end())
-			{
-				const VkSampleLocationEXT location =
-				{
-					static_cast<float>(locationNdx.x()) / static_cast<float>(numLocations),	// float x;
-					static_cast<float>(locationNdx.y()) / static_cast<float>(numLocations),	// float y;
-				};
-
-				grid.setSample(gridX, gridY, sampleNdx, location);
-				takenLocationIndices.insert(locationNdx);
-
-				++sampleNdx;	// next sample
-			}
-		}
-	}
-}
-
 //! Place samples very close to each other
 void fillSampleLocationsPacked (MultisamplePixelGrid& grid, const deUint32 subPixelBits)
 {
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.cpp
new file mode 100644
index 0000000..d27aada
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.cpp
@@ -0,0 +1,1309 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_shader_fragment_mask
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vktTestCase.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkImageUtil.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
+#include "deRandom.hpp"
+
+#include "tcuVector.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include <string>
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace
+{
+using namespace vk;
+using de::UniquePtr;
+using de::MovePtr;
+using de::SharedPtr;
+using tcu::UVec2;
+using tcu::UVec4;
+using tcu::Vec2;
+using tcu::Vec4;
+
+typedef SharedPtr<Unique<VkImageView> >		ImageViewSp;
+typedef SharedPtr<Unique<VkPipeline> >		PipelineSp;
+
+struct PositionColor
+{
+	tcu::Vec4	        position;
+	VkClearColorValue	color;
+
+	PositionColor (const tcu::Vec4& pos, const tcu::UVec4& col) : position(pos)
+    {
+        deMemcpy(color.uint32, col.getPtr(), sizeof(color.uint32));
+    }
+
+	PositionColor (const tcu::Vec4& pos, const tcu::Vec4&  col) : position(pos)
+    {
+        deMemcpy(color.float32, col.getPtr(), sizeof(color.float32));
+    }
+
+	PositionColor (const PositionColor& rhs)
+		: position	(rhs.position)
+        , color     (rhs.color)
+	{
+	}
+};
+
+//! Make a dummy sampler.
+Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
+{
+	const VkSamplerCreateInfo samplerParams =
+	{
+		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			// VkStructureType         sType;
+		DE_NULL,										// const void*             pNext;
+		(VkSamplerCreateFlags)0,						// VkSamplerCreateFlags    flags;
+		VK_FILTER_NEAREST,								// VkFilter                magFilter;
+		VK_FILTER_NEAREST,								// VkFilter                minFilter;
+		VK_SAMPLER_MIPMAP_MODE_NEAREST,					// VkSamplerMipmapMode     mipmapMode;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeU;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeV;
+		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode    addressModeW;
+		0.0f,											// float                   mipLodBias;
+		VK_FALSE,										// VkBool32                anisotropyEnable;
+		1.0f,											// float                   maxAnisotropy;
+		VK_FALSE,										// VkBool32                compareEnable;
+		VK_COMPARE_OP_ALWAYS,							// VkCompareOp             compareOp;
+		0.0f,											// float                   minLod;
+		0.0f,											// float                   maxLod;
+		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		// VkBorderColor           borderColor;
+		VK_FALSE,										// VkBool32                unnormalizedCoordinates;
+	};
+	return createSampler(vk, device, &samplerParams);
+}
+
+Move<VkImage> makeImage (const DeviceInterface&			vk,
+						 const VkDevice					device,
+						 const VkFormat					format,
+						 const UVec2&					size,
+						 const deUint32					layers,
+						 const VkSampleCountFlagBits	samples,
+						 const VkImageUsageFlags		usage)
+{
+	const VkImageCreateInfo imageParams =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
+		DE_NULL,										// const void*				pNext;
+		(VkImageCreateFlags)0,							// VkImageCreateFlags		flags;
+		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
+		format,											// VkFormat					format;
+		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
+		1u,												// deUint32					mipLevels;
+		layers,											// deUint32					arrayLayers;
+		samples,										// VkSampleCountFlagBits	samples;
+		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
+		usage,											// VkImageUsageFlags		usage;
+		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
+		0u,												// deUint32					queueFamilyIndexCount;
+		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
+		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
+	};
+	return createImage(vk, device, &imageParams);
+}
+
+//! Create a test-specific MSAA pipeline
+Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&					vk,
+									   const VkDevice							device,
+									   const VkPipelineLayout					pipelineLayout,
+									   const VkRenderPass						renderPass,
+									   const VkShaderModule						vertexModule,
+									   const VkShaderModule						fragmentModule,
+									   const bool								useVertexInput,
+									   const VkFormat							vertexAttribColorFormat,
+									   const bool								useColorAttachment,
+									   const deUint32							subpassNdx,
+									   const UVec2&								renderSize,
+									   const VkSampleCountFlagBits				numSamples)
+{
+	std::vector<VkVertexInputBindingDescription>	vertexInputBindingDescriptions;
+	std::vector<VkVertexInputAttributeDescription>	vertexInputAttributeDescriptions;
+
+	// Vertex attributes: position and color
+	if (useVertexInput)
+	{
+		vertexInputBindingDescriptions.push_back  (makeVertexInputBindingDescription  (0u, sizeof(PositionColor), VK_VERTEX_INPUT_RATE_VERTEX));
+		vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u));
+		vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(1u, 0u, vertexAttribColorFormat, sizeof(Vec4)));
+	}
+
+	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags	flags;
+		static_cast<deUint32>(vertexInputBindingDescriptions.size()),	// uint32_t									vertexBindingDescriptionCount;
+		dataOrNullPtr(vertexInputBindingDescriptions),					// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		static_cast<deUint32>(vertexInputAttributeDescriptions.size()),	// uint32_t									vertexAttributeDescriptionCount;
+		dataOrNullPtr(vertexInputAttributeDescriptions),				// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+	};
+
+	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,														// const void*								pNext;
+		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
+		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
+		VK_FALSE,														// VkBool32									primitiveRestartEnable;
+	};
+
+	const VkViewport viewport =
+	{
+		0.0f, 0.0f,																	// x, y
+		static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),		// widht, height
+		0.0f, 1.0f																	// minDepth, maxDepth
+	};
+
+	const VkRect2D scissor =
+	{
+		makeOffset2D(0, 0),
+		makeExtent2D(renderSize.x(), renderSize.y()),
+	};
+
+	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
+		DE_NULL,														// const void*							pNext;
+		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags	flags;
+		1u,																// uint32_t								viewportCount;
+		&viewport,														// const VkViewport*					pViewports;
+		1u,																// uint32_t								scissorCount;
+		&scissor,														// const VkRect2D*						pScissors;
+	};
+
+	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags	flags;
+		VK_FALSE,													// VkBool32									depthClampEnable;
+		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
+		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
+		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
+		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
+		VK_FALSE,													// VkBool32									depthBiasEnable;
+		0.0f,														// float									depthBiasConstantFactor;
+		0.0f,														// float									depthBiasClamp;
+		0.0f,														// float									depthBiasSlopeFactor;
+		1.0f,														// float									lineWidth;
+	};
+
+	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
+		numSamples,													// VkSampleCountFlagBits					rasterizationSamples;
+		VK_FALSE,													// VkBool32									sampleShadingEnable;
+		1.0f,														// float									minSampleShading;
+		DE_NULL,													// const VkSampleMask*						pSampleMask;
+		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
+		VK_FALSE													// VkBool32									alphaToOneEnable;
+	};
+
+	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
+		VK_FALSE,													// VkBool32									depthTestEnable;
+		VK_TRUE,													// VkBool32									depthWriteEnable;
+		VK_COMPARE_OP_ALWAYS,										// VkCompareOp								depthCompareOp;
+		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
+		VK_FALSE,													// VkBool32									stencilTestEnable;
+		VkStencilOpState(),											// VkStencilOpState							front;
+		VkStencilOpState(),											// VkStencilOpState							back;
+		0.0f,														// float									minDepthBounds;
+		1.0f,														// float									maxDepthBounds;
+	};
+
+	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+	const VkPipelineColorBlendAttachmentState defaultBlendAttachmentState =
+	{
+		VK_FALSE,				// VkBool32					blendEnable;
+		VK_BLEND_FACTOR_ONE,	// VkBlendFactor			srcColorBlendFactor;
+		VK_BLEND_FACTOR_ZERO,	// VkBlendFactor			dstColorBlendFactor;
+		VK_BLEND_OP_ADD,		// VkBlendOp				colorBlendOp;
+		VK_BLEND_FACTOR_ONE,	// VkBlendFactor			srcAlphaBlendFactor;
+		VK_BLEND_FACTOR_ZERO,	// VkBlendFactor			dstAlphaBlendFactor;
+		VK_BLEND_OP_ADD,		// VkBlendOp				alphaBlendOp;
+		colorComponentsAll,		// VkColorComponentFlags	colorWriteMask;
+	};
+
+	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+		DE_NULL,													// const void*									pNext;
+		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
+		VK_FALSE,													// VkBool32										logicOpEnable;
+		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+		(useColorAttachment ? 1u : 0u),								// deUint32										attachmentCount;
+		&defaultBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
+		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
+	};
+
+	const VkPipelineShaderStageCreateInfo pShaderStages[] =
+	{
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			DE_NULL,												// const void*							pNext;
+			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+			VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
+			vertexModule,											// VkShaderModule						module;
+			"main",													// const char*							pName;
+			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+		},
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+			DE_NULL,												// const void*							pNext;
+			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+			VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
+			fragmentModule,											// VkShaderModule						module;
+			"main",													// const char*							pName;
+			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+		}
+	};
+
+	const VkGraphicsPipelineCreateInfo	graphicsPipelineInfo =
+	{
+		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
+		DE_NULL,											// const void*										pNext;
+		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
+		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
+		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
+		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
+		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
+		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
+		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
+		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
+		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
+		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
+		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
+		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
+		pipelineLayout,										// VkPipelineLayout									layout;
+		renderPass,											// VkRenderPass										renderPass;
+		subpassNdx,											// deUint32											subpass;
+		DE_NULL,											// VkPipeline										basePipelineHandle;
+		-1,													// deInt32											basePipelineIndex;
+	};
+
+	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
+}
+
+std::vector<PositionColor> genShapes (const VkFormat colorFormat)
+{
+	std::vector<PositionColor> vertices;
+
+	if (colorFormat == VK_FORMAT_R8G8B8A8_UNORM)
+	{
+		vertices.push_back(PositionColor(Vec4( 0.0f,  -0.75f, 0.0f, 1.0f), Vec4(0.5f, 0.5f, 0.5f, 1.0f)));
+		vertices.push_back(PositionColor(Vec4(-0.75f,  0.75f, 0.0f, 1.0f), Vec4(1.0f, 0.5f, 0.5f, 1.0f)));
+		vertices.push_back(PositionColor(Vec4( 0.75f,  0.65f, 0.0f, 1.0f), Vec4(0.0f, 0.5f, 1.0f, 1.0f)));
+	}
+	else
+	{
+		vertices.push_back(PositionColor(Vec4( 0.0f,  -0.75f, 0.0f, 1.0f), UVec4(0xabcdu, 0u, 0u, 0u)));
+		vertices.push_back(PositionColor(Vec4(-0.75f,  0.75f, 0.0f, 1.0f), UVec4(0xbcdeu, 0u, 0u, 0u)));
+		vertices.push_back(PositionColor(Vec4( 0.75f,  0.65f, 0.0f, 1.0f), UVec4(0xcdefu, 0u, 0u, 0u)));
+	}
+
+	return vertices;
+}
+
+//! Map color image format to a convenient format used in vertex attributes
+VkFormat getVertexInputColorFormat (const VkFormat colorImageFormat)
+{
+	switch (tcu::getTextureChannelClass(mapVkFormat(colorImageFormat).type))
+	{
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+			return VK_FORMAT_R32G32B32A32_SFLOAT;
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return VK_FORMAT_R32G32B32A32_SINT;
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return VK_FORMAT_R32G32B32A32_UINT;
+
+		default:
+			DE_ASSERT(0);
+			return VK_FORMAT_UNDEFINED;
+	}
+}
+
+enum SampleSource
+{
+	SAMPLE_SOURCE_IMAGE,			//!< texel fetch from an image
+	SAMPLE_SOURCE_SUBPASS_INPUT,	//!< texel fetch from an input attachment
+};
+
+//! The parameters that define a test case
+struct TestParams
+{
+	UVec2					renderSize;
+	deUint32				numLayers;			//!< 1 or N for layered image
+	SampleSource			sampleSource;		//!< source of texel fetch
+	VkSampleCountFlagBits	numColorSamples;
+	VkFormat				colorFormat;		//!< Color attachment format
+
+	TestParams (void)
+		: numLayers			()
+		, numColorSamples	()
+		, colorFormat		()
+	{
+	}
+};
+
+void checkRequirements (Context& context, TestParams params)
+{
+	context.requireDeviceFunctionality("VK_AMD_shader_fragment_mask");
+
+	// In the subpass input case we have to store fetch results into a buffer for subsequent verification in a compute shader.
+	const bool requireFragmentStores = (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT);
+
+	const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
+
+	if ((limits.framebufferColorSampleCounts & params.numColorSamples) == 0u)
+		TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
+
+	if ((isIntFormat(params.colorFormat) || isUintFormat(params.colorFormat)))
+	{
+		if ((limits.sampledImageIntegerSampleCounts & params.numColorSamples) == 0u)
+			TCU_THROW(NotSupportedError, "sampledImageIntegerSampleCounts: sample count not supported");
+	}
+	else
+	{
+		if ((limits.sampledImageColorSampleCounts & params.numColorSamples) == 0u)
+			TCU_THROW(NotSupportedError, "sampledImageColorSampleCounts: sample count not supported");
+	}
+
+	if (requireFragmentStores)
+	{
+		if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
+			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics: feature not supported");
+	}
+}
+
+//! Common data used by the test
+struct WorkingData
+{
+	deUint32						numVertices;				//!< Number of vertices defined in the vertex buffer
+	Move<VkBuffer>					vertexBuffer;
+	MovePtr<Allocation>				vertexBufferAlloc;
+	Move<VkImage>					colorImage;					//!< Color image
+	MovePtr<Allocation>				colorImageAlloc;
+	Move<VkImageView>				colorImageView;				//!< Color image view spanning all layers
+	Move<VkBuffer>					colorBuffer;				//!< Buffer used to copy image data
+	MovePtr<Allocation>				colorBufferAlloc;
+	VkDeviceSize					colorBufferSize;
+	Move<VkSampler>					defaultSampler;				//!< Dummy sampler, we are using texel fetches
+
+	WorkingData (void)
+		: numVertices		()
+		, colorBufferSize	()
+	{
+	}
+};
+
+void initPrograms (SourceCollections& programCollection, const TestParams params)
+{
+	std::string	colorType;					//!< color pixel type used by image functions
+	std::string	colorBufferType;			//!< packed pixel type as stored in a ssbo
+	std::string colorBufferPack;			//!< a cast or a function call when writing back color format to the ssbo
+	std::string	colorFragInQualifier;		//!< fragment shader color input qualifier
+	std::string samplerPrefix;				//!< u, i, or empty
+
+	switch (params.colorFormat)
+	{
+		case VK_FORMAT_R8G8B8A8_UNORM:
+			colorType				= "vec4";
+			colorBufferType			= "uint";
+			colorBufferPack			= "packUnorm4x8";
+			break;
+
+		case VK_FORMAT_R32_UINT:
+			colorType				= "uint";
+			colorBufferType			= "uint";
+			colorBufferPack			= colorBufferType;
+			colorFragInQualifier	= "flat";
+			samplerPrefix			= "u";
+			break;
+
+		case VK_FORMAT_R32_SINT:
+			colorType				= "int";
+			colorBufferType			= "int";
+			colorBufferPack			= colorBufferType;
+			colorFragInQualifier	= "flat";
+			samplerPrefix			= "i";
+			break;
+
+		default:
+			DE_FATAL("initPrograms not handled for this color format");
+			break;
+	}
+
+	// Vertex shader - position and color
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "layout(location = 0) in  vec4 in_position;\n"
+			<< "layout(location = 1) in  " << colorType << " in_color;\n"
+			<< "layout(location = 0) out " << colorType << " o_color;\n"
+			<< "\n"
+			<< "out gl_PerVertex {\n"
+			<< "    vec4 gl_Position;\n"
+			<< "};\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			// Introduce a variance in geometry per instance index which maps to the image layer
+			<< "    float a   = 0.25 * float(gl_InstanceIndex);\n"
+			<< "    mat3 rm   = mat3( cos(a), sin(a), 0.0,\n"
+			<< "                     -sin(a), cos(a), 0.0,\n"
+			<< "                         0.0,    0.0, 1.0);\n"
+			<< "    vec2 rpos = (rm * vec3(in_position.xy, 1.0)).xy;\n"
+			<< "\n"
+			<< "    gl_Position = vec4(rpos, in_position.zw);\n"
+			<< "    o_color     = in_color;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+	}
+
+	// Vertex shader - no vertex data, fill viewport with one primitive
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "out gl_PerVertex {\n"
+			<< "    vec4 gl_Position;\n"
+			<< "};\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			// Specify an oversized triangle covering the whole viewport.
+			<< "    switch (gl_VertexIndex)\n"
+			<< "    {\n"
+			<< "        case 0:\n"
+			<< "            gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "        case 1:\n"
+			<< "            gl_Position = vec4(-1.0,  3.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "        case 2:\n"
+			<< "            gl_Position = vec4( 3.0, -1.0, 0.0, 1.0);\n"
+			<< "            break;\n"
+			<< "    }\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("vert_full") << glu::VertexSource(src.str());
+	}
+
+	// Fragment shader - output color from VS
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "\n"
+			<< "layout(location = 0) in " << colorFragInQualifier << " " << colorType << " in_color;\n"
+			<< "layout(location = 0) out " << colorType << " o_color;\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    o_color = in_color;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+	}
+
+	// Fragment shader - FMASK fetch from an input attachment
+	if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
+	{
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< "#extension GL_AMD_shader_fragment_mask : enable\n"
+			<< "\n"
+			<< "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n"
+			<< "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n"
+			<< "    " << colorBufferType << " color[];\n"
+			<< "} sb_out;\n"
+			<< "layout(input_attachment_index = " << params.numLayers << ", set = 0, binding = 2) uniform " << samplerPrefix << "subpassInputMS" << " input_attach;\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    ivec2 p            = ivec2(gl_FragCoord.xy);\n"
+			<< "    int   width        = " << params.renderSize.x() << ";\n"
+			<< "    int   numSamples   = " << static_cast<deUint32>(params.numColorSamples) << ";\n"
+			<< "    int   colorOutNdx  = numSamples * (p.x + width * p.y);\n"
+			<< "\n"
+			<< "    uint mask = fragmentMaskFetchAMD(input_attach);\n"
+			<< "    for (int sampleNdx = 0; sampleNdx < numSamples; ++sampleNdx)\n"
+			<< "    {\n"
+			<< "        int fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n"
+			<< "        " << samplerPrefix << "vec4 color = fragmentFetchAMD(input_attach, fragNdx);\n"
+			<< "        sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n"
+			<< "    }\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("frag_fmask_fetch") << glu::FragmentSource(src.str());
+	}
+
+	// Generate compute shaders
+	const struct ComputeShaderParams
+	{
+		const char*		name;
+		bool			isFmaskFetch;
+		bool			enabled;
+	} computeShaders[] =
+	{
+		// name					// FMASK?	// enabled?
+		{ "comp_fetch",			false,		true,													},
+		{ "comp_fmask_fetch",	true,		(params.sampleSource != SAMPLE_SOURCE_SUBPASS_INPUT)	},
+	};
+
+	for (const ComputeShaderParams* pShaderParams = computeShaders; pShaderParams != DE_ARRAY_END(computeShaders); ++pShaderParams)
+	if (pShaderParams->enabled)
+	{
+		const std::string samplingPos = (params.numLayers == 1 ? "ivec2(gl_WorkGroupID.xy)"
+															   : "ivec3(gl_WorkGroupID)");
+		std::ostringstream src;
+		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+			<< (pShaderParams->isFmaskFetch ? "#extension GL_AMD_shader_fragment_mask : enable\n" : "")
+			<< "#define NUM_SAMPLES " << static_cast<deUint32>(params.numColorSamples) << "\n"
+			<< "\n"
+			<< "layout(local_size_x = NUM_SAMPLES) in;\n"	// one work group per pixel, each sample gets a local invocation
+			<< "\n"
+			<< "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n"
+			<< "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n"
+			<< "    " << colorBufferType << " color[];\n"
+			<< "} sb_out;\n"
+			<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "    int sampleNdx   = int(gl_LocalInvocationID.x);\n"
+			<< "    int colorOutNdx = NUM_SAMPLES * int(gl_WorkGroupID.x +\n"
+			<< "                                        gl_WorkGroupID.y * gl_NumWorkGroups.x +\n"
+			<< "                                        gl_WorkGroupID.z * gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n"
+			<< "\n";
+		if (pShaderParams->isFmaskFetch)
+		{
+			src << "    uint  mask    = fragmentMaskFetchAMD(u_image, " << samplingPos << ");\n"
+				<< "    int   fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n"
+				<< "    " << samplerPrefix << "vec4 color = fragmentFetchAMD(u_image, " << samplingPos << ", fragNdx);\n"
+				<< "    sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n";
+		}
+		else
+		{
+			src << "    " << samplerPrefix << "vec4 color = texelFetch(u_image, " << samplingPos << ", sampleNdx);\n"
+				<< "    sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n";
+		}
+		src << "}\n";
+
+		programCollection.glslSources.add(pShaderParams->name) << glu::ComputeSource(src.str());
+	}
+}
+
+std::vector<VkClearValue> genClearValues (const VkFormat format, const deUint32 count)
+{
+	std::vector<VkClearValue>	clearValues;
+	de::Random					rng (332);
+
+	switch (format)
+	{
+		case VK_FORMAT_R8G8B8A8_UNORM:
+			for (deUint32 i = 0u; i < count; ++i)
+				clearValues.push_back(makeClearValueColorF32(rng.getFloat(), rng.getFloat(), rng.getFloat(), 1.0f));
+			break;
+
+		case VK_FORMAT_R32_UINT:
+		case VK_FORMAT_R32_SINT:
+			for (deUint32 i = 0u; i < count; ++i)
+				clearValues.push_back(makeClearValueColorU32(rng.getUint32(), 0u, 0u, 0u));
+			break;
+
+		default:
+			DE_FATAL("Clear color not defined for this format");
+			break;
+	}
+
+	return clearValues;
+}
+
+//! For subpass load case draw and fetch must happen within the same render pass.
+void drawAndSampleInputAttachment (Context& context, const TestParams& params, WorkingData& wd)
+{
+	DE_ASSERT(params.numLayers == 1u);	// subpass load with single-layer image
+
+	const DeviceInterface&	vk		= context.getDeviceInterface();
+	const VkDevice			device	= context.getDevice();
+
+	Move<VkRenderPass>		renderPass;
+	Move<VkFramebuffer>		framebuffer;
+
+	// Create descriptor set
+	const Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
+		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	VK_SHADER_STAGE_FRAGMENT_BIT, &wd.defaultSampler.get())
+		.addSingleBinding		(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			VK_SHADER_STAGE_FRAGMENT_BIT)
+		.addSingleBinding		(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,		VK_SHADER_STAGE_FRAGMENT_BIT)
+		.build(vk, device));
+
+	const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
+		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
+		.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
+		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
+
+	const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
+
+	{
+		const VkDescriptorImageInfo		colorImageInfo	= makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+		const VkDescriptorBufferInfo	bufferInfo		= makeDescriptorBufferInfo(*wd.colorBuffer, 0u, wd.colorBufferSize);
+
+		DescriptorSetUpdateBuilder	builder;
+
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo);
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		 &bufferInfo);
+
+		if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
+			builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &colorImageInfo);
+
+		builder.update(vk, device);
+	}
+
+	// Create a render pass and a framebuffer
+	{
+		std::vector<VkSubpassDescription>		subpasses;
+		std::vector<VkSubpassDependency>		subpassDependencies;
+		std::vector<VkImageView>				attachments;
+		std::vector<VkAttachmentDescription>	attachmentDescriptions;
+		std::vector<VkAttachmentReference>		attachmentReferences;
+
+		// Reserve capacity to avoid invalidating pointers to elements
+		attachmentReferences.reserve(2);	// color image + input attachment
+
+		// Create a MS draw subpass
+		{
+			attachments.push_back(*wd.colorImageView);
+
+			attachmentDescriptions.push_back(makeAttachmentDescription(
+				(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags		flags;
+				params.colorFormat,												// VkFormat							format;
+				params.numColorSamples,											// VkSampleCountFlagBits			samples;
+				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp				loadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp				storeOp;
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,								// VkAttachmentLoadOp				stencilLoadOp;
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,								// VkAttachmentStoreOp				stencilStoreOp;
+				VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout					initialLayout;
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL						// VkImageLayout					finalLayout;
+			));
+
+			attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()),	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
+			const VkAttachmentReference* colorRef = &attachmentReferences.back();
+
+			const VkSubpassDescription subpassDescription =
+			{
+				(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags       flags;
+				VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint             pipelineBindPoint;
+				0u,													// uint32_t                        inputAttachmentCount;
+				DE_NULL,											// const VkAttachmentReference*    pInputAttachments;
+				1u,													// uint32_t                        colorAttachmentCount;
+				colorRef,											// const VkAttachmentReference*    pColorAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pResolveAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pDepthStencilAttachment;
+				0u,													// uint32_t                        preserveAttachmentCount;
+				DE_NULL,											// const uint32_t*                 pPreserveAttachments;
+			};
+
+			subpasses.push_back(subpassDescription);
+		}
+
+		// Create a sampling subpass
+		{
+			attachmentReferences.push_back(makeAttachmentReference(0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
+			const VkAttachmentReference* inputRef = &attachmentReferences.back();
+
+			// No color attachment, side effects only
+			VkSubpassDescription subpassDescription =
+			{
+				(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags       flags;
+				VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint             pipelineBindPoint;
+				1u,													// uint32_t                        inputAttachmentCount;
+				inputRef,											// const VkAttachmentReference*    pInputAttachments;
+				0u,													// uint32_t                        colorAttachmentCount;
+				DE_NULL,											// const VkAttachmentReference*    pColorAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pResolveAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pDepthStencilAttachment;
+				0u,													// uint32_t                        preserveAttachmentCount;
+				DE_NULL,											// const uint32_t*                 pPreserveAttachments;
+			};
+
+			subpasses.push_back(subpassDescription);
+		}
+
+		// Serialize the subpasses
+		{
+			const VkAccessFlags	dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
+											  | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
+											  | VK_ACCESS_SHADER_WRITE_BIT;
+			const VkSubpassDependency	dependency	=
+			{
+				0u,																							// uint32_t                srcSubpass;
+				1u,																							// uint32_t                dstSubpass;
+				VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags    srcStageMask;
+				VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,														// VkPipelineStageFlags    dstStageMask;
+				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,														// VkAccessFlags           srcAccessMask;
+				dstAccessMask,																				// VkAccessFlags           dstAccessMask;
+				VK_DEPENDENCY_BY_REGION_BIT,																// VkDependencyFlags       dependencyFlags;
+			};
+			subpassDependencies.push_back(dependency);
+		}
+
+		VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
+			DE_NULL,												// const void*						pNext;
+			(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
+			static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
+			dataOrNullPtr(attachmentDescriptions),					// const VkAttachmentDescription*	pAttachments;
+			static_cast<deUint32>(subpasses.size()),				// deUint32							subpassCount;
+			dataOrNullPtr(subpasses),								// const VkSubpassDescription*		pSubpasses;
+			static_cast<deUint32>(subpassDependencies.size()),		// deUint32							dependencyCount;
+			dataOrNullPtr(subpassDependencies),						// const VkSubpassDependency*		pDependencies;
+		};
+
+		renderPass  = createRenderPass(vk, device, &renderPassInfo);
+		framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y());
+	}
+
+	const Unique<VkShaderModule>	vertexModuleDraw	(createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
+	const Unique<VkShaderModule>	fragmentModuleDraw	(createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
+
+	// Create pipelines for MS draw
+	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
+	const Unique<VkPipeline>		pipelineDraw		(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleDraw, *fragmentModuleDraw,
+																			  true/*use vertex attribs*/, getVertexInputColorFormat(params.colorFormat), true/*use color attach*/, 0u/*subpass*/,
+																			  params.renderSize, params.numColorSamples));
+
+	// Sampling pass is single-sampled, output to storage buffer
+	const Unique<VkShaderModule>	vertexModuleSample		(createShaderModule(vk, device, context.getBinaryCollection().get("vert_full"), 0u));
+	const Unique<VkShaderModule>	fragmentModuleSample	(createShaderModule(vk, device, context.getBinaryCollection().get("frag_fmask_fetch"), 0u));
+
+	// Sampling pipeline
+	const Unique<VkPipeline>		pipelineSample		(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleSample, *fragmentModuleSample,
+																			  false/*use vertex attribs*/, VK_FORMAT_UNDEFINED, false/*no color output*/, 1u/*subpass*/,
+																			  params.renderSize, VK_SAMPLE_COUNT_1_BIT));
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	{
+		// Generate clear values
+		std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers);
+
+		const VkRect2D renderArea =
+		{
+			{ 0u, 0u },
+			{ params.renderSize.x(), params.renderSize.y() }
+		};
+
+		const VkRenderPassBeginInfo renderPassBeginInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			// VkStructureType         sType;
+			DE_NULL,											// const void*             pNext;
+			*renderPass,										// VkRenderPass            renderPass;
+			*framebuffer,										// VkFramebuffer           framebuffer;
+			renderArea,											// VkRect2D                renderArea;
+			static_cast<deUint32>(clearValues.size()),			// uint32_t                clearValueCount;
+			dataOrNullPtr(clearValues),							// const VkClearValue*     pClearValues;
+		};
+		vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+	}
+
+	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
+
+	{
+		const VkDeviceSize vertexBufferOffset = 0ull;
+		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset);
+	}
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineDraw);
+	vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, 0u);
+
+	vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSample);
+	vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);	// fill the framebuffer, geometry defined in the VS
+
+	vk.cmdEndRenderPass(*cmdBuffer);
+
+	// Buffer write barrier
+	{
+		const VkBufferMemoryBarrier barrier =
+		{
+			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
+			DE_NULL,										// const void*        pNext;
+			VK_ACCESS_SHADER_WRITE_BIT,						// VkAccessFlags      srcAccessMask;
+			VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
+			*wd.colorBuffer,								// VkBuffer           buffer;
+			0ull,											// VkDeviceSize       offset;
+			VK_WHOLE_SIZE,									// VkDeviceSize       size;
+		};
+
+		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
+	}
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+
+	invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+}
+
+//! Only draw a multisampled image
+void draw (Context& context, const TestParams& params, WorkingData& wd)
+{
+	const DeviceInterface&	vk		= context.getDeviceInterface();
+	const VkDevice			device	= context.getDevice();
+
+	std::vector<ImageViewSp>	imageViews;
+	Move<VkRenderPass>			renderPass;
+	Move<VkFramebuffer>			framebuffer;
+
+	// Create color attachments
+	for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
+	{
+		imageViews.push_back(ImageViewSp(new Unique<VkImageView>(
+			makeImageView(vk, device, *wd.colorImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, layerNdx, 1u)))));
+	}
+
+	// Create a render pass and a framebuffer
+	{
+		std::vector<VkSubpassDescription>		subpasses;
+		std::vector<VkImageView>				attachments;
+		std::vector<VkAttachmentDescription>	attachmentDescriptions;
+		std::vector<VkAttachmentReference>		attachmentReferences;
+
+		// Reserve capacity to avoid invalidating pointers to elements
+		attachmentReferences.reserve(params.numLayers);
+
+		// Create MS draw subpasses
+		for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
+		{
+			attachments.push_back(**imageViews[layerNdx]);
+
+			attachmentDescriptions.push_back(makeAttachmentDescription(
+				(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags		flags;
+				params.colorFormat,												// VkFormat							format;
+				params.numColorSamples,											// VkSampleCountFlagBits			samples;
+				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp				loadOp;
+				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp				storeOp;
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,								// VkAttachmentLoadOp				stencilLoadOp;
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,								// VkAttachmentStoreOp				stencilStoreOp;
+				VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout					initialLayout;
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL						// VkImageLayout					finalLayout;
+			));
+
+			attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()),	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
+			const VkAttachmentReference* colorRef = &attachmentReferences.back();
+
+			const VkSubpassDescription subpassDescription =
+			{
+				(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags       flags;
+				VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint             pipelineBindPoint;
+				0u,													// uint32_t                        inputAttachmentCount;
+				DE_NULL,											// const VkAttachmentReference*    pInputAttachments;
+				1u,													// uint32_t                        colorAttachmentCount;
+				colorRef,											// const VkAttachmentReference*    pColorAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pResolveAttachments;
+				DE_NULL,											// const VkAttachmentReference*    pDepthStencilAttachment;
+				0u,													// uint32_t                        preserveAttachmentCount;
+				DE_NULL,											// const uint32_t*                 pPreserveAttachments;
+			};
+
+			subpasses.push_back(subpassDescription);
+		}
+
+		// All MS image drawing subpasses are independent
+		VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
+			DE_NULL,												// const void*						pNext;
+			(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
+			static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
+			dataOrNullPtr(attachmentDescriptions),					// const VkAttachmentDescription*	pAttachments;
+			static_cast<deUint32>(subpasses.size()),				// deUint32							subpassCount;
+			dataOrNullPtr(subpasses),								// const VkSubpassDescription*		pSubpasses;
+			0u,														// deUint32							dependencyCount;
+			DE_NULL,												// const VkSubpassDependency*		pDependencies;
+		};
+
+		renderPass  = createRenderPass(vk, device, &renderPassInfo);
+		framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y());
+	}
+
+	std::vector<PipelineSp>			pipelines;
+	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device));
+	const Unique<VkShaderModule>	vertexModuleDraw	(createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
+	const Unique<VkShaderModule>	fragmentModuleDraw	(createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
+
+	// Create pipelines for MS draw
+	for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
+	{
+		pipelines.push_back(PipelineSp(new Unique<VkPipeline>(
+			makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleDraw, *fragmentModuleDraw,
+								 true /*use vertex attribs*/, getVertexInputColorFormat(params.colorFormat), true/*use color attachment*/, layerNdx /*subpass*/,
+								 params.renderSize, params.numColorSamples))));
+	}
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	{
+		// Generate clear values
+		std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers);
+
+		const VkRect2D renderArea =
+		{
+			{ 0u, 0u },
+			{ params.renderSize.x(), params.renderSize.y() }
+		};
+
+		const VkRenderPassBeginInfo renderPassBeginInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			// VkStructureType         sType;
+			DE_NULL,											// const void*             pNext;
+			*renderPass,										// VkRenderPass            renderPass;
+			*framebuffer,										// VkFramebuffer           framebuffer;
+			renderArea,											// VkRect2D                renderArea;
+			static_cast<deUint32>(clearValues.size()),			// uint32_t                clearValueCount;
+			dataOrNullPtr(clearValues),							// const VkClearValue*     pClearValues;
+		};
+		vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+	}
+
+	{
+		const VkDeviceSize vertexBufferOffset = 0ull;
+		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset);
+	}
+
+	for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
+	{
+		if (layerNdx != 0u)
+			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
+
+		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[layerNdx]);
+		vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, layerNdx);	// pass instance index to slightly change geometry per layer
+	}
+
+	vk.cmdEndRenderPass(*cmdBuffer);
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+}
+
+//! Sample from an image in a compute shader, storing the result in a color buffer
+void dispatchSampleImage (Context& context, const TestParams& params, WorkingData& wd, const std::string& shaderName)
+{
+	const DeviceInterface&	vk		= context.getDeviceInterface();
+	const VkDevice			device	= context.getDevice();
+
+	// Create descriptor set
+
+	const Unique<VkDescriptorSetLayout> descriptorSetLayout(
+		DescriptorSetLayoutBuilder()
+		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	VK_SHADER_STAGE_COMPUTE_BIT, &wd.defaultSampler.get())
+		.addSingleBinding		(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			VK_SHADER_STAGE_COMPUTE_BIT)
+		.build(vk, device));
+
+	const Unique<VkDescriptorPool> descriptorPool(
+		DescriptorPoolBuilder()
+		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
+		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
+
+	const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
+
+	{
+		const VkDescriptorImageInfo		colorImageInfo		= makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+		const VkDescriptorBufferInfo	resultBufferInfo	= makeDescriptorBufferInfo(*wd.colorBuffer, 0ull, wd.colorBufferSize);
+
+		DescriptorSetUpdateBuilder	builder;
+
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo);
+		builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		  &resultBufferInfo);
+
+		builder.update(vk, device);
+	}
+
+	// Pipeline
+
+	const Unique<VkShaderModule>	shaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get(shaderName), 0u));
+	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device, *descriptorSetLayout));
+	const Unique<VkPipeline>		pipeline		(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule, DE_NULL));
+
+	const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
+	const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));
+
+	beginCommandBuffer(vk, *cmdBuffer);
+
+	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
+
+	vk.cmdDispatch(*cmdBuffer, params.renderSize.x(), params.renderSize.y(), params.numLayers);
+
+	{
+		const VkBufferMemoryBarrier barrier =
+		{
+			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
+			DE_NULL,										// const void*        pNext;
+			VK_ACCESS_SHADER_WRITE_BIT,						// VkAccessFlags      srcAccessMask;
+			VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
+			*wd.colorBuffer,								// VkBuffer           buffer;
+			0ull,											// VkDeviceSize       offset;
+			VK_WHOLE_SIZE,									// VkDeviceSize       size;
+		};
+
+		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0,
+			(const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
+	}
+
+	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+	submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
+
+	invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+}
+
+//! Get a single-sampled image access from a multisampled color buffer with samples packed per pixel
+tcu::ConstPixelBufferAccess getSingleSampledAccess (const void* const imageData, const TestParams& params, const deUint32 sampleNdx, const deUint32 layerNdx)
+{
+	const deUint32		numSamples	= static_cast<deUint32>(params.numColorSamples);
+	const deUint32		pixelSize	= tcu::getPixelSize(mapVkFormat(params.colorFormat));
+	const deUint32		rowSize		= pixelSize * params.renderSize.x();
+	const deUint32		layerSize	= rowSize * params.renderSize.y();
+	const deUint8*		src			= static_cast<const deUint8*>(imageData)
+									+ (layerNdx * numSamples * layerSize)
+									+ (sampleNdx * pixelSize);
+	const tcu::IVec3	size		(params.renderSize.x(), params.renderSize.y(), 1);
+	const tcu::IVec3	pitch		(numSamples * pixelSize,
+									 numSamples * rowSize,
+									 numSamples * layerSize);
+	return tcu::ConstPixelBufferAccess(mapVkFormat(params.colorFormat), size, pitch, src);
+}
+
+tcu::TestStatus test (Context& context, const TestParams params)
+{
+	WorkingData				wd;
+	const DeviceInterface&	vk		  = context.getDeviceInterface();
+	const VkDevice			device	  = context.getDevice();
+	MovePtr<Allocator>		allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())));
+
+	// Initialize resources
+	{
+		const VkImageUsageFlags	msImageUsage	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+												| VK_IMAGE_USAGE_SAMPLED_BIT
+												| (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
+		wd.colorImage		= makeImage(vk, device, params.colorFormat, params.renderSize, params.numLayers, params.numColorSamples, msImageUsage);
+		wd.colorImageAlloc	= bindImage(vk, device, *allocator, *wd.colorImage, MemoryRequirement::Any);
+		wd.colorImageView	= makeImageView(vk, device, *wd.colorImage, (params.numLayers == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY), params.colorFormat,
+											makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.numLayers));
+
+		wd.defaultSampler	= makeSampler(vk, device);
+
+		// Color buffer is meant to hold data for all layers and all samples of the image.
+		// Data is tightly packed layer by layer, for each pixel all samples are laid out together starting with sample 0.
+		// E.g.: pixel(0,0)sample(0)sample(1), pixel(1,0)sample(0)sample(1), ...
+		wd.colorBufferSize	= static_cast<VkDeviceSize>(tcu::getPixelSize(mapVkFormat(params.colorFormat))
+														* params.renderSize.x() * params.renderSize.y() * params.numLayers * static_cast<deUint32>(params.numColorSamples));
+		wd.colorBuffer		= makeBuffer(vk, device, wd.colorBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+		wd.colorBufferAlloc	= bindBuffer(vk, device, *allocator, *wd.colorBuffer, MemoryRequirement::HostVisible);
+
+		deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize));
+		flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+
+		const std::vector<PositionColor>	vertices			= genShapes(params.colorFormat);
+		const VkDeviceSize					vertexBufferSize	= static_cast<VkDeviceSize>(sizeof(vertices[0]) * vertices.size());
+
+		wd.numVertices			= static_cast<deUint32>(vertices.size());
+		wd.vertexBuffer			= makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
+		wd.vertexBufferAlloc	= bindBuffer(vk, device, *allocator, *wd.vertexBuffer, MemoryRequirement::HostVisible);
+
+		deMemcpy(wd.vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize));
+		flushMappedMemoryRange(vk, device, wd.vertexBufferAlloc->getMemory(), wd.vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+	}
+
+	if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
+	{
+		// Create a multisample image and sample from it
+		drawAndSampleInputAttachment (context, params, wd);
+	}
+	else
+	{
+		// Draw the image, then sample from it in a CS
+		draw				(context, params, wd);
+		dispatchSampleImage (context, params, wd, "comp_fmask_fetch");
+	}
+
+	// Copy the result
+	std::vector<deUint8> fmaskFetchColorBuffer (static_cast<deUint32>(wd.colorBufferSize));
+	deMemcpy(&fmaskFetchColorBuffer[0], wd.colorBufferAlloc->getHostPtr(), static_cast<std::size_t>(wd.colorBufferSize));
+
+	// Clear the color buffer, just to be sure we're getting the new data
+	deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize));
+	flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
+
+	// Sample image using the standard texel fetch
+	dispatchSampleImage (context, params, wd, "comp_fetch");
+
+	// Verify the images
+	{
+		const void* const fmaskResult	 = dataOrNullPtr(fmaskFetchColorBuffer);
+		const void* const expectedResult = wd.colorBufferAlloc->getHostPtr();
+
+		DE_ASSERT(!isFloatFormat(params.colorFormat));	// we're using int compare
+
+		// Mismatch, do image compare to pinpoint the failure
+		for (deUint32 layerNdx  = 0u; layerNdx  < params.numLayers;								 ++layerNdx)
+		for (deUint32 sampleNdx = 0u; sampleNdx < static_cast<deUint32>(params.numColorSamples); ++sampleNdx)
+		{
+			const std::string					imageName	= "layer_" + de::toString(layerNdx) + "_sample_" + de::toString(sampleNdx);
+			const std::string					imageDesc	= "Layer " + de::toString(layerNdx) + " Sample " + de::toString(sampleNdx);
+			const tcu::ConstPixelBufferAccess	expected	= getSingleSampledAccess(expectedResult, params, sampleNdx, layerNdx);
+			const tcu::ConstPixelBufferAccess	actual		= getSingleSampledAccess(fmaskResult,	 params, sampleNdx, layerNdx);
+			const UVec4							threshold	(0);	// should match exactly
+
+			const bool ok = tcu::intThresholdCompare(context.getTestContext().getLog(), imageName.c_str(), imageDesc.c_str(),
+													 expected, actual, threshold, tcu::COMPARE_LOG_RESULT);
+
+			if (!ok)
+				return tcu::TestStatus::fail("Some texels were incorrect");
+		}
+	}
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+std::string getFormatShortString (const VkFormat format)
+{
+	std::string s(de::toLower(getFormatName(format)));
+	return s.substr(10);
+}
+
+void createShaderFragmentMaskTestsInGroup (tcu::TestCaseGroup* rootGroup)
+{
+	// Per spec, the following formats must support color attachment and sampled image
+	const VkFormat colorFormats[] =
+	{
+		VK_FORMAT_R8G8B8A8_UNORM,
+		VK_FORMAT_R32_UINT,
+		VK_FORMAT_R32_SINT,
+	};
+
+	const VkSampleCountFlagBits	sampleCounts[] =
+	{
+		VK_SAMPLE_COUNT_2_BIT,
+		VK_SAMPLE_COUNT_4_BIT,
+		VK_SAMPLE_COUNT_8_BIT,
+		VK_SAMPLE_COUNT_16_BIT,
+	};
+
+	const struct SourceCase
+	{
+		const char*			name;
+		deUint32			numLayers;
+		SampleSource		sampleSource;
+	} sourceCases[] =
+	{
+		{ "image_2d",		1u,	SAMPLE_SOURCE_IMAGE			},
+		{ "image_2d_array",	3u,	SAMPLE_SOURCE_IMAGE			},
+		{ "subpass_input",	1u,	SAMPLE_SOURCE_SUBPASS_INPUT	},
+	};
+
+	// Test 1: Compare fragments fetched via FMASK and an ordinary texel fetch
+	{
+		for (const VkSampleCountFlagBits* pSampleCount = sampleCounts; pSampleCount != DE_ARRAY_END(sampleCounts); ++pSampleCount)
+		{
+			MovePtr<tcu::TestCaseGroup> sampleCountGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), ("samples_" + de::toString(*pSampleCount)).c_str(), ""));
+			for (const SourceCase* pSourceCase = sourceCases; pSourceCase != DE_ARRAY_END(sourceCases); ++pSourceCase)
+			{
+				MovePtr<tcu::TestCaseGroup> sourceGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), pSourceCase->name, ""));
+				for (const VkFormat* pColorFormat = colorFormats; pColorFormat != DE_ARRAY_END(colorFormats); ++pColorFormat)
+				{
+					TestParams params;
+					params.renderSize		= UVec2(32, 32);
+					params.colorFormat		= *pColorFormat;
+					params.numColorSamples	= *pSampleCount;
+					params.numLayers		= pSourceCase->numLayers;
+					params.sampleSource		= pSourceCase->sampleSource;
+
+					addFunctionCaseWithPrograms(sourceGroup.get(), getFormatShortString(*pColorFormat), "", checkRequirements, initPrograms, test, params);
+				}
+				sampleCountGroup->addChild(sourceGroup.release());
+			}
+			rootGroup->addChild(sampleCountGroup.release());
+		}
+	}
+}
+
+} // anonymous ns
+
+tcu::TestCaseGroup* createMultisampleShaderFragmentMaskTests (tcu::TestContext& testCtx)
+{
+	return createTestGroup(testCtx, "shader_fragment_mask", "Access raw texel values in a compressed MSAA surface", createShaderFragmentMaskTestsInGroup);
+}
+
+} // pipeline
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.hpp
new file mode 100644
index 0000000..9855bcf
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleShaderFragmentMaskTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTPIPELINEMULTISAMPLESHADERFRAGMENTMASKTESTS_HPP
+#define _VKTPIPELINEMULTISAMPLESHADERFRAGMENTMASKTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Tests for VK_AMD_shader_fragment_mask
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+tcu::TestCaseGroup* createMultisampleShaderFragmentMaskTests (tcu::TestContext& testCtx);
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLESHADERFRAGMENTMASKTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp
index e184950..0682a53 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp
@@ -26,6 +26,8 @@
 #include "vktPipelineMultisampleTests.hpp"
 #include "vktPipelineMultisampleImageTests.hpp"
 #include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
+#include "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
+#include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
 #include "vktPipelineClearUtil.hpp"
 #include "vktPipelineImageUtil.hpp"
 #include "vktPipelineVertexUtil.hpp"
@@ -3886,6 +3888,12 @@
 		multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
 	}
 
+	// VK_AMD_mixed_attachment samples and VK_AMD_shader_fragment_mask
+	{
+		multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx));
+		multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx));
+	}
+
 	// Sample mask with and without vk_ext_post_depth_coverage
 	{
 		const vk::VkSampleCountFlagBits standardSamplesSet[] =
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineRenderToImageTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineRenderToImageTests.cpp
index 7d1d133..c858f98 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineRenderToImageTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineRenderToImageTests.cpp
@@ -1735,6 +1735,10 @@
 		VK_FORMAT_R32_UINT,
 		VK_FORMAT_R16G16_SINT,
 		VK_FORMAT_R32G32B32A32_SFLOAT,
+		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
+		VK_FORMAT_R5G6B5_UNORM_PACK16,
+		VK_FORMAT_A2B10G10R10_UINT_PACK32,
+		VK_FORMAT_A2B10G10R10_UNORM_PACK32
 	};
 
 	const VkFormat depthStencilFormat[] =
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.cpp
new file mode 100644
index 0000000..d720a25
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.cpp
@@ -0,0 +1,94 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Utilities for VK_EXT_sample_locations
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineSampleLocationsUtil.hpp"
+#include "deRandom.hpp"
+#include <set>
+
+namespace vkt
+{
+namespace pipeline
+{
+using namespace vk;
+using tcu::UVec2;
+using tcu::Vec2;
+
+//! Order a Vector by X, Y, Z, and W
+template<typename VectorT>
+struct LessThan
+{
+	bool operator()(const VectorT& v1, const VectorT& v2) const
+	{
+		for (int i = 0; i < VectorT::SIZE; ++i)
+		{
+			if (v1[i] == v2[i])
+				continue;
+			else
+				return v1[i] < v2[i];
+		}
+
+		return false;
+	}
+};
+
+static inline deUint32 numSamplesPerPixel (const MultisamplePixelGrid& pixelGrid)
+{
+	return static_cast<deUint32>(pixelGrid.samplesPerPixel());
+}
+
+//! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
+void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed)
+{
+	const deUint32	guardOffset			= 1u;	// don't put samples on the right or the bottom edge of the pixel
+	const deUint32	maxLocationIndex	= 1u << subPixelBits;
+	de::Random		rng					(seed);
+
+	for (deUint32 gridY = 0; gridY < grid.size().y(); ++gridY)
+	for (deUint32 gridX = 0; gridX < grid.size().x(); ++gridX)
+	{
+		std::set<UVec2, LessThan<UVec2> >	takenLocationIndices;
+		for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(grid); /* no increment */)
+		{
+			const UVec2 locationNdx (rng.getUint32() % (maxLocationIndex + 1 - guardOffset),
+									 rng.getUint32() % (maxLocationIndex + 1 - guardOffset));
+
+			if (takenLocationIndices.find(locationNdx) == takenLocationIndices.end())
+			{
+				const VkSampleLocationEXT location =
+				{
+					static_cast<float>(locationNdx.x()) / static_cast<float>(maxLocationIndex),	// float x;
+					static_cast<float>(locationNdx.y()) / static_cast<float>(maxLocationIndex),	// float y;
+				};
+
+				grid.setSample(gridX, gridY, sampleNdx, location);
+				takenLocationIndices.insert(locationNdx);
+
+				++sampleNdx;	// next sample
+			}
+		}
+	}
+}
+
+} // pipeline
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.hpp
new file mode 100644
index 0000000..46b7955
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSampleLocationsUtil.hpp
@@ -0,0 +1,106 @@
+#ifndef _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
+#define _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * Copyright (c) 2019 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 Utilities for VK_EXT_sample_locations
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkTypeUtil.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vktTestCase.hpp"
+#include "tcuVector.hpp"
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+
+//! Specify sample locations in a pixel grid
+class MultisamplePixelGrid
+{
+public:
+	MultisamplePixelGrid (const tcu::UVec2& gridSize, const vk::VkSampleCountFlagBits numSamples)
+		: m_gridSize		(gridSize)
+		, m_numSamples		(numSamples)
+		, m_sampleLocations	(gridSize.x() * gridSize.y() * numSamples)
+	{
+		DE_ASSERT(gridSize.x() > 0 && gridSize.y() > 0);
+		DE_ASSERT(numSamples   > 1);
+	}
+
+	//! If grid x,y is larger than gridSize, then each coordinate is wrapped, x' = x % size_x
+	const vk::VkSampleLocationEXT& getSample (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
+	{
+		return m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)];
+	}
+
+	void setSample (const deUint32 gridX, const deUint32 gridY, const deUint32 sampleNdx, const vk::VkSampleLocationEXT& location)
+	{
+		DE_ASSERT(gridX < m_gridSize.x());
+		DE_ASSERT(gridY < m_gridSize.y());
+
+		m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)] = location;
+	}
+
+	const tcu::UVec2&				size				(void) const	{ return m_gridSize; }
+	vk::VkSampleCountFlagBits		samplesPerPixel		(void) const	{ return m_numSamples; }
+	const vk::VkSampleLocationEXT*	sampleLocations		(void) const	{ return dataOrNullPtr(m_sampleLocations); }
+	vk::VkSampleLocationEXT*		sampleLocations		(void)			{ return dataOrNullPtr(m_sampleLocations); }
+	deUint32						sampleLocationCount	(void) const	{ return static_cast<deUint32>(m_sampleLocations.size()); }
+
+private:
+	deUint32 getSampleIndex (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
+	{
+		gridX %= m_gridSize.x();
+		gridY %= m_gridSize.y();
+		return (gridY * m_gridSize.x() + gridX) * static_cast<deUint32>(m_numSamples) + sampleNdx;
+	}
+
+	tcu::UVec2								m_gridSize;
+	vk::VkSampleCountFlagBits				m_numSamples;
+	std::vector<vk::VkSampleLocationEXT>	m_sampleLocations;
+};
+
+//! References the data inside MultisamplePixelGrid
+inline vk::VkSampleLocationsInfoEXT makeSampleLocationsInfo (const MultisamplePixelGrid& pixelGrid)
+{
+	const vk::VkSampleLocationsInfoEXT info =
+	{
+		vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,				// VkStructureType               sType;
+		DE_NULL,														// const void*                   pNext;
+		pixelGrid.samplesPerPixel(),									// VkSampleCountFlagBits         sampleLocationsPerPixel;
+		vk::makeExtent2D(pixelGrid.size().x(), pixelGrid.size().y()),	// VkExtent2D                    sampleLocationGridSize;
+		pixelGrid.sampleLocationCount(),								// uint32_t                      sampleLocationsCount;
+		pixelGrid.sampleLocations(),									// const VkSampleLocationEXT*    pSampleLocations;
+	};
+	return info;
+}
+
+//! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
+void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed = 142u);
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp
index 7a54fd6..5904ca8 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp
@@ -132,7 +132,7 @@
 																			VkImageViewType				imageViewType,
 																			VkFormat					imageFormat,
 																			VkComponentMapping			componentMapping,
-																			VkSamplerReductionModeEXT	reductionMode,
+																			VkSamplerReductionMode		reductionMode,
 																			bool						separateStencilUsage);
 
 	virtual										~SamplerMagReduceFilterTest	(void) {}
@@ -140,7 +140,7 @@
 	virtual VkComponentMapping					getComponentMapping			(void) const;
 
 private:
-	const VkSamplerReductionModeCreateInfoEXT	m_reductionCreaterInfo;
+	const VkSamplerReductionModeCreateInfo		m_reductionCreaterInfo;
 	VkComponentMapping							m_componentMapping;
 };
 
@@ -153,7 +153,7 @@
 																			 VkImageViewType			imageViewType,
 																			 VkFormat					imageFormat,
 																			 VkComponentMapping			componentMapping,
-																			 VkSamplerReductionModeEXT	reductionMode,
+																			 VkSamplerReductionMode		reductionMode,
 																			 bool						separateStencilUsage);
 
 	virtual										~SamplerMinReduceFilterTest	(void) {}
@@ -161,7 +161,7 @@
 	virtual VkComponentMapping					getComponentMapping			(void) const;
 
 private:
-	const VkSamplerReductionModeCreateInfoEXT	m_reductionCreaterInfo;
+	const VkSamplerReductionModeCreateInfo		m_reductionCreaterInfo;
 	VkComponentMapping							m_componentMapping;
 };
 
@@ -566,13 +566,13 @@
 namespace
 {
 
-VkSamplerReductionModeCreateInfoEXT getSamplerReductionCreateInfo (VkSamplerReductionModeEXT reductionMode)
+VkSamplerReductionModeCreateInfo getSamplerReductionCreateInfo (VkSamplerReductionMode reductionMode)
 {
-	const VkSamplerReductionModeCreateInfoEXT	 ret =
+	const VkSamplerReductionModeCreateInfo ret =
 	{
-		VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,	// VkStructureType				sType
+		VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,		// VkStructureType				sType
 		DE_NULL,													// const void*					pNext
-		reductionMode												// VkSamplerReductionModeEXT	reductionMode
+		reductionMode												// VkSamplerReductionMode		reductionMode
 	};
 	return ret;
 }
@@ -588,7 +588,7 @@
 														VkImageViewType				imageViewType,
 														VkFormat					imageFormat,
 														VkComponentMapping			componentMapping,
-														VkSamplerReductionModeEXT	reductionMode,
+														VkSamplerReductionMode		reductionMode,
 														bool						separateStencilUsage)
 	: SamplerMagFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
 	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
@@ -618,7 +618,7 @@
 														VkImageViewType				imageViewType,
 														VkFormat					imageFormat,
 														VkComponentMapping			componentMapping,
-														VkSamplerReductionModeEXT	reductionMode,
+														VkSamplerReductionMode		reductionMode,
 														bool						separateStencilUsage)
 	: SamplerMinFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
 	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp
index 5eadb9f..9b5f24a 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp
@@ -51,6 +51,7 @@
 #include "vktPipelineExecutablePropertiesTests.hpp"
 #include "vktPipelineVertexOnlyTests.hpp"
 #include "vktPipelineMaxVaryingsTests.hpp"
+#include "vktPipelineBlendOperationAdvancedTests.hpp"
 #include "vktTestGroupUtil.hpp"
 
 namespace vkt
@@ -93,6 +94,7 @@
 	pipelineTests->addChild(createExecutablePropertiesTests		(testCtx));
 	pipelineTests->addChild(createVertexOnlyTests				(testCtx));
 	pipelineTests->addChild(createMaxVaryingsTests				(testCtx));
+	pipelineTests->addChild(createBlendOperationAdvancedTests	(testCtx));
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTimestampTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTimestampTests.cpp
index 5555672..0cc5f76 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTimestampTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTimestampTests.cpp
@@ -46,6 +46,7 @@
 
 #include <sstream>
 #include <vector>
+#include <set>
 #include <cctype>
 #include <locale>
 #include <limits>
@@ -797,7 +798,7 @@
 	configCommandBuffer();
 	if (m_hostQueryReset)
 	{
-		vk.resetQueryPoolEXT(vkDevice, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
+		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
 	}
 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
 
@@ -820,7 +821,7 @@
 		}
 
 		// Host resets the query pool
-		vk.resetQueryPoolEXT(vkDevice, *m_queryPool, 0u, stageSize);
+		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, stageSize);
 		// Get timestamp value from query pool
 		vk::VkResult res = vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize * 2, (void*)m_timestampValuesHostQueryReset, sizeof(deUint64) * 2, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
 
@@ -1150,8 +1151,11 @@
 
 std::vector<VkTimeDomainEXT> CalibratedTimestampTestInstance::getDomainSubset (const std::vector<VkTimeDomainEXT>& available, const std::vector<VkTimeDomainEXT>& interesting) const
 {
+	const std::set<VkTimeDomainEXT> availableSet	(begin(available),		end(available));
+	const std::set<VkTimeDomainEXT> interestingSet	(begin(interesting),	end(interesting));
+
 	std::vector<VkTimeDomainEXT> subset;
-	std::set_intersection(begin(available), end(available), begin(interesting), end(interesting), std::back_inserter(subset));
+	std::set_intersection(begin(availableSet), end(availableSet), begin(interestingSet), end(interestingSet), std::back_inserter(subset));
 	return subset;
 }
 
@@ -2881,7 +2885,7 @@
 	if (m_hostQueryReset)
 	{
 		// Only reset the pool for the primary command buffer, the secondary command buffer will reset the pool by itself.
-		vk.resetQueryPoolEXT(m_context.getDevice(), *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
+		vk.resetQueryPool(m_context.getDevice(), *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
 	}
 
 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
diff --git a/external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt b/external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt
index 7efcd0e..cdfaa71 100644
--- a/external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt
@@ -42,6 +42,8 @@
 	vktProtectedMemWorkgroupStorageTests.hpp
 	vktProtectedMemTests.cpp
 	vktProtectedMemTests.hpp
+	vktProtectedMemStackTests.cpp
+	vktProtectedMemStackTests.hpp
 	)
 
 set(DEQP_VK_PROTECTED_MEMORY_LIBS
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.cpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.cpp
new file mode 100644
index 0000000..3e9b105
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.cpp
@@ -0,0 +1,400 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2018 The Khronos Group Inc.
+ * Copyright (c) 2018 Google Inc.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 Protected memory stack tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktProtectedMemStackTests.hpp"
+
+#include "vktProtectedMemContext.hpp"
+#include "vktProtectedMemUtils.hpp"
+#include "vktProtectedMemImageValidator.hpp"
+#include "vktTestCase.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuVector.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuStringTemplate.hpp"
+
+#include "gluTextureTestUtil.hpp"
+
+#include "deRandom.hpp"
+
+namespace vkt
+{
+namespace ProtectedMem
+{
+
+namespace
+{
+
+struct Params
+{
+	deUint32	stackSize;
+	deUint32	imageWidth;
+	deUint32	imageHeight;
+
+	Params (deUint32	stackSize_)
+		: stackSize	(stackSize_)
+	{
+		// Find suitable image dimensions based on stack memory size
+		imageWidth = 1;
+		imageHeight = 1;
+		bool increaseWidth = true;
+		while (imageWidth * imageHeight < stackSize)
+		{
+			if (increaseWidth)
+				imageWidth *= 2;
+			else
+				imageHeight *= 2;
+
+			increaseWidth = !increaseWidth;
+		}
+	}
+};
+
+deUint32 getSeedValue (const Params& params)
+{
+	return deInt32Hash(params.stackSize);
+}
+
+class StackTestInstance : public ProtectedTestInstance
+{
+public:
+								StackTestInstance	(Context&				ctx,
+													 const ImageValidator&	validator,
+													 const Params&			params);
+	virtual tcu::TestStatus		iterate				(void);
+
+private:
+	de::MovePtr<tcu::Texture2D>	createTestTexture2D	(void);
+	tcu::TestStatus				validateResult		(vk::VkImage			image,
+													 vk::VkImageLayout imageLayout,
+													 const tcu::Texture2D&	texture2D,
+													 const tcu::Sampler&	refSampler);
+	void						calculateRef		(tcu::Texture2D&		texture2D);
+
+	const ImageValidator&		m_validator;
+	const Params&				m_params;
+};
+
+class StackTestCase : public TestCase
+{
+public:
+								StackTestCase	(tcu::TestContext&		testCtx,
+												 const std::string&		name,
+												 const std::string&		description,
+												 const Params&			params)
+									: TestCase		(testCtx, name, description)
+									, m_validator	(vk::VK_FORMAT_R8G8B8A8_UNORM)
+									, m_params		(params)
+								{
+								}
+
+	virtual						~StackTestCase	(void) {}
+	virtual TestInstance*		createInstance	(Context& ctx) const
+								{
+									return new StackTestInstance(ctx, m_validator, m_params);
+								}
+	virtual void				initPrograms	(vk::SourceCollections& programCollection) const;
+
+private:
+	ImageValidator				m_validator;
+	Params						m_params;
+};
+
+void StackTestCase::initPrograms (vk::SourceCollections& programCollection) const
+{
+	m_validator.initPrograms(programCollection);
+
+	// Test validates handling of protected memory allocated on stack.
+	// The test copies protected memory content into temporary variable allocated inside function p.
+	// Thus test forces protected content to appear on stack.
+	// Function p() returns specified protected memory element from the variable allocated on stack.
+	// Function u() returns specified protected memory element from the global variable.
+	// Values returned by p() and u() should be same.
+	// Test is repeated several times (16) to avoid coincidental matches.
+	// In case of any mismatches it is signalized to inherited verifier function by setting 0 in result store image.
+	// Each invocation validates particular element (bytes) on stack.
+	// Number of invocations matches stack size specified in test parameters.
+	std::string comp =
+		std::string() +
+		"#version 450\n"
+		"layout(local_size_x = " + de::toString(m_params.imageWidth) + ", local_size_y = " + de::toString(m_params.imageHeight) + ", local_size_z = 1) in;\n"
+		"layout(set = 0, binding = 0, rgba8) writeonly uniform highp image2D u_resultImage;\n"
+		"layout(set = 0, binding = 1, rgba8) readonly uniform highp image2D u_srcImage;\n"
+		"vec4 protectedData[" + de::toString(m_params.stackSize) + "];\n"
+		"\n"
+		"vec4 p(int idx)\n"
+		"{\n"
+		"    vec4 localData[" + de::toString(m_params.stackSize) + "];\n"
+		"    for (int i = 0; i < " + de::toString(m_params.stackSize) + "; i++)\n"
+		"        localData[i] = protectedData[i];\n"
+		"    return localData[idx];\n"
+		"}\n"
+		"\n"
+		"vec4 u(int idx)\n"
+		"{\n"
+		"    return protectedData[idx];\n"
+		"}\n"
+		"\n"
+		"void main() {\n"
+		"    const int n = " + de::toString(m_params.stackSize) + ";\n"
+		"    int m = 0;\n"
+		"    int w = " + de::toString(m_params.imageWidth) + ";\n"
+		"    int gx = int(gl_GlobalInvocationID.x);\n"
+		"    int gy = int(gl_GlobalInvocationID.y);\n"
+		"    int checked_ndx = gy * w + gx;\n"
+		"    vec4 outColor;\n"
+		"\n"
+		"    for (int j = 0; j < 16; j++)\n"
+		"    {\n"
+		"        for (int i = 0; i < n; i++)\n"
+		"        {\n"
+		"            const int idx = (i + j) % n;\n"
+		"            protectedData[i] = imageLoad(u_srcImage, ivec2(idx % w, idx / w));\n"
+		"        }\n"
+		"\n"
+		"        vec4 vp = p(checked_ndx);\n"
+		"        vec4 vu = u(checked_ndx);\n"
+		"        if (any(notEqual(vp,vu)))\n"
+		"            m++;\n"
+		"    }\n"
+		"\n"
+		"    if (m <= 0)\n"
+		"        outColor = vec4(0.0f);\n"
+		"    else\n"
+		"        outColor = vec4(1.0f);\n"
+		"    imageStore(u_resultImage, ivec2(gx, gy), outColor);\n"
+		"}\n";
+
+	programCollection.glslSources.add("comp") << glu::ComputeSource(comp);
+}
+
+StackTestInstance::StackTestInstance (Context&				ctx,
+									  const ImageValidator&	validator,
+									  const Params&			params)
+	: ProtectedTestInstance	(ctx)
+	, m_validator			(validator)
+	, m_params				(params)
+{
+}
+
+de::MovePtr<tcu::Texture2D> StackTestInstance::createTestTexture2D (void)
+{
+	const tcu::TextureFormat		texFmt		= mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM);
+	de::MovePtr<tcu::Texture2D>		texture2D	(new tcu::Texture2D(texFmt, m_params.imageWidth, m_params.imageHeight));
+
+	texture2D->allocLevel(0);
+
+	const tcu::PixelBufferAccess&	level		= texture2D->getLevel(0);
+
+	fillWithUniqueColors(level, getSeedValue(m_params));
+
+	return texture2D;
+}
+
+tcu::TestStatus StackTestInstance::iterate (void)
+{
+	ProtectedContext&						ctx					(m_protectedContext);
+	const vk::DeviceInterface&				vk					= ctx.getDeviceInterface();
+	const vk::VkDevice						device				= ctx.getDevice();
+	const vk::VkQueue						queue				= ctx.getQueue();
+	const deUint32							queueFamilyIndex	= ctx.getQueueFamilyIndex();
+	const vk::VkPhysicalDeviceProperties	properties			= vk::getPhysicalDeviceProperties(ctx.getInstanceDriver(), ctx.getPhysicalDevice());
+
+	vk::Unique<vk::VkCommandPool>			cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
+
+	de::MovePtr<tcu::Texture2D>				texture2D			= createTestTexture2D();
+	const tcu::Sampler						refSampler			= tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
+																			   tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
+
+	vk::Unique<vk::VkShaderModule>			computeShader		(vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("comp"), 0));
+
+	de::MovePtr<vk::ImageWithMemory>		imageSrc;
+	de::MovePtr<vk::ImageWithMemory>		imageDst;
+	vk::Move<vk::VkSampler>					sampler;
+	vk::Move<vk::VkImageView>				imageViewSrc;
+	vk::Move<vk::VkImageView>				imageViewDst;
+
+	vk::Move<vk::VkDescriptorSetLayout>		descriptorSetLayout;
+	vk::Move<vk::VkDescriptorPool>			descriptorPool;
+	vk::Move<vk::VkDescriptorSet>			descriptorSet;
+
+	// Check the number of invocations supported
+	if (properties.limits.maxComputeWorkGroupInvocations < m_params.imageWidth * m_params.imageHeight)
+		throw tcu::NotSupportedError("Not enough compute workgroup invocations supported.");
+
+	// Create src and dst images
+	{
+		vk::VkImageUsageFlags imageUsageFlags = vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT	|
+												vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT	|
+												vk::VK_IMAGE_USAGE_SAMPLED_BIT		|
+												vk::VK_IMAGE_USAGE_STORAGE_BIT;
+
+		imageSrc = createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
+								 m_params.imageWidth, m_params.imageHeight,
+								 vk::VK_FORMAT_R8G8B8A8_UNORM,
+								 imageUsageFlags);
+
+		imageDst = createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
+								 m_params.imageWidth, m_params.imageHeight,
+								 vk::VK_FORMAT_R8G8B8A8_UNORM,
+								 imageUsageFlags);
+	}
+
+	// Upload source image
+	{
+		de::MovePtr<vk::ImageWithMemory>	unprotectedImage	= createImage2D(ctx, PROTECTION_DISABLED, queueFamilyIndex,
+																				m_params.imageWidth, m_params.imageHeight,
+																				vk::VK_FORMAT_R8G8B8A8_UNORM,
+																				vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+
+		// Upload data to an unprotected image
+		uploadImage(m_protectedContext, **unprotectedImage, *texture2D);
+
+		// Copy unprotected image to protected image
+		copyToProtectedImage(m_protectedContext, **unprotectedImage, **imageSrc, vk::VK_IMAGE_LAYOUT_GENERAL, m_params.imageWidth, m_params.imageHeight);
+	}
+
+	// Clear dst image
+	clearImage(m_protectedContext, **imageDst);
+
+	// Create descriptors
+	{
+		vk::DescriptorSetLayoutBuilder	layoutBuilder;
+		vk::DescriptorPoolBuilder		poolBuilder;
+
+		layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+		layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+		poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u);
+
+		descriptorSetLayout		= layoutBuilder.build(vk, device);
+		descriptorPool			= poolBuilder.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+		descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
+	}
+
+	// Create pipeline layout
+	vk::Unique<vk::VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
+
+	// Create image views
+	{
+		imageViewSrc = createImageView(ctx, **imageSrc, vk::VK_FORMAT_R8G8B8A8_UNORM);
+		imageViewDst = createImageView(ctx, **imageDst, vk::VK_FORMAT_R8G8B8A8_UNORM);
+	}
+
+	// Update descriptor set information
+	{
+		vk::DescriptorSetUpdateBuilder	updateBuilder;
+
+		vk::VkDescriptorImageInfo		descStorageImgDst	= makeDescriptorImageInfo((vk::VkSampler)0, *imageViewDst, vk::VK_IMAGE_LAYOUT_GENERAL);
+		vk::VkDescriptorImageInfo		descStorageImgSrc	= makeDescriptorImageInfo((vk::VkSampler)0, *imageViewSrc, vk::VK_IMAGE_LAYOUT_GENERAL);
+
+		updateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descStorageImgDst);
+		updateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descStorageImgSrc);
+
+		updateBuilder.update(vk, device);
+	}
+
+	// Create compute commands & submit
+	{
+		const vk::Unique<vk::VkFence>		fence		(vk::createFence(vk, device));
+		vk::Unique<vk::VkPipeline>			pipeline	(makeComputePipeline(vk, device, *pipelineLayout, *computeShader, DE_NULL));
+		vk::Unique<vk::VkCommandBuffer>		cmdBuffer	(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+		beginCommandBuffer(vk, *cmdBuffer);
+
+		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
+		vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
+		vk.cmdDispatch(*cmdBuffer, 1u, 1u, 1u);
+		endCommandBuffer(vk, *cmdBuffer);
+
+		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
+	}
+
+	// Calculate reference image
+	calculateRef(*texture2D);
+
+	// Validate result
+	return validateResult(**imageDst, vk::VK_IMAGE_LAYOUT_GENERAL, *texture2D, refSampler);
+}
+
+void StackTestInstance::calculateRef (tcu::Texture2D& texture2D)
+{
+	const tcu::PixelBufferAccess&	reference	= texture2D.getLevel(0);
+	const tcu::IVec4				zero;
+
+	for (int x = 0; x < reference.getWidth(); ++x)
+	for (int y = 0; y < reference.getHeight(); ++y)
+		reference.setPixel(zero, x, y);
+}
+
+tcu::TestStatus StackTestInstance::validateResult (vk::VkImage image, vk::VkImageLayout imageLayout, const tcu::Texture2D& texture2D, const tcu::Sampler& refSampler)
+{
+	de::Random			rnd			(getSeedValue(m_params));
+	ValidationData		refData;
+
+	for (int ndx = 0; ndx < 4; ++ndx)
+	{
+		const float	lod	= 0.0f;
+		const float	cx	= rnd.getFloat(0.0f, 1.0f);
+		const float	cy	= rnd.getFloat(0.0f, 1.0f);
+
+		refData.coords[ndx] = tcu::Vec4(cx, cy, 0.0f, 0.0f);
+		refData.values[ndx] = texture2D.sample(refSampler, cx, cy, lod);
+	}
+
+	if (!m_validator.validateImage(m_protectedContext, refData, image, vk::VK_FORMAT_R8G8B8A8_UNORM, imageLayout))
+		return tcu::TestStatus::fail("Result validation failed");
+	else
+		return tcu::TestStatus::pass("Pass");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup*	createStackTests (tcu::TestContext& testCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup> stackGroup (new tcu::TestCaseGroup(testCtx, "stack", "Protected memory stack tests"));
+
+	static const deUint32 stackMemSizes[] = { 32, 64, 128, 256, 512, 1024 };
+
+	for (int stackMemSizeIdx = 0; stackMemSizeIdx < DE_LENGTH_OF_ARRAY(stackMemSizes); ++stackMemSizeIdx)
+	{
+		std::string testName = std::string("stacksize_") + de::toString(stackMemSizes[stackMemSizeIdx]);
+
+		stackGroup->addChild(new StackTestCase(testCtx, testName, "", Params(stackMemSizes[stackMemSizeIdx])));
+	}
+
+	return stackGroup.release();
+}
+
+} // ProtectedMem
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.hpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.hpp
new file mode 100644
index 0000000..8142a9f
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStackTests.hpp
@@ -0,0 +1,42 @@
+#ifndef _VKTPROTECTEDMEMSTACKTESTS_HPP
+#define _VKTPROTECTEDMEMSTACKTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2018 The Khronos Group Inc.
+ * Copyright (c) 2018 Google Inc.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 Protected memory stack tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace ProtectedMem
+{
+
+tcu::TestCaseGroup*		createStackTests	(tcu::TestContext& testCtx);
+
+} // ProtectedMem
+} // vkt
+
+#endif // _VKTPROTECTEDMEMSTACKTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp
index 12ce141..0c30924 100644
--- a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp
@@ -40,6 +40,7 @@
 #include "vktProtectedMemWsiSwapchainTests.hpp"
 #include "vktProtectedMemYCbCrConversionTests.hpp"
 #include "vktProtectedMemWorkgroupStorageTests.hpp"
+#include "vktProtectedMemStackTests.hpp"
 
 namespace vkt
 {
@@ -96,6 +97,7 @@
 	}
 
 	protectedTests->addChild(createWorkgroupStorageTests(testCtx));
+	protectedTests->addChild(createStackTests(testCtx));
 
 	return protectedTests.release();
 
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp
index f5728e0..a484925 100644
--- a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp
@@ -913,5 +913,40 @@
 	}
 }
 
+void fillWithUniqueColors (const tcu::PixelBufferAccess& dst, deUint32 seed)
+{
+	// This is an implementation of linear congruential generator.
+	// The A and M are prime numbers, thus allowing to generate unique number sequence of length genM-1.
+	// The generator uses C constant as 0, thus value of 0 is not allowed as a seed.
+	const deUint64	genA	= 1573051ull;
+	const deUint64	genM	= 2097023ull;
+	deUint64		genX	= seed % genM;
+
+	DE_ASSERT(deUint64(dst.getWidth()) * deUint64(dst.getHeight()) * deUint64(dst.getDepth()) < genM - 1);
+
+	if (genX == 0)
+		genX = 1;
+
+	const int	numCols		= dst.getWidth();
+	const int	numRows		= dst.getHeight();
+	const int	numSlices	= dst.getDepth();
+
+	for (int z = 0; z < numSlices; z++)
+	for (int y = 0; y < numRows; y++)
+	for (int x = 0; x < numCols; x++)
+	{
+		genX = (genA * genX) % genM;
+
+		DE_ASSERT(genX != seed);
+
+		const float		r		= float(deUint32((genX >> 0)  & 0x7F)) / 127.0f;
+		const float		g		= float(deUint32((genX >> 7)  & 0x7F)) / 127.0f;
+		const float		b		= float(deUint32((genX >> 14) & 0x7F)) / 127.0f;
+		const tcu::Vec4	color	= tcu::Vec4(r, g, b, 1.0f);
+
+		dst.setPixel(color, x, y, z);
+	}
+}
+
 } // ProtectedMem
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp
index 8671a84..fd338cd 100644
--- a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp
+++ b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp
@@ -177,6 +177,9 @@
 																		 const tcu::Vec4&					maxVal,
 																		 deUint32							seed);
 
+void								fillWithUniqueColors				(const tcu::PixelBufferAccess&		dst,
+																		 deUint32							seed);
+
 } // ProtectedMem
 } // vkt
 
diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp
index 5c1a2b5..3d15661 100644
--- a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp
+++ b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp
@@ -400,7 +400,7 @@
 	endCommandBuffer(vk, *cmdBuffer);
 
 	if (m_testVector.queryResultsMode == RESULTS_MODE_GET_RESET)
-		vk.resetQueryPoolEXT(device, m_queryPool, 0, NUM_QUERIES_IN_POOL);
+		vk.resetQueryPool(device, m_queryPool, 0, NUM_QUERIES_IN_POOL);
 
 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
 
@@ -659,7 +659,7 @@
 		};
 
 		if (!hasSeparateResetCmdBuf() && m_testVector.queryResultsMode == RESULTS_MODE_GET_RESET)
-			vk.resetQueryPoolEXT(m_context.getDevice(), m_queryPool, 0, NUM_QUERIES_IN_POOL);
+			vk.resetQueryPool(m_context.getDevice(), m_queryPool, 0, NUM_QUERIES_IN_POOL);
 		vk.queueSubmit(queue, 1, &submitInfoRender, DE_NULL);
 	}
 
@@ -939,7 +939,7 @@
 
 	if (m_testVector.queryResultsMode == RESULTS_MODE_GET_RESET)
 	{
-		vk.resetQueryPoolEXT(device, m_queryPool, 0, NUM_QUERIES_IN_POOL);
+		vk.resetQueryPool(device, m_queryPool, 0, NUM_QUERIES_IN_POOL);
 		vk::VkResult queryResult = vk.getQueryPoolResults(device, m_queryPool, 0, NUM_QUERIES_IN_POOL, resultsBuffer.size(), &resultsBuffer[0], m_testVector.queryResultsStride, m_queryResultFlags);
 
 		if (queryResult != vk::VK_NOT_READY)
@@ -966,7 +966,7 @@
 
 				if (m_testVector.queryResultsAvailability && *(srcPtrTyped + 1) != 0)
 				{
-					TCU_FAIL("resetQueryPoolEXT did not disable availability bit");
+					TCU_FAIL("resetQueryPool did not disable availability bit");
 				}
 			}
 			else if (m_testVector.queryResultSize == RESULT_SIZE_64_BIT)
@@ -979,7 +979,7 @@
 
 				if (m_testVector.queryResultsAvailability && *(srcPtrTyped + 1) != 0)
 				{
-					TCU_FAIL("resetQueryPoolEXT did not disable availability bit");
+					TCU_FAIL("resetQueryPool did not disable availability bit");
 				}
 			}
 			else
diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolPerformanceTests.cpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolPerformanceTests.cpp
index ce1c454..a9b7312 100644
--- a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolPerformanceTests.cpp
+++ b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolPerformanceTests.cpp
@@ -258,10 +258,6 @@
 	// enable every <enabledCounterStride> counter that has command or render pass scope
 	for (deUint32 i = 0; i < counterCount; i++)
 	{
-		// skip counters with command buffer scope
-		if (m_counters[i].scope == VK_QUERY_SCOPE_COMMAND_BUFFER_KHR)
-			continue;
-
 		// handle offset
 		if (enabledCounterOffset)
 		{
diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp
index 56385f1..08bb2d2 100644
--- a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp
+++ b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp
@@ -519,7 +519,7 @@
 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Compute shader invocations: " << getComputeExecution(m_parameters[parametersNdx]) << tcu::TestLog::EndMessage;
 
 		if (m_parameters[0].resetType == RESET_TYPE_HOST)
-			vk.resetQueryPoolEXT(device, *queryPool, 0u, 1u);
+			vk.resetQueryPool(device, *queryPool, 0u, 1u);
 
 		// Wait for completion
 		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
@@ -544,7 +544,7 @@
 
 			deUint64 temp = data[0].first;
 
-			vk.resetQueryPoolEXT(device, *queryPool, 0, 1u);
+			vk.resetQueryPool(device, *queryPool, 0, 1u);
 			vk::VkResult res = GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
 			/* From Vulkan spec:
 			 *
@@ -698,7 +698,7 @@
 
 	// Secondary buffer is emitted only once, so it is safe to reset the query pool here.
 	if (m_parameters[0].resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, 1u);
+		vk.resetQueryPool(device, *queryPool, 0u, 1u);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -730,7 +730,7 @@
 
 			deUint64 temp = results[0].first;
 
-			vk.resetQueryPoolEXT(device, queryPool, 0u, 1u);
+			vk.resetQueryPool(device, queryPool, 0u, 1u);
 			vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
 			/* From Vulkan spec:
 			 *
@@ -906,7 +906,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parameters[0].resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, 1u);
+		vk.resetQueryPool(device, *queryPool, 0u, 1u);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -1288,7 +1288,7 @@
 	endCommandBuffer(vk, *cmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
@@ -1376,7 +1376,7 @@
 
 		deUint64 temp = results[0].first;
 
-		vk.resetQueryPoolEXT(device, queryPool, 0, queryCount);
+		vk.resetQueryPool(device, queryPool, 0, queryCount);
 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
 		/* From Vulkan spec:
 		 *
@@ -1506,7 +1506,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -1600,7 +1600,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -1763,7 +1763,7 @@
 	endCommandBuffer(vk, *cmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
@@ -1842,7 +1842,7 @@
 
 		deUint64 temp = results[0].first;
 
-		vk.resetQueryPoolEXT(device, queryPool, 0, queryCount);
+		vk.resetQueryPool(device, queryPool, 0, queryCount);
 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
 		/* From Vulkan spec:
 		 *
@@ -1958,7 +1958,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -2052,7 +2052,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -2213,7 +2213,7 @@
 	endCommandBuffer(vk, *cmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
@@ -2273,7 +2273,7 @@
 
 		deUint64 temp = results[0].first;
 
-		vk.resetQueryPoolEXT(device, queryPool, 0, queryCount);
+		vk.resetQueryPool(device, queryPool, 0, queryCount);
 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
 		/* From Vulkan spec:
 		 *
@@ -2378,7 +2378,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
@@ -2472,7 +2472,7 @@
 	endCommandBuffer(vk, *primaryCmdBuffer);
 
 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
-		vk.resetQueryPoolEXT(device, *queryPool, 0u, queryCount);
+		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
 
 	// Wait for completion
 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
diff --git a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
index afe7d56..5f35a7d 100644
--- a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
+++ b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
@@ -2150,31 +2150,31 @@
 												TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
 
 											if (getLineStippleEnable() &&
-												!context.getLineRasterizationFeatures().stippledRectangularLines)
+												!context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
 												TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
 											break;
 										case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
-											if (!context.getLineRasterizationFeatures().rectangularLines)
+											if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
 												TCU_THROW(NotSupportedError, "Rectangular lines not supported");
 
 											if (getLineStippleEnable() &&
-												!context.getLineRasterizationFeatures().stippledRectangularLines)
+												!context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
 												TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
 											break;
 										case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
-											if (!context.getLineRasterizationFeatures().bresenhamLines)
+											if (!context.getLineRasterizationFeaturesEXT().bresenhamLines)
 												TCU_THROW(NotSupportedError, "Bresenham lines not supported");
 
 											if (getLineStippleEnable() &&
-												!context.getLineRasterizationFeatures().stippledBresenhamLines)
+												!context.getLineRasterizationFeaturesEXT().stippledBresenhamLines)
 												TCU_THROW(NotSupportedError, "Stippled Bresenham lines not supported");
 											break;
 										case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
-											if (!context.getLineRasterizationFeatures().smoothLines)
+											if (!context.getLineRasterizationFeaturesEXT().smoothLines)
 												TCU_THROW(NotSupportedError, "Smooth lines not supported");
 
 											if (getLineStippleEnable() &&
-												!context.getLineRasterizationFeatures().stippledSmoothLines)
+												!context.getLineRasterizationFeaturesEXT().stippledSmoothLines)
 												TCU_THROW(NotSupportedError, "Stippled smooth lines not supported");
 											break;
 										}
diff --git a/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt b/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt
index 273f83f..0a2464f 100644
--- a/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt
@@ -19,10 +19,14 @@
 	vktRenderPassSparseRenderTargetTests.hpp
 	vktRenderPassSubpassDependencyTests.cpp
 	vktRenderPassSubpassDependencyTests.hpp
+	vktRenderPassUnusedAttachmentSparseFillingTests.hpp
+	vktRenderPassUnusedAttachmentSparseFillingTests.cpp
 	vktRenderPassUnusedAttachmentTests.cpp
 	vktRenderPassUnusedAttachmentTests.hpp
 	vktRenderPassUnusedClearAttachmentTests.cpp
 	vktRenderPassUnusedClearAttachmentTests.hpp
+	vktRenderPassFragmentDensityMapTests.cpp
+	vktRenderPassFragmentDensityMapTests.hpp
 	)
 
 set(DEQP_VK_RENDER_PASS_LIBS
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp
index 17437ca..ce2092c 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp
@@ -100,13 +100,14 @@
 	VkRect2D					renderArea;
 	VkImageAspectFlags			aspectFlag;
 	deUint32					sampleCount;
-	VkResolveModeFlagBitsKHR	depthResolveMode;
-	VkResolveModeFlagBitsKHR	stencilResolveMode;
+	VkResolveModeFlagBits		depthResolveMode;
+	VkResolveModeFlagBits		stencilResolveMode;
 	VerifyBuffer				verifyBuffer;
 	VkClearDepthStencilValue	clearValue;
 	float						depthExpectedValue;
 	deUint8						stencilExpectedValue;
 	bool						separateDepthStencilLayouts;
+	bool						unusedResolve;
 };
 
 float get16bitDepthComponent(deUint8* pixelPtr)
@@ -165,6 +166,8 @@
 	VkDevice						m_device;
 	VkPhysicalDevice				m_physicalDevice;
 
+	const Unique<VkCommandPool>		m_commandPool;
+
 	VkImageSp						m_multisampleImage;
 	AllocationSp					m_multisampleImageMemory;
 	VkImageViewSp					m_multisampleImageView;
@@ -178,8 +181,6 @@
 	Unique<VkFramebuffer>			m_framebuffer;
 	Unique<VkPipelineLayout>		m_renderPipelineLayout;
 	Unique<VkPipeline>				m_renderPipeline;
-
-	const Unique<VkCommandPool>		m_commandPool;
 };
 
 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
@@ -191,11 +192,13 @@
 	, m_device					(context.getDevice())
 	, m_physicalDevice			(context.getPhysicalDevice())
 
+	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
+
 	, m_multisampleImage		(createImage(m_config.sampleCount, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
 	, m_multisampleImageMemory	(createImageMemory(m_multisampleImage))
 	, m_multisampleImageView	(createImageView(m_multisampleImage, 0u))
 
-	, m_singlesampleImage		(createImage(1, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
+	, m_singlesampleImage		(createImage(1, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | (config.unusedResolve ? static_cast<vk::VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_DST_BIT) : 0u))))
 	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImage))
 	, m_singlesampleImageView	(createImageView(m_singlesampleImage, m_config.resolveBaseLayer))
 
@@ -206,9 +209,6 @@
 	, m_framebuffer				(createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
 	, m_renderPipelineLayout	(createRenderPipelineLayout())
 	, m_renderPipeline			(createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))
-
-
-	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
 {
 }
 
@@ -225,9 +225,9 @@
 	if (m_config.separateDepthStencilLayouts)
 		m_context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
 
-	VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties;
-	deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
-	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
+	VkPhysicalDeviceDepthStencilResolveProperties dsResolveProperties;
+	deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolveProperties));
+	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
 	dsResolveProperties.pNext = DE_NULL;
 
 	VkPhysicalDeviceProperties2 deviceProperties;
@@ -240,23 +240,23 @@
 	instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
 
 	// check if both modes are supported
-	VkResolveModeFlagBitsKHR depthResolveMode		= m_config.depthResolveMode;
-	VkResolveModeFlagBitsKHR stencilResolveMode		= m_config.stencilResolveMode;
-	if ((depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
+	VkResolveModeFlagBits depthResolveMode		= m_config.depthResolveMode;
+	VkResolveModeFlagBits stencilResolveMode		= m_config.stencilResolveMode;
+	if ((depthResolveMode != VK_RESOLVE_MODE_NONE) &&
 		!(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
 		TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
-	if ((stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
+	if ((stencilResolveMode != VK_RESOLVE_MODE_NONE) &&
 		!(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
 		TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
 
 	// check if the implementation supports setting the depth and stencil resolve
-	// modes to different values when one of those modes is VK_RESOLVE_MODE_NONE_KHR
+	// modes to different values when one of those modes is VK_RESOLVE_MODE_NONE
 	if (dsResolveProperties.independentResolveNone)
 	{
 		if ((!dsResolveProperties.independentResolve) &&
 			(depthResolveMode != stencilResolveMode) &&
-			(depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
-			(stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR))
+			(depthResolveMode != VK_RESOLVE_MODE_NONE) &&
+			(stencilResolveMode != VK_RESOLVE_MODE_NONE))
 			TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
 	}
 	else if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
@@ -384,6 +384,68 @@
 
 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void)
 {
+	// When the depth/stencil resolve attachment is unused, it needs to be cleared outside the render pass so it has the expected values.
+	if (m_config.unusedResolve)
+	{
+		const tcu::TextureFormat			format			(mapVkFormat(m_config.format));
+		const Unique<VkCommandBuffer>		commandBuffer	(allocateCommandBuffer(m_vkd, m_device, *m_commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+		const vk::VkImageSubresourceRange	imageRange		=
+		{
+			((tcu::hasDepthComponent(format.order)		? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT)	: 0u) |
+			 (tcu::hasStencilComponent(format.order)	? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT)	: 0u)),
+			0u,
+			VK_REMAINING_MIP_LEVELS,
+			0u,
+			VK_REMAINING_ARRAY_LAYERS,
+		};
+		const vk::VkImageMemoryBarrier		preBarrier		=
+		{
+			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+			nullptr,
+
+			// src and dst access masks.
+			0,
+			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
+
+			// old and new layouts.
+			vk::VK_IMAGE_LAYOUT_UNDEFINED,
+			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+
+			VK_QUEUE_FAMILY_IGNORED,
+			VK_QUEUE_FAMILY_IGNORED,
+
+			**m_singlesampleImage,
+			imageRange,
+		};
+		const vk::VkImageMemoryBarrier		postBarrier		=
+		{
+			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+			nullptr,
+
+			// src and dst access masks.
+			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
+			0,
+
+			// old and new layouts.
+			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+
+			VK_QUEUE_FAMILY_IGNORED,
+			VK_QUEUE_FAMILY_IGNORED,
+
+			**m_singlesampleImage,
+			imageRange,
+		};
+
+		vk::beginCommandBuffer(m_vkd, commandBuffer.get());
+			m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preBarrier);
+			m_vkd.cmdClearDepthStencilImage(commandBuffer.get(), **m_singlesampleImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_config.clearValue, 1u, &imageRange);
+			m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &postBarrier);
+		vk::endCommandBuffer(m_vkd, commandBuffer.get());
+
+		vk::submitCommandsAndWait(m_vkd, m_device, m_context.getUniversalQueue(), commandBuffer.get());
+	}
+
 	const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
 
 	VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@@ -424,7 +486,7 @@
 		attachmentDescriptionStencil = &stencilFinalLayout;
 	}
 
-	const AttachmentDescription2 multisampleAttachment		// VkAttachmentDescription2KHR
+	const AttachmentDescription2 multisampleAttachment		// VkAttachmentDescription2
 	(
 															// VkStructureType					sType;
 		attachmentDescriptionStencil,						// const void*						pNext;
@@ -438,7 +500,7 @@
 		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
 		finalLayout											// VkImageLayout					finalLayout;
 	);
-	const AttachmentReference2 multisampleAttachmentRef		// VkAttachmentReference2KHR
+	const AttachmentReference2 multisampleAttachmentRef		// VkAttachmentReference2
 	(
 															// VkStructureType					sType;
 		attachmentRefStencil,								// const void*						pNext;
@@ -447,7 +509,9 @@
 		0u													// VkImageAspectFlags				aspectMask;
 	);
 
-	const AttachmentDescription2 singlesampleAttachment		// VkAttachmentDescription2KHR
+	const vk::VkImageLayout		singleSampleInitialLayout = (m_config.unusedResolve ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED);
+
+	const AttachmentDescription2 singlesampleAttachment		// VkAttachmentDescription2
 	(
 															// VkStructureType					sType;
 		attachmentDescriptionStencil,						// const void*						pNext;
@@ -458,32 +522,32 @@
 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp;
-		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
+		singleSampleInitialLayout,							// VkImageLayout					initialLayout;
 		finalLayout											// VkImageLayout					finalLayout;
 	);
-	AttachmentReference2 singlesampleAttachmentRef			// VkAttachmentReference2KHR
+	AttachmentReference2 singlesampleAttachmentRef			// VkAttachmentReference2
 	(
-															// VkStructureType					sType;
-		DE_NULL,											// const void*						pNext;
-		1u,													// deUint32							attachment;
-		layout,												// VkImageLayout					layout;
-		0u													// VkImageAspectFlags				aspectMask;
+																// VkStructureType					sType;
+		DE_NULL,												// const void*						pNext;
+		(m_config.unusedResolve ? VK_ATTACHMENT_UNUSED : 1u),	// deUint32							attachment;
+		layout,													// VkImageLayout					layout;
+		0u														// VkImageAspectFlags				aspectMask;
 	);
 
 	std::vector<AttachmentDescription2> attachments;
 	attachments.push_back(multisampleAttachment);
 	attachments.push_back(singlesampleAttachment);
 
-	VkSubpassDescriptionDepthStencilResolveKHR dsResolveDescription =
+	VkSubpassDescriptionDepthStencilResolve dsResolveDescription =
 	{
-		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,
+		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
 		DE_NULL,																// const void*						pNext;
-		m_config.depthResolveMode,												// VkResolveModeFlagBitsKHR			depthResolveMode;
-		m_config.stencilResolveMode,											// VkResolveModeFlagBitsKHR			stencilResolveMode;
-		&singlesampleAttachmentRef												// VkAttachmentReference2KHR		pDepthStencilResolveAttachment;
+		m_config.depthResolveMode,												// VkResolveModeFlagBits			depthResolveMode;
+		m_config.stencilResolveMode,											// VkResolveModeFlagBits			stencilResolveMode;
+		&singlesampleAttachmentRef												// VkAttachmentReference2			pDepthStencilResolveAttachment;
 	};
 
-	const SubpassDescription2 subpass					// VkSubpassDescription2KHR
+	const SubpassDescription2 subpass					// VkSubpassDescription2
 	(
 														// VkStructureType						sType;
 		&dsResolveDescription,							// const void*							pNext;
@@ -491,26 +555,26 @@
 		VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint					pipelineBindPoint;
 		0u,												// deUint32								viewMask;
 		0u,												// deUint32								inputAttachmentCount;
-		DE_NULL,										// const VkAttachmentReference2KHR*		pInputAttachments;
+		DE_NULL,										// const VkAttachmentReference2*		pInputAttachments;
 		0u,												// deUint32								colorAttachmentCount;
-		DE_NULL,										// const VkAttachmentReference2KHR*		pColorAttachments;
-		DE_NULL,										// const VkAttachmentReference2KHR*		pResolveAttachments;
-		&multisampleAttachmentRef,						// const VkAttachmentReference2KHR*		pDepthStencilAttachment;
+		DE_NULL,										// const VkAttachmentReference2*		pColorAttachments;
+		DE_NULL,										// const VkAttachmentReference2*		pResolveAttachments;
+		&multisampleAttachmentRef,						// const VkAttachmentReference2*		pDepthStencilAttachment;
 		0u,												// deUint32								preserveAttachmentCount;
 		DE_NULL											// const deUint32*						pPreserveAttachments;
 	);
 
-	const RenderPassCreateInfo2 renderPassCreator		// VkRenderPassCreateInfo2KHR
+	const RenderPassCreateInfo2 renderPassCreator		// VkRenderPassCreateInfo2
 	(
 														// VkStructureType						sType;
 		DE_NULL,										// const void*							pNext;
 		(VkRenderPassCreateFlags)0u,					// VkRenderPassCreateFlags				flags;
 		(deUint32)attachments.size(),					// deUint32								attachmentCount;
-		&attachments[0],								// const VkAttachmentDescription2KHR*	pAttachments;
+		&attachments[0],								// const VkAttachmentDescription2*		pAttachments;
 		1u,												// deUint32								subpassCount;
-		&subpass,										// const VkSubpassDescription2KHR*		pSubpasses;
+		&subpass,										// const VkSubpassDescription2*			pSubpasses;
 		0u,												// deUint32								dependencyCount;
-		DE_NULL,										// const VkSubpassDependency2KHR*		pDependencies;
+		DE_NULL,										// const VkSubpassDependency2*			pDependencies;
 		0u,												// deUint32								correlatedViewMaskCount;
 		DE_NULL											// const deUint32*						pCorrelatedViewMasks;
 	);
@@ -853,7 +917,7 @@
 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
 
 	float expectedValue = m_config.depthExpectedValue;
-	if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE_KHR)
+	if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
 		expectedValue = m_config.clearValue.depth;
 
 	// depth data in buffer is tightly packed, ConstPixelBufferAccess
@@ -943,7 +1007,7 @@
 	// because of that depth and stencil need to be tested separately
 
 	deUint8 expectedValue = m_config.stencilExpectedValue;
-	if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE_KHR)
+	if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
 		expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
 
 	for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
@@ -1090,6 +1154,68 @@
 	}
 };
 
+class PropertiesTestCase : public vkt::TestCase
+{
+public:
+							PropertiesTestCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description)
+								: vkt::TestCase(testCtx, name, description)
+								{}
+	virtual					~PropertiesTestCase		(void) {}
+
+	virtual TestInstance*	createInstance			(Context& context) const;
+	virtual void			checkSupport			(Context& context) const;
+};
+
+class PropertiesTestInstance : public vkt::TestInstance
+{
+public:
+								PropertiesTestInstance	(Context& context)
+									: vkt::TestInstance(context)
+									{}
+	virtual						~PropertiesTestInstance	(void) {}
+
+	virtual tcu::TestStatus		iterate					(void);
+
+};
+
+TestInstance* PropertiesTestCase::createInstance (Context& context) const
+{
+	return new PropertiesTestInstance(context);
+}
+
+void PropertiesTestCase::checkSupport (Context& context) const
+{
+	context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
+}
+
+tcu::TestStatus PropertiesTestInstance::iterate (void)
+{
+	vk::VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsrProperties;
+	dsrProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
+	dsrProperties.pNext = nullptr;
+
+	vk::VkPhysicalDeviceProperties2 properties2;
+	properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+	properties2.pNext = &dsrProperties;
+
+	m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);
+
+	if ((dsrProperties.supportedDepthResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
+		TCU_FAIL("supportedDepthResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
+
+	if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
+		TCU_FAIL("supportedStencilResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
+
+	if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_AVERAGE_BIT_KHR) != 0)
+		TCU_FAIL("supportedStencilResolveModes includes forbidden VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
+
+	if (dsrProperties.independentResolve == VK_TRUE && dsrProperties.independentResolveNone != VK_TRUE)
+		TCU_FAIL("independentResolve supported but independentResolveNone not supported");
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+
 void initTests (tcu::TestCaseGroup* group)
 {
 	typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
@@ -1114,16 +1240,16 @@
 
 	struct ResolveModeData
 	{
-		VkResolveModeFlagBitsKHR	flag;
-		std::string					name;
+		VkResolveModeFlagBits	flag;
+		std::string				name;
 	};
 	ResolveModeData resolveModes[] =
 	{
-		{ VK_RESOLVE_MODE_NONE_KHR,				"none" },
-		{ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,	"zero" },
-		{ VK_RESOLVE_MODE_AVERAGE_BIT_KHR,		"average" },
-		{ VK_RESOLVE_MODE_MIN_BIT_KHR,			"min" },
-		{ VK_RESOLVE_MODE_MAX_BIT_KHR,			"max" },
+		{ VK_RESOLVE_MODE_NONE,				"none" },
+		{ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,	"zero" },
+		{ VK_RESOLVE_MODE_AVERAGE_BIT,		"average" },
+		{ VK_RESOLVE_MODE_MIN_BIT,			"min" },
+		{ VK_RESOLVE_MODE_MAX_BIT,			"max" },
 	};
 
 	struct ImageTestData
@@ -1175,6 +1301,13 @@
 
 	tcu::TestContext& testCtx(group->getTestContext());
 
+	// Misc tests.
+	{
+		de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", "Miscellaneous depth/stencil resolve tests"));
+		miscGroup->addChild(new PropertiesTestCase(testCtx, "properties", "Check reported depth/stencil resolve properties"));
+		group->addChild(miscGroup.release());
+	}
+
 	// iterate over image data
 	for	 (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
 	{
@@ -1218,84 +1351,93 @@
 						// iterate over stencil resolve modes
 						for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
 						{
-							// there is no average resolve mode for stencil - go to next iteration
-							ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
-							if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
-								continue;
-
-							// if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
-							// depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
-							ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
-							if ((dResolve.flag == VK_RESOLVE_MODE_NONE_KHR) && (sResolve.flag == VK_RESOLVE_MODE_NONE_KHR))
-								continue;
-
-							// If there is no depth, the depth resolve mode should be NONE, or
-							// match the stencil resolve mode.
-							if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
-								(dResolve.flag != sResolve.flag))
-								continue;
-
-							// If there is no stencil, the stencil resmove mode should be NONE, or
-							// match the depth resolve mode.
-							if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
-								(dResolve.flag != sResolve.flag))
-								continue;
-
-							std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
-
-							if (hasDepth)
+							for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
 							{
-								std::string	name			= baseName + "_testing_depth";
-								const char*	testName		= name.c_str();
-								float		expectedValue	= depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
+								// there is no average resolve mode for stencil - go to next iteration
+								ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
+								if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
+									continue;
 
-								const TestConfig testConfig =
-								{
-									format,
-									imageData.width,
-									imageData.height,
-									1u,
-									1u,
-									0u,
-									imageData.renderArea,
-									aspectFlags,
-									sampleCount,
-									dResolve.flag,
-									sResolve.flag,
-									VB_DEPTH,
-									imageData.clearValue,
-									expectedValue,
-									0u,
-									useSeparateDepthStencilLayouts
-								};
-								formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
-							}
-							if (hasStencil)
-							{
-								std::string	name			= baseName + "_testing_stencil";
-								const char*	testName		= name.c_str();
-								deUint8		expectedValue	= stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
+								// if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
+								// depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
+								ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
+								if ((dResolve.flag == VK_RESOLVE_MODE_NONE) && (sResolve.flag == VK_RESOLVE_MODE_NONE))
+									continue;
 
-								const TestConfig testConfig =
+								// If there is no depth, the depth resolve mode should be NONE, or
+								// match the stencil resolve mode.
+								if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE) &&
+									(dResolve.flag != sResolve.flag))
+									continue;
+
+								// If there is no stencil, the stencil resolve mode should be NONE, or
+								// match the depth resolve mode.
+								if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE) &&
+									(dResolve.flag != sResolve.flag))
+									continue;
+
+								const bool unusedResolve = (unusedIdx > 0);
+
+								std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
+								if (unusedResolve)
+									baseName += "_unused_resolve";
+
+								if (hasDepth)
 								{
-									format,
-									imageData.width,
-									imageData.height,
-									1u,
-									1u,
-									0u,
-									imageData.renderArea,
-									aspectFlags,
-									sampleCount,
-									dResolve.flag,
-									sResolve.flag,
-									VB_STENCIL,
-									imageData.clearValue,
-									0.0f,
-									expectedValue,
-									useSeparateDepthStencilLayouts
-								};
-								formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+									std::string	name			= baseName + "_testing_depth";
+									const char*	testName		= name.c_str();
+									float		expectedValue	= depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
+
+									const TestConfig testConfig =
+									{
+										format,
+										imageData.width,
+										imageData.height,
+										1u,
+										1u,
+										0u,
+										imageData.renderArea,
+										aspectFlags,
+										sampleCount,
+										dResolve.flag,
+										sResolve.flag,
+										VB_DEPTH,
+										imageData.clearValue,
+										expectedValue,
+										0u,
+										useSeparateDepthStencilLayouts,
+										unusedResolve,
+									};
+									formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+								}
+								if (hasStencil)
+								{
+									std::string	name			= baseName + "_testing_stencil";
+									const char*	testName		= name.c_str();
+									deUint8		expectedValue	= stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
+
+									const TestConfig testConfig =
+									{
+										format,
+										imageData.width,
+										imageData.height,
+										1u,
+										1u,
+										0u,
+										imageData.renderArea,
+										aspectFlags,
+										sampleCount,
+										dResolve.flag,
+										sResolve.flag,
+										VB_STENCIL,
+										imageData.clearValue,
+										0.0f,
+										expectedValue,
+										useSeparateDepthStencilLayouts,
+										unusedResolve,
+									};
+									formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+								}
 							}
 						}
 					}
@@ -1351,64 +1493,72 @@
 
 					for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
 					{
-						ResolveModeData& mode = resolveModes[resolveModeNdx];
-
-						if (hasDepth)
+						for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
 						{
-							std::string	name			= "depth_" + mode.name;
-							const char*	testName		= name.c_str();
-							float		expectedValue	= depthExpectedValue[resolveModeNdx][sampleCountNdx];
-							const TestConfig testConfig =
-							{
-								format,
-								layeredTextureTestData.width,
-								layeredTextureTestData.height,
-								layeredTextureTestData.imageLayers,
-								3u,
-								0u,
-								layeredTextureTestData.renderArea,
-								aspectFlags,
-								sampleCount,
-								mode.flag,
-								VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
-								VB_DEPTH,
-								layeredTextureTestData.clearValue,
-								expectedValue,
-								0u,
-								useSeparateDepthStencilLayouts
-							};
-							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
-						}
+							ResolveModeData& mode = resolveModes[resolveModeNdx];
 
-						// there is no average resolve mode for stencil - go to next iteration
-						if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
-							continue;
+							const bool			unusedResolve	= (unusedIdx > 0);
+							const std::string	unusedSuffix	= (unusedResolve ? "_unused_resolve" : "");
 
-						if (hasStencil)
-						{
-							std::string	name			= "stencil_" + mode.name;
-							const char*	testName		= name.c_str();
-							deUint8		expectedValue	= stencilExpectedValue[resolveModeNdx][sampleCountNdx];
-							const TestConfig testConfig =
+							if (hasDepth)
 							{
-								format,
-								layeredTextureTestData.width,
-								layeredTextureTestData.height,
-								layeredTextureTestData.imageLayers,
-								3u,
-								0u,
-								layeredTextureTestData.renderArea,
-								aspectFlags,
-								sampleCount,
-								VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
-								mode.flag,
-								VB_STENCIL,
-								layeredTextureTestData.clearValue,
-								0.0f,
-								expectedValue,
-								useSeparateDepthStencilLayouts
-							};
-							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+								std::string	name			= "depth_" + mode.name + unusedSuffix;
+								const char*	testName		= name.c_str();
+								float		expectedValue	= depthExpectedValue[resolveModeNdx][sampleCountNdx];
+								const TestConfig testConfig =
+								{
+									format,
+									layeredTextureTestData.width,
+									layeredTextureTestData.height,
+									layeredTextureTestData.imageLayers,
+									3u,
+									0u,
+									layeredTextureTestData.renderArea,
+									aspectFlags,
+									sampleCount,
+									mode.flag,
+									VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+									VB_DEPTH,
+									layeredTextureTestData.clearValue,
+									expectedValue,
+									0u,
+									useSeparateDepthStencilLayouts,
+									unusedResolve,
+								};
+								formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+							}
+
+							// there is no average resolve mode for stencil - go to next iteration
+							if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
+								continue;
+
+							if (hasStencil)
+							{
+								std::string	name			= "stencil_" + mode.name + unusedSuffix;
+								const char*	testName		= name.c_str();
+								deUint8		expectedValue	= stencilExpectedValue[resolveModeNdx][sampleCountNdx];
+								const TestConfig testConfig =
+								{
+									format,
+									layeredTextureTestData.width,
+									layeredTextureTestData.height,
+									layeredTextureTestData.imageLayers,
+									3u,
+									0u,
+									layeredTextureTestData.renderArea,
+									aspectFlags,
+									sampleCount,
+									VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+									mode.flag,
+									VB_STENCIL,
+									layeredTextureTestData.clearValue,
+									0.0f,
+									expectedValue,
+									useSeparateDepthStencilLayouts,
+									unusedResolve,
+								};
+								formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
+							}
 						}
 					}
 					sampleGroup->addChild(formatGroup.release());
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.cpp
new file mode 100644
index 0000000..573f676
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.cpp
@@ -0,0 +1,1248 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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 Tests fragment density map extension ( VK_EXT_fragment_density_map )
+ *//*--------------------------------------------------------------------*/
+
+#include "vktRenderPassFragmentDensityMapTests.hpp"
+#include "pipeline/vktPipelineImageUtil.hpp"
+#include "deMath.h"
+#include "vktTestCase.hpp"
+#include "vkImageUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "tcuTestLog.hpp"
+#include <sstream>
+#include <vector>
+
+// Each test generates an image with a color gradient where all colors should be unique when rendered without density map
+// ( the number of each color in a histogram should be 1 ).
+// The whole density map has the same values defined by input fragment area ( one of the test input parameters ).
+// With density map enabled - the number of each color in a histogram should be [ fragmentArea.x * fragmentArea.y ].
+//
+// Additionally test checks if gl_FragSizeEXT shader variable has proper value ( as defined by fragmentArea input parameter ).
+//
+// static_* tests use density map loaded from CPU.
+// dynamic_* tests use density map rendered on a GPU in a separate render pass
+// *_nonsubsampled tests check if it's possible to use nonsubsampled images instead of subsampled ones
+// There are 3 render passes performed during the test:
+//  - render pass that produces density map ( this rp is skipped when density map is static )
+//  - render pass that produces subsampled image using density map
+//  - render pass that copies subsampled image to traditional image using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT flag.
+//    ( because subsampled images cannot be retrieved to CPU in any other way ).
+
+namespace vkt
+{
+
+namespace renderpass
+{
+
+using namespace vk;
+
+namespace
+{
+
+// set value of DRY_RUN_WITHOUT_FDM_EXTENSION to 1 if you want to check the correctness of the code without using VK_EXT_fragment_density_map extension
+#define DRY_RUN_WITHOUT_FDM_EXTENSION 0
+
+struct TestParams
+{
+	TestParams(bool dynamicDensity, bool nonSubsampled, const tcu::UVec2& area)
+		: dynamicDensityMap{ dynamicDensity }, nonSubsampledImages{ nonSubsampled }, fragmentArea{ area }, densityMapFormat{ VK_FORMAT_R8G8_UNORM }
+	{}
+	bool		dynamicDensityMap;
+	bool		nonSubsampledImages;
+	tcu::UVec2	fragmentArea;
+	VkFormat	densityMapFormat;
+};
+
+struct Vertex4RGBA
+{
+	tcu::Vec4	position;
+	tcu::Vec4	color;
+};
+
+std::vector<Vertex4RGBA> createFullscreenQuadRG(void)
+{
+	const Vertex4RGBA lowerLeftVertex	= { tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f) };
+	const Vertex4RGBA upperLeftVertex	= { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),	tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f) };
+	const Vertex4RGBA lowerRightVertex	= { tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),		tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f) };
+	const Vertex4RGBA upperRightVertex	= { tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) };
+
+	return
+	{
+		lowerLeftVertex, lowerRightVertex, upperLeftVertex,
+		upperLeftVertex, lowerRightVertex, upperRightVertex
+	};
+}
+
+std::vector<Vertex4RGBA> createFullscreenQuadDensity(float densityX, float densityY)
+{
+	const Vertex4RGBA lowerLeftVertex	= { tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),		tcu::Vec4(densityX, densityY, 0.0f, 1.0f) };
+	const Vertex4RGBA upperLeftVertex	= { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),	tcu::Vec4(densityX, densityY, 0.0f, 1.0f) };
+	const Vertex4RGBA lowerRightVertex	= { tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),		tcu::Vec4(densityX, densityY, 0.0f, 1.0f) };
+	const Vertex4RGBA upperRightVertex	= { tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),		tcu::Vec4(densityX, densityY, 0.0f, 1.0f) };
+
+	return
+	{
+		lowerLeftVertex, lowerRightVertex, upperLeftVertex,
+		upperLeftVertex, lowerRightVertex, upperRightVertex
+	};
+};
+
+template <typename T>
+void createVertexBuffer(const DeviceInterface&		vk,
+						VkDevice					vkDevice,
+						const deUint32&				queueFamilyIndex,
+						SimpleAllocator&			memAlloc,
+						const std::vector<T>&		vertices,
+						Move<VkBuffer>&				vertexBuffer,
+						de::MovePtr<Allocation>&	vertexAlloc)
+{
+	const VkBufferCreateInfo vertexBufferParams =
+	{
+		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,			// VkStructureType		sType;
+		DE_NULL,										// const void*			pNext;
+		0u,												// VkBufferCreateFlags	flags;
+		(VkDeviceSize)(sizeof(T) * vertices.size()),	// VkDeviceSize			size;
+		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,				// VkBufferUsageFlags	usage;
+		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode		sharingMode;
+		1u,												// deUint32				queueFamilyIndexCount;
+		&queueFamilyIndex								// const deUint32*		pQueueFamilyIndices;
+	};
+
+	vertexBuffer	= createBuffer(vk, vkDevice, &vertexBufferParams);
+	vertexAlloc		= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
+	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
+
+	// Upload vertex data
+	deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(T));
+	flushAlloc(vk, vkDevice, *vertexAlloc);
+}
+
+template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
+Move<VkRenderPass> createRenderPassProduceDynamicDensityMap(const DeviceInterface&	vk,
+															VkDevice				vkDevice,
+															const TestParams&		testParams)
+{
+	VkImageLayout densityPassFinalLayout = testParams.dynamicDensityMap ? VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	std::vector<AttachmentDesc>		attachmentDescriptions =
+	{
+		{
+			DE_NULL,															// const void*						pNext
+			(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
+			testParams.densityMapFormat,										// VkFormat							format
+			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits			samples
+			VK_ATTACHMENT_LOAD_OP_CLEAR,										// VkAttachmentLoadOp				loadOp
+			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp				storeOp
+			VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
+			VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
+			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout					initialLayout
+			densityPassFinalLayout												// VkImageLayout					finalLayout
+		}
+	};
+
+	std::vector<AttachmentRef> colorAttachmentRefs
+	{
+		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
+	};
+
+	std::vector<SubpassDesc>	subpassDescriptions
+	{
+		{
+			DE_NULL,
+			(VkSubpassDescriptionFlags)0,										// VkSubpassDescriptionFlags		flags
+			VK_PIPELINE_BIND_POINT_GRAPHICS,									// VkPipelineBindPoint				pipelineBindPoint
+			0u,																	// deUint32							viewMask
+			0u,																	// deUint32							inputAttachmentCount
+			DE_NULL,															// const VkAttachmentReference*		pInputAttachments
+			static_cast<deUint32>(colorAttachmentRefs.size()),					// deUint32							colorAttachmentCount
+			colorAttachmentRefs.data(),											// const VkAttachmentReference*		pColorAttachments
+			DE_NULL,															// const VkAttachmentReference*		pResolveAttachments
+			DE_NULL,															// const VkAttachmentReference*		pDepthStencilAttachment
+			0u,																	// deUint32							preserveAttachmentCount
+			DE_NULL																// const deUint32*					pPreserveAttachments
+		}
+	};
+
+	std::vector<SubpassDep>		subpassDependencies;
+	if ( testParams.dynamicDensityMap )
+	{
+		subpassDependencies.emplace_back(
+			SubpassDep(
+				DE_NULL,														// const void*				pNext
+				0u,																// uint32_t					srcSubpass
+				VK_SUBPASS_EXTERNAL,											// uint32_t					dstSubpass
+				VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,					// VkPipelineStageFlags		srcStageMask
+				VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,				// VkPipelineStageFlags		dstStageMask
+				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,							// VkAccessFlags			srcAccessMask
+				VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,					// VkAccessFlags			dstAccessMask
+				VK_DEPENDENCY_BY_REGION_BIT,									// VkDependencyFlags		dependencyFlags
+				0u																// deInt32					viewOffset
+			)
+		);
+	};
+
+	const RenderPassCreateInfo	renderPassInfo(
+		DE_NULL,																// const void*						pNext
+		(VkRenderPassCreateFlags)0,												// VkRenderPassCreateFlags			flags
+		static_cast<deUint32>(attachmentDescriptions.size()),					// deUint32							attachmentCount
+		attachmentDescriptions.data(),											// const VkAttachmentDescription*	pAttachments
+		static_cast<deUint32>(subpassDescriptions.size()),						// deUint32							subpassCount
+		subpassDescriptions.data(),												// const VkSubpassDescription*		pSubpasses
+		static_cast<deUint32>(subpassDependencies.size()),						// deUint32							dependencyCount
+		(!testParams.dynamicDensityMap) ? DE_NULL : subpassDependencies.data(),	// const VkSubpassDependency*		pDependencies
+		0u,																		// deUint32							correlatedViewMaskCount
+		DE_NULL																	// const deUint32*					pCorrelatedViewMasks
+	);
+
+	return renderPassInfo.createRenderPass(vk, vkDevice);
+}
+
+template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
+Move<VkRenderPass> createRenderPassProduceSubsampledImage(const DeviceInterface&	vk,
+													 VkDevice				vkDevice,
+													 const TestParams&		testParams)
+{
+	DE_UNREF(testParams);
+	std::vector<AttachmentDesc>		attachmentDescriptions
+	{
+		// Output color attachment
+		{
+			DE_NULL,																// const void*						pNext
+			(VkAttachmentDescriptionFlags)0,										// VkAttachmentDescriptionFlags		flags
+			VK_FORMAT_R8G8B8A8_UNORM,												// VkFormat							format
+			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			samples
+			VK_ATTACHMENT_LOAD_OP_CLEAR,											// VkAttachmentLoadOp				loadOp
+			VK_ATTACHMENT_STORE_OP_STORE,											// VkAttachmentStoreOp				storeOp
+			VK_ATTACHMENT_LOAD_OP_DONT_CARE,										// VkAttachmentLoadOp				stencilLoadOp
+			VK_ATTACHMENT_STORE_OP_DONT_CARE,										// VkAttachmentStoreOp				stencilStoreOp
+			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout					initialLayout
+			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL								// VkImageLayout					finalLayout
+		}
+	};
+
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	{
+		attachmentDescriptions.emplace_back(
+			AttachmentDesc(
+				DE_NULL,															// const void*						pNext
+				(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
+				testParams.densityMapFormat,										// VkFormat							format
+				VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits			samples
+				VK_ATTACHMENT_LOAD_OP_LOAD,											// VkAttachmentLoadOp				loadOp
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				storeOp
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
+				VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,					// VkImageLayout					initialLayout
+				VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT					// VkImageLayout					finalLayout
+			)
+		);
+	}
+#endif
+
+	std::vector<AttachmentRef> colorAttachmentRefs
+	{
+		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
+	};
+
+	std::vector<SubpassDesc>	subpassDescriptions
+	{
+		{
+			DE_NULL,
+			(VkSubpassDescriptionFlags)0,											// VkSubpassDescriptionFlags	flags
+			VK_PIPELINE_BIND_POINT_GRAPHICS,										// VkPipelineBindPoint			pipelineBindPoint
+			0u,																		// deUint32						viewMask
+			0u,																		// deUint32						inputAttachmentCount
+			DE_NULL,																// const VkAttachmentReference*	pInputAttachments
+			static_cast<deUint32>(colorAttachmentRefs.size()),						// deUint32						colorAttachmentCount
+			colorAttachmentRefs.data(),												// const VkAttachmentReference*	pColorAttachments
+			DE_NULL,																// const VkAttachmentReference*	pResolveAttachments
+			DE_NULL,																// const VkAttachmentReference*	pDepthStencilAttachment
+			0u,																		// deUint32						preserveAttachmentCount
+			DE_NULL																	// const deUint32*				pPreserveAttachments
+		}
+	};
+
+	std::vector<SubpassDep>		subpassDependencies
+	{
+		{
+			DE_NULL,																// const void*				pNext
+			0u,																		// uint32_t					srcSubpass
+			VK_SUBPASS_EXTERNAL,													// uint32_t					dstSubpass
+			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,							// VkPipelineStageFlags		srcStageMask
+			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,									// VkPipelineStageFlags		dstStageMask
+			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags			srcAccessMask
+			VK_ACCESS_SHADER_READ_BIT,												// VkAccessFlags			dstAccessMask
+			VK_DEPENDENCY_BY_REGION_BIT,											// VkDependencyFlags		dependencyFlags
+			0u																		// deInt32					viewOffset
+		}
+	};
+
+	VkRenderPassFragmentDensityMapCreateInfoEXT renderPassFragmentDensityMap;
+	renderPassFragmentDensityMap.sType							= VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT;
+	renderPassFragmentDensityMap.pNext							= DE_NULL;
+	renderPassFragmentDensityMap.fragmentDensityMapAttachment	= { 1, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT };
+
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	const void* renderPassInfoPNext = (const void*)&renderPassFragmentDensityMap;
+#else
+	const void* renderPassInfoPNext = DE_NULL;
+#endif
+	const RenderPassCreateInfo	renderPassInfo(
+		renderPassInfoPNext,														// const void*						pNext
+		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
+		static_cast<deUint32>(attachmentDescriptions.size()),						// deUint32							attachmentCount
+		attachmentDescriptions.data(),												// const VkAttachmentDescription*	pAttachments
+		static_cast<deUint32>(subpassDescriptions.size()),							// deUint32							subpassCount
+		subpassDescriptions.data(),													// const VkSubpassDescription*		pSubpasses
+		static_cast<deUint32>(subpassDependencies.size()),							// deUint32							dependencyCount
+		subpassDependencies.data(),													// const VkSubpassDependency*		pDependencies
+		0u,																			// deUint32							correlatedViewMaskCount
+		DE_NULL																		// const deUint32*					pCorrelatedViewMasks
+	);
+
+	return renderPassInfo.createRenderPass(vk, vkDevice);
+}
+
+template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
+Move<VkRenderPass> createRenderPassOutputSubsampledImage(const DeviceInterface&	vk,
+													VkDevice				vkDevice,
+													const TestParams&		testParams)
+{
+	DE_UNREF(testParams);
+	// copy subsampled image to ordinary image - you cannot retrieve subsampled image to CPU in any way. You must first convert it into plain image through rendering
+	std::vector<AttachmentDesc>		attachmentDescriptions =
+	{
+		// output attachment
+		AttachmentDesc(
+			DE_NULL,											// const void*						pNext
+			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
+			VK_FORMAT_R8G8B8A8_UNORM,							// VkFormat							format
+			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples
+			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp
+			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
+			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp
+			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp
+			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout
+		),
+	};
+
+	std::vector<AttachmentRef> colorAttachmentRefs
+	{
+		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
+	};
+
+	std::vector<SubpassDesc>	subpassDescriptions =
+	{
+		{
+			DE_NULL,
+			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
+			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
+			0u,													// deUint32							viewMask
+			0u,													// deUint32							inputAttachmentCount
+			DE_NULL,											// const VkAttachmentReference*		pInputAttachments
+			static_cast<deUint32>(colorAttachmentRefs.size()),	// deUint32							colorAttachmentCount
+			colorAttachmentRefs.data(),							// const VkAttachmentReference*		pColorAttachments
+			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments
+			DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment
+			0u,													// deUint32							preserveAttachmentCount
+			DE_NULL												// const deUint32*					pPreserveAttachments
+		}
+	};
+
+	const RenderPassCreateInfo	renderPassInfo(
+		DE_NULL,												// const void*						pNext
+		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
+		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount
+		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
+		static_cast<deUint32>(subpassDescriptions.size()),		// deUint32							subpassCount
+		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
+		0,														// deUint32							dependencyCount
+		DE_NULL,												// const VkSubpassDependency*		pDependencies
+		0u,														// deUint32							correlatedViewMaskCount
+		DE_NULL													// const deUint32*					pCorrelatedViewMasks
+	);
+
+	return renderPassInfo.createRenderPass(vk, vkDevice);
+}
+
+Move<VkFramebuffer> createFrameBuffer( const DeviceInterface& vk, VkDevice vkDevice, VkRenderPass renderPass, const tcu::UVec2& renderSize, const std::vector<VkImageView>& imageViews)
+{
+	const VkFramebufferCreateInfo	framebufferParams =
+	{
+		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
+		DE_NULL,									// const void*				pNext;
+		0u,											// VkFramebufferCreateFlags	flags;
+		renderPass,									// VkRenderPass				renderPass;
+		static_cast<deUint32>(imageViews.size()),	// deUint32					attachmentCount;
+		imageViews.data(),							// const VkImageView*		pAttachments;
+		renderSize.x(),								// deUint32					width;
+		renderSize.y(),								// deUint32					height;
+		1u											// deUint32					layers;
+	};
+
+	return createFramebuffer(vk, vkDevice, &framebufferParams);
+}
+
+class FragmentDensityMapTest : public vkt::TestCase
+{
+public:
+										FragmentDensityMapTest	(tcu::TestContext&	testContext,
+																 const std::string&	name,
+																 const std::string&	description,
+																 const TestParams&	testParams);
+	virtual void						initPrograms			(SourceCollections&	sourceCollections) const;
+	virtual TestInstance*				createInstance			(Context&			context) const;
+	virtual void						checkSupport			(Context& context) const;
+
+private:
+	const TestParams					m_testParams;
+};
+
+class FragmentDensityMapTestInstance : public vkt::TestInstance
+{
+public:
+													FragmentDensityMapTestInstance	(Context&				context,
+																					 const TestParams&		testParams);
+	virtual tcu::TestStatus							iterate							(void);
+private:
+	tcu::TestStatus									verifyImage						(void);
+
+	TestParams										m_testParams;
+	const tcu::UVec2								m_renderSize;
+	const tcu::UVec2								m_densityMapSize;
+
+	VkPhysicalDeviceFragmentDensityMapPropertiesEXT	m_fragmentDensityMapProperties;
+
+	Move<VkCommandPool>								m_cmdPool;
+
+	Move<VkImage>									m_densityMapImage;
+	de::MovePtr<Allocation>							m_densityMapImageAlloc;
+	Move<VkImageView>								m_densityMapImageView;
+
+	Move<VkImage>									m_colorImage;
+	de::MovePtr<Allocation>							m_colorImageAlloc;
+	Move<VkImageView>								m_colorImageView;
+
+	Move<VkImage>									m_outputImage;
+	de::MovePtr<Allocation>							m_outputImageAlloc;
+	Move<VkImageView>								m_outputImageView;
+
+	Move<VkSampler>									m_colorSampler;
+
+	Move<VkRenderPass>								m_renderPassProduceDynamicDensityMap;
+	Move<VkRenderPass>								m_renderPassProduceSubsampledImage;
+	Move<VkRenderPass>								m_renderPassOutputSubsampledImage;
+	Move<VkFramebuffer>								m_framebufferProduceDynamicDensityMap;
+	Move<VkFramebuffer>								m_framebufferProduceSubsampledImage;
+	Move<VkFramebuffer>								m_framebufferOutputSubsampledImage;
+
+	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutProduceSubsampled;
+	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutOutputSubsampledImage;
+	Move<VkDescriptorPool>							m_descriptorPoolOutputSubsampledImage;
+	Move<VkDescriptorSet>							m_descriptorSetOutputSubsampledImage;
+
+	Move<VkShaderModule>							m_vertexCommonShaderModule;
+	Move<VkShaderModule>							m_fragmentShaderModuleProduceSubsampledImage;
+	Move<VkShaderModule>							m_fragmentShaderModuleOutputSubsampledImage;
+
+	Move<VkBuffer>									m_vertexBuffer;
+	std::vector<Vertex4RGBA>						m_vertices;
+	de::MovePtr<Allocation>							m_vertexBufferAlloc;
+
+	Move<VkBuffer>									m_vertexBufferDDM;
+	std::vector<Vertex4RGBA>						m_verticesDDM;
+	de::MovePtr<Allocation>							m_vertexBufferAllocDDM;
+
+	Move<VkPipelineLayout>							m_pipelineLayoutProduceSubsampledImage;
+	Move<VkPipelineLayout>							m_pipelineLayoutOutputSubsampledImage;
+	Move<VkPipeline>								m_graphicsPipelineProduceDynamicDensityMap;
+	Move<VkPipeline>								m_graphicsPipelineProduceSubsampledImage;
+	Move<VkPipeline>								m_graphicsPipelineOutputSubsampledImage;
+
+	Move<VkCommandBuffer>							m_cmdBuffer;
+};
+
+FragmentDensityMapTest::FragmentDensityMapTest (tcu::TestContext&	testContext,
+												const std::string&	name,
+												const std::string&	description,
+												const TestParams&	testParams)
+	: vkt::TestCase	(testContext, name, description)
+	, m_testParams	(testParams)
+{
+}
+
+void FragmentDensityMapTest::initPrograms(SourceCollections& sourceCollections) const
+{
+	std::ostringstream densityVertexGLSL;
+	densityVertexGLSL <<
+		"#version 450\n"
+		"layout(location = 0) in  vec4 inPosition;\n"
+		"layout(location = 1) in  vec4 inColor;\n"
+		"layout(location = 0) out vec4 outColor;\n"
+		"layout(location = 1) out vec2 outUV;\n"
+		"void main(void)\n"
+		"{\n"
+		"	gl_Position = inPosition;\n"
+		"	outColor = inColor;\n"
+		"	outUV = 0.5 * inPosition.xy + vec2(0.5);\n"
+		"}\n";
+	sourceCollections.glslSources.add("densitymap_vert") << glu::VertexSource(densityVertexGLSL.str());
+
+	std::ostringstream densityFragmentProduceGLSL;
+	densityFragmentProduceGLSL <<
+		"#version 450\n"
+		"#extension GL_EXT_fragment_invocation_density : enable\n"
+		"layout(location = 0) in  vec4 inColor;\n"
+		"layout(location = 1) in  vec2 inUV;\n"
+		"layout(location = 0) out vec4 fragColor;\n"
+		"void main(void)\n"
+		"{\n"
+		"	fragColor = vec4(inColor.x, inColor.y, 1.0/float(gl_FragSizeEXT.x), 1.0/(gl_FragSizeEXT.y));\n"
+		"}\n";
+	sourceCollections.glslSources.add("densitymap_frag_produce") << glu::FragmentSource(densityFragmentProduceGLSL.str());
+
+	std::ostringstream densityFragmentOutputGLSL;
+	densityFragmentOutputGLSL <<
+		"#version 450\n"
+		"layout(location = 0) in vec4 inColor;\n"
+		"layout(location = 1) in vec2 inUV;\n"
+		"layout(binding = 0)  uniform sampler2D subsampledImage;\n"
+		"layout(location = 0) out vec4 fragColor;\n"
+		"void main(void)\n"
+		"{\n"
+		"	fragColor = texture(subsampledImage, inUV);\n"
+		"}\n";
+	sourceCollections.glslSources.add("densitymap_frag_output") << glu::FragmentSource(densityFragmentOutputGLSL.str());
+}
+
+TestInstance* FragmentDensityMapTest::createInstance(Context& context) const
+{
+	return new FragmentDensityMapTestInstance(context, m_testParams);
+}
+
+void FragmentDensityMapTest::checkSupport(Context& context) const
+{
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
+
+	VkPhysicalDeviceFeatures2 features;
+	deMemset(&features, 0, sizeof(VkPhysicalDeviceFeatures2));
+	features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+
+	VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures;
+	deMemset(&fragmentDensityMapFeatures, 0, sizeof(VkPhysicalDeviceFragmentDensityMapFeaturesEXT));
+	fragmentDensityMapFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT;
+	features.pNext						= &fragmentDensityMapFeatures;
+
+	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features);
+
+	if (!fragmentDensityMapFeatures.fragmentDensityMap)
+		TCU_THROW(NotSupportedError, "fragmentDensityMap feature is not supported");
+	if (m_testParams.dynamicDensityMap && !fragmentDensityMapFeatures.fragmentDensityMapDynamic)
+		TCU_THROW(NotSupportedError, "fragmentDensityMapDynamic feature is not supported");
+	if (m_testParams.nonSubsampledImages && !fragmentDensityMapFeatures.fragmentDensityMapNonSubsampledImages)
+		TCU_THROW(NotSupportedError, "fragmentDensityMapNonSubsampledImages feature is not supported");
+#else
+	DE_UNREF(context);
+#endif
+}
+
+FragmentDensityMapTestInstance::FragmentDensityMapTestInstance(Context&			context,
+															const TestParams&	testParams)
+	: vkt::TestInstance	( context )
+	, m_testParams		( testParams )
+	, m_renderSize		( 32u, 32u )
+	, m_densityMapSize	( 16u, 16u )
+	, m_vertices		( createFullscreenQuadRG() )
+	, m_verticesDDM		( createFullscreenQuadDensity(1.0f / static_cast<float>(testParams.fragmentArea.x()), 1.0f / static_cast<float>(testParams.fragmentArea.y())) )
+{
+	const DeviceInterface&		vk						= m_context.getDeviceInterface();
+	const VkDevice				vkDevice				= m_context.getDevice();
+	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
+	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	{
+		VkPhysicalDeviceProperties2 properties;
+		deMemset(&properties, 0, sizeof(VkPhysicalDeviceProperties2));
+		properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+
+		deMemset(&m_fragmentDensityMapProperties, 0, sizeof(VkPhysicalDeviceFragmentDensityMapPropertiesEXT));
+		m_fragmentDensityMapProperties.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT;
+		properties.pNext						= &m_fragmentDensityMapProperties;
+
+		context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
+	}
+#else
+	{
+		m_fragmentDensityMapProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT;
+		m_fragmentDensityMapProperties.minFragmentDensityTexelSize.width	= 1u;
+		m_fragmentDensityMapProperties.maxFragmentDensityTexelSize.width	= 1u;
+		m_fragmentDensityMapProperties.minFragmentDensityTexelSize.height	= 1u;
+		m_fragmentDensityMapProperties.maxFragmentDensityTexelSize.height	= 1u;
+		m_fragmentDensityMapProperties.fragmentDensityInvocations			= DE_FALSE;
+		m_testParams.fragmentArea.x()										= 1u;
+		m_testParams.fragmentArea.y()										= 1u;
+	}
+#endif
+
+	// Create density map image
+	{
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+		vk::VkImageUsageFlags densityMapImageUsage = m_testParams.dynamicDensityMap ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT : VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
+#else
+		vk::VkImageUsageFlags densityMapImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+#endif
+		const VkImageCreateInfo	densityMapImageParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
+			DE_NULL,																		// const void*				pNext;
+			0u,																				// VkImageCreateFlags		flags;
+			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
+			m_testParams.densityMapFormat,													// VkFormat					format;
+			{ m_densityMapSize.x(), m_densityMapSize.y(), 1u },								// VkExtent3D				extent;
+			1u,																				// deUint32					mipLevels;
+			1u,																				// deUint32					arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
+			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
+			densityMapImageUsage,															// VkImageUsageFlags		usage;
+			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
+			1u,																				// deUint32					queueFamilyIndexCount;
+			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
+		};
+
+		m_densityMapImage = createImage(vk, vkDevice, &densityMapImageParams);
+
+		// Allocate and bind density map image memory
+		VkMemoryRequirements			memoryRequirements = getImageMemoryRequirements(vk, vkDevice, *m_densityMapImage);
+
+		m_densityMapImageAlloc = memAlloc.allocate(memoryRequirements, MemoryRequirement::Any);
+		VK_CHECK(vk.bindImageMemory(vkDevice, *m_densityMapImage, m_densityMapImageAlloc->getMemory(), m_densityMapImageAlloc->getOffset()));
+
+		// create and fill staging buffer, copy its data to density map image
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+		tcu::TextureFormat	densityMapTextureFormat = vk::mapVkFormat(m_testParams.densityMapFormat);
+
+		if ( !m_testParams.dynamicDensityMap )
+		{
+			VkDeviceSize stagingBufferSize = tcu::getPixelSize(densityMapTextureFormat) * m_densityMapSize.x() * m_densityMapSize.y() * 1;
+			const vk::VkBufferCreateInfo	stagingBufferCreateInfo =
+			{
+				vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+				DE_NULL,
+				0u,									// flags
+				stagingBufferSize,					// size
+				VK_BUFFER_USAGE_TRANSFER_SRC_BIT,	// usage
+				vk::VK_SHARING_MODE_EXCLUSIVE,		// sharingMode
+				0u,									// queueFamilyCount
+				DE_NULL,							// pQueueFamilyIndices
+			};
+			vk::Move<vk::VkBuffer>			stagingBuffer		= vk::createBuffer(vk, vkDevice, &stagingBufferCreateInfo);
+			const vk::VkMemoryRequirements	stagingRequirements = vk::getBufferMemoryRequirements(vk, vkDevice, *stagingBuffer);
+			de::MovePtr<vk::Allocation>		stagingAllocation	= memAlloc.allocate(stagingRequirements, MemoryRequirement::HostVisible);
+			VK_CHECK(vk.bindBufferMemory(vkDevice, *stagingBuffer, stagingAllocation->getMemory(), stagingAllocation->getOffset()));
+			tcu::PixelBufferAccess			stagingBufferAccess	= tcu::PixelBufferAccess(densityMapTextureFormat, m_densityMapSize.x(), m_densityMapSize.y(), 1, stagingAllocation->getHostPtr());
+
+			tcu::Vec4 fragmentArea { 1.0f / static_cast<float>(testParams.fragmentArea.x()), 1.0f / static_cast<float>(testParams.fragmentArea.y()), 0.0f, 1.0f };
+			for (int y = 0; y < stagingBufferAccess.getHeight(); y++)
+				for (int x = 0; x < stagingBufferAccess.getWidth(); x++)
+					stagingBufferAccess.setPixel(fragmentArea, x, y);
+			flushAlloc(vk, vkDevice, *stagingAllocation);
+
+			std::vector<VkBufferImageCopy> copyRegions =
+			{
+				{
+					0,													// VkDeviceSize					bufferOffset
+					0,													// deUint32						bufferRowLength
+					0,													// deUint32						bufferImageHeight
+					{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 },				// VkImageSubresourceLayers		imageSubresource
+					{ 0, 0, 0 },										// VkOffset3D					imageOffset
+					{ m_densityMapSize.x(), m_densityMapSize.y(), 1u }	// VkExtent3D					imageExtent
+				}
+			};
+
+			vk::copyBufferToImage
+			(
+				vk,
+				vkDevice,
+				m_context.getUniversalQueue(),
+				queueFamilyIndex,
+				*stagingBuffer,
+				stagingBufferSize,
+				copyRegions,
+				DE_NULL,
+				VK_IMAGE_ASPECT_COLOR_BIT,
+				1,
+				1,
+				*m_densityMapImage,
+				VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,
+				VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
+			);
+		}
+#endif
+
+		//create image view for fragment density map
+		deUint32 densityMapImageViewCreateFlags = m_testParams.dynamicDensityMap ? (deUint32)VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT : 0u;
+		const VkImageViewCreateInfo densityMapImageViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,							// VkStructureType			sType;
+			DE_NULL,															// const void*				pNext;
+			(VkImageViewCreateFlags)densityMapImageViewCreateFlags,				// VkImageViewCreateFlags	flags;
+			*m_densityMapImage,													// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,												// VkImageViewType			viewType;
+			m_testParams.densityMapFormat,										// VkFormat					format;
+			componentMappingRGBA,												// VkChannelMapping			channels;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }						// VkImageSubresourceRange	subresourceRange;
+		};
+
+		m_densityMapImageView = createImageView(vk, vkDevice, &densityMapImageViewParams);
+	}
+
+	// Create subsampled color image
+	{
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	deUint32 colorImageCreateFlags = m_testParams.nonSubsampledImages ? 0u : (deUint32)VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
+#else
+	deUint32 colorImageCreateFlags = 0u;
+#endif
+		const VkImageCreateInfo	colorImageParams
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType			sType;
+			DE_NULL,															// const void*				pNext;
+			(VkImageCreateFlags)colorImageCreateFlags,							// VkImageCreateFlags		flags;
+			VK_IMAGE_TYPE_2D,													// VkImageType				imageType;
+			VK_FORMAT_R8G8B8A8_UNORM,											// VkFormat					format;
+			{ m_renderSize.x(), m_renderSize.y(), 1u },							// VkExtent3D				extent;
+			1u,																	// deUint32					mipLevels;
+			1u,																	// deUint32					arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits	samples;
+			VK_IMAGE_TILING_OPTIMAL,											// VkImageTiling			tiling;
+			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,	// VkImageUsageFlags		usage;
+			VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode			sharingMode;
+			1u,																	// deUint32					queueFamilyIndexCount;
+			&queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED											// VkImageLayout			initialLayout;
+		};
+
+		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
+
+		// Allocate and bind color image memory
+		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
+		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
+
+		// create image view for subsampled image
+		const VkImageViewCreateInfo colorImageViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
+			DE_NULL,											// const void*				pNext;
+			0u,													// VkImageViewCreateFlags	flags;
+			*m_colorImage,										// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
+			VK_FORMAT_R8G8B8A8_UNORM,							// VkFormat					format;
+			componentMappingRGBA,								// VkChannelMapping			channels;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
+		};
+
+		m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
+	}
+
+	// Create output image ( data from subsampled color image will be copied into it using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT )
+	{
+		const VkImageCreateInfo	outputImageParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
+			DE_NULL,																// const void*				pNext;
+			0u,																		// VkImageCreateFlags		flags;
+			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
+			VK_FORMAT_R8G8B8A8_UNORM,												// VkFormat					format;
+			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
+			1u,																		// deUint32					mipLevels;
+			1u,																		// deUint32					arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
+			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
+			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
+			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
+			1u,																		// deUint32					queueFamilyIndexCount;
+			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
+		};
+
+		m_outputImage = createImage(vk, vkDevice, &outputImageParams);
+
+		// Allocate and bind input image memory
+		m_outputImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_outputImage), MemoryRequirement::Any);
+		VK_CHECK(vk.bindImageMemory(vkDevice, *m_outputImage, m_outputImageAlloc->getMemory(), m_outputImageAlloc->getOffset()));
+
+		// create image view for output image
+		const VkImageViewCreateInfo outputImageViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+			DE_NULL,										// const void*				pNext;
+			0u,												// VkImageViewCreateFlags	flags;
+			*m_outputImage,									// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
+			VK_FORMAT_R8G8B8A8_UNORM,						// VkFormat					format;
+			componentMappingRGBA,							// VkChannelMapping			channels;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
+		};
+
+		m_outputImageView = createImageView(vk, vkDevice, &outputImageViewParams);
+	}
+
+	// create a sampler that is able to read from subsampled image
+	{
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+		deUint32 samplerCreateFlags = (deUint32)VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT;
+#else
+		deUint32 samplerCreateFlags = 0u;
+#endif
+		const struct VkSamplerCreateInfo		samplerInfo
+		{
+			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			// sType
+			DE_NULL,										// pNext
+			(VkSamplerCreateFlags)samplerCreateFlags,		// flags
+			VK_FILTER_NEAREST,								// magFilter
+			VK_FILTER_NEAREST,								// minFilter
+			VK_SAMPLER_MIPMAP_MODE_NEAREST,					// mipmapMode
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeU
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeV
+			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeW
+			0.0f,											// mipLodBias
+			VK_FALSE,										// anisotropyEnable
+			1.0f,											// maxAnisotropy
+			DE_FALSE,										// compareEnable
+			VK_COMPARE_OP_ALWAYS,							// compareOp
+			0.0f,											// minLod
+			0.0f,											// maxLod
+			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		// borderColor
+			VK_FALSE,										// unnormalizedCoords
+		};
+		m_colorSampler = createSampler(vk, vkDevice, &samplerInfo);
+	}
+
+	// Create render passes
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	if ( testParams.dynamicDensityMap )
+#endif
+		m_renderPassProduceDynamicDensityMap	= createRenderPassProduceDynamicDensityMap<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
+	m_renderPassProduceSubsampledImage		= createRenderPassProduceSubsampledImage<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
+	m_renderPassOutputSubsampledImage		= createRenderPassOutputSubsampledImage<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
+
+	// Create framebuffers
+#if  !DRY_RUN_WITHOUT_FDM_EXTENSION
+	if ( testParams.dynamicDensityMap )
+#endif
+		m_framebufferProduceDynamicDensityMap = createFrameBuffer(vk, vkDevice, *m_renderPassProduceDynamicDensityMap, m_densityMapSize, { *m_densityMapImageView });
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	m_framebufferProduceSubsampledImage = createFrameBuffer(vk, vkDevice, *m_renderPassProduceSubsampledImage, m_renderSize, { *m_colorImageView, *m_densityMapImageView });
+#else
+	m_framebufferProduceSubsampledImage = createFrameBuffer(vk, vkDevice, *m_renderPassProduceSubsampledImage, m_renderSize, { *m_colorImageView });
+#endif
+	m_framebufferOutputSubsampledImage	= createFrameBuffer( vk, vkDevice, *m_renderPassOutputSubsampledImage, m_renderSize, { *m_outputImageView } );
+
+	// Create pipeline layout for first two render passes that do not use any descriptors
+	{
+		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
+			DE_NULL,										// const void*					pNext;
+			0u,												// VkPipelineLayoutCreateFlags	flags;
+			0u,												// deUint32						setLayoutCount;
+			DE_NULL,										// const VkDescriptorSetLayout*	pSetLayouts;
+			0u,												// deUint32						pushConstantRangeCount;
+			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges;
+		};
+
+		m_pipelineLayoutProduceSubsampledImage = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+	}
+
+	// Create pipeline layout for last render pass ( output subsampled image )
+	{
+		std::vector<VkDescriptorSetLayoutBinding>	descriptorSetLayoutBindings =
+		{
+			{
+				0,											// deUint32				binding;
+				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType;
+				1,											// deUint32				descriptorCount;
+				VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags;
+				&(m_colorSampler.get())						// const VkSampler*		pImmutableSamplers;
+			},
+		};
+
+		const VkDescriptorSetLayoutCreateInfo		descriptorSetLayoutParams	=
+		{
+			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
+			DE_NULL,													// const void*							pNext
+			0u,															// VkDescriptorSetLayoutCreateFlags		flags
+			static_cast<deUint32>(descriptorSetLayoutBindings.size()),	// deUint32								bindingCount
+			descriptorSetLayoutBindings.data()							// const VkDescriptorSetLayoutBinding*	pBindings
+		};
+		m_descriptorSetLayoutOutputSubsampledImage = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
+
+		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
+			DE_NULL,											// const void*					pNext;
+			0u,													// VkPipelineLayoutCreateFlags	flags;
+			1u,													// deUint32						setLayoutCount;
+			&m_descriptorSetLayoutOutputSubsampledImage.get(),	// const VkDescriptorSetLayout*	pSetLayouts;
+			0u,													// deUint32						pushConstantRangeCount;
+			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
+		};
+		m_pipelineLayoutOutputSubsampledImage = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+	}
+
+	// Update descriptor set
+	{
+		{
+			std::vector<VkDescriptorPoolSize> poolSizes =
+			{
+				{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u }
+			};
+
+			const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo =
+			{
+				VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
+				DE_NULL,											// const void*					pNext
+				VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
+				1u,													// deUint32						maxSets
+				static_cast<deUint32>(poolSizes.size()),			// deUint32						poolSizeCount
+				poolSizes.data()									// const VkDescriptorPoolSize*	pPoolSizes
+			};
+			m_descriptorPoolOutputSubsampledImage = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
+		}
+
+		{
+			const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo =
+			{
+				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType
+				DE_NULL,											// const void*					pNext
+				*m_descriptorPoolOutputSubsampledImage,				// VkDescriptorPool				descriptorPool
+				1u,													// deUint32						descriptorSetCount
+				&m_descriptorSetLayoutOutputSubsampledImage.get(),	// const VkDescriptorSetLayout*	pSetLayouts
+			};
+			m_descriptorSetOutputSubsampledImage = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
+
+			const VkDescriptorImageInfo			inputImageInfo =
+			{
+				DE_NULL,											// VkSampleri		sampler;
+				*m_colorImageView,									// VkImageView		imageView;
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	imageLayout;
+			};
+
+			std::vector<VkWriteDescriptorSet>	descriptorWrite =
+			{
+				{
+					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
+					DE_NULL,										// const void*						pNext;
+					*m_descriptorSetOutputSubsampledImage,			// VkDescriptorSet					dstSet;
+					0u,												// deUint32							dstBinding;
+					0u,												// deUint32							dstArrayElement;
+					1u,												// deUint32							descriptorCount;
+					VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,		// VkDescriptorType					descriptorType;
+					&inputImageInfo,								// const VkDescriptorImageInfo*		pImageInfo;
+					DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
+					DE_NULL											// const VkBufferView*				pTexelBufferView;
+				}
+			};
+			vk.updateDescriptorSets(vkDevice, static_cast<deUint32>(descriptorWrite.size()), descriptorWrite.data(), 0u, DE_NULL);
+		}
+	}
+
+	m_vertexCommonShaderModule						= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("densitymap_vert"), 0);
+	m_fragmentShaderModuleProduceSubsampledImage	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("densitymap_frag_produce"), 0);
+	m_fragmentShaderModuleOutputSubsampledImage		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("densitymap_frag_output"), 0);
+
+	// Create pipelines
+	{
+		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
+		{
+			0u,																// deUint32					binding;
+			sizeof(Vertex4RGBA),											// deUint32					strideInBytes;
+			VK_VERTEX_INPUT_RATE_VERTEX										// VkVertexInputStepRate	inputRate;
+		};
+
+		std::vector<VkVertexInputAttributeDescription>	vertexInputAttributeDescriptions	=
+		{
+			{ 0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
+			{ 1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(sizeof(float) * 4) }
+		};
+
+		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+			DE_NULL,														// const void*								pNext;
+			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
+			1u,																// deUint32									vertexBindingDescriptionCount;
+			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+			static_cast<deUint32>(vertexInputAttributeDescriptions.size()),	// deUint32									vertexAttributeDescriptionCount;
+			vertexInputAttributeDescriptions.data()							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+		};
+
+		const std::vector<VkViewport>				viewportsDDM						{ makeViewport(m_densityMapSize) };
+		const std::vector<VkRect2D>					scissorsDDM							{ makeRect2D(m_densityMapSize) };
+		const std::vector<VkViewport>				viewports							{ makeViewport(m_renderSize) };
+		const std::vector<VkRect2D>					scissors							{ makeRect2D(m_renderSize) };
+
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+		if (testParams.dynamicDensityMap)
+#endif
+			m_graphicsPipelineProduceDynamicDensityMap = makeGraphicsPipeline(vk,							// const DeviceInterface&						vk
+															vkDevice,										// const VkDevice								device
+															*m_pipelineLayoutProduceSubsampledImage,		// const VkPipelineLayout						pipelineLayout
+															*m_vertexCommonShaderModule,					// const VkShaderModule							vertexShaderModule
+															DE_NULL,										// const VkShaderModule							tessellationControlModule
+															DE_NULL,										// const VkShaderModule							tessellationEvalModule
+															DE_NULL,										// const VkShaderModule							geometryShaderModule
+															*m_fragmentShaderModuleProduceSubsampledImage,	// const VkShaderModule							fragmentShaderModule
+															*m_renderPassProduceDynamicDensityMap,			// const VkRenderPass							renderPass
+															viewportsDDM,									// const std::vector<VkViewport>&				viewports
+															scissorsDDM,									// const std::vector<VkRect2D>&					scissors
+															VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,			// const VkPrimitiveTopology					topology
+															0u,												// const deUint32								subpass
+															0u,												// const deUint32								patchControlPoints
+															&vertexInputStateParams);						// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
+
+		m_graphicsPipelineProduceSubsampledImage = makeGraphicsPipeline(vk,									// const DeviceInterface&						vk
+															vkDevice,										// const VkDevice								device
+															*m_pipelineLayoutProduceSubsampledImage,		// const VkPipelineLayout						pipelineLayout
+															*m_vertexCommonShaderModule,					// const VkShaderModule							vertexShaderModule
+															DE_NULL,										// const VkShaderModule							tessellationControlModule
+															DE_NULL,										// const VkShaderModule							tessellationEvalModule
+															DE_NULL,										// const VkShaderModule							geometryShaderModule
+															*m_fragmentShaderModuleProduceSubsampledImage,	// const VkShaderModule							fragmentShaderModule
+															*m_renderPassProduceSubsampledImage,			// const VkRenderPass							renderPass
+															viewports,										// const std::vector<VkViewport>&				viewports
+															scissors,										// const std::vector<VkRect2D>&					scissors
+															VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,			// const VkPrimitiveTopology					topology
+															0u,												// const deUint32								subpass
+															0u,												// const deUint32								patchControlPoints
+															&vertexInputStateParams);						// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
+
+		m_graphicsPipelineOutputSubsampledImage = makeGraphicsPipeline(vk,									// const DeviceInterface&						vk
+															vkDevice,										// const VkDevice								device
+															*m_pipelineLayoutOutputSubsampledImage,			// const VkPipelineLayout						pipelineLayout
+															*m_vertexCommonShaderModule,					// const VkShaderModule							vertexShaderModule
+															DE_NULL,										// const VkShaderModule							tessellationControlModule
+															DE_NULL,										// const VkShaderModule							tessellationEvalModule
+															DE_NULL,										// const VkShaderModule							geometryShaderModule
+															*m_fragmentShaderModuleOutputSubsampledImage,	// const VkShaderModule							fragmentShaderModule
+															*m_renderPassOutputSubsampledImage,				// const VkRenderPass							renderPass
+															viewports,										// const std::vector<VkViewport>&				viewports
+															scissors,										// const std::vector<VkRect2D>&					scissors
+															VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,			// const VkPrimitiveTopology					topology
+															0u,												// const deUint32								subpass
+															0u,												// const deUint32								patchControlPoints
+															&vertexInputStateParams);						// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
+	}
+
+	// Create vertex buffers
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	if (testParams.dynamicDensityMap)
+#endif
+		createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_verticesDDM, m_vertexBufferDDM, m_vertexBufferAllocDDM);
+	createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_vertices, m_vertexBuffer, m_vertexBufferAlloc);
+
+	// Create command pool and command buffer
+	m_cmdPool	= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
+	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+	const typename				RenderpassSubpass2::SubpassBeginInfo	subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
+	const typename				RenderpassSubpass2::SubpassEndInfo		subpassEndInfo(DE_NULL);
+	const						VkDeviceSize							vertexBufferOffset = 0;
+	std::vector<VkClearValue>	attachmentClearValuesDDM				= { makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f) };
+	std::vector<VkClearValue>	attachmentClearValues					= { makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f) };
+
+	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
+
+	// first render pass - render dynamic density map
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	if ( testParams.dynamicDensityMap )
+#endif
+	{
+		const VkRenderPassBeginInfo renderPassBeginInfoProduceDynamicDensityMap =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
+			DE_NULL,												// const void*			pNext;
+			*m_renderPassProduceDynamicDensityMap,					// VkRenderPass			renderPass;
+			*m_framebufferProduceDynamicDensityMap,					// VkFramebuffer		framebuffer;
+			makeRect2D(m_densityMapSize),							// VkRect2D				renderArea;
+			static_cast<deUint32>(attachmentClearValuesDDM.size()),	// uint32_t				clearValueCount;
+			attachmentClearValuesDDM.data()							// const VkClearValue*	pClearValues;
+		};
+		RenderpassSubpass2::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfoProduceDynamicDensityMap, &subpassBeginInfo);
+		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceDynamicDensityMap);
+		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBufferDDM.get(), &vertexBufferOffset);
+		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_verticesDDM.size(), 1, 0, 0);
+		RenderpassSubpass2::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
+	}
+
+	// render subsampled image
+	const VkRenderPassBeginInfo renderPassBeginInfoProduceSubsampledImage =
+	{
+		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
+		DE_NULL,												// const void*			pNext;
+		*m_renderPassProduceSubsampledImage,					// VkRenderPass			renderPass;
+		*m_framebufferProduceSubsampledImage,					// VkFramebuffer		framebuffer;
+		makeRect2D(m_renderSize),								// VkRect2D				renderArea;
+		static_cast<deUint32>(attachmentClearValues.size()),	// uint32_t				clearValueCount;
+		attachmentClearValues.data()							// const VkClearValue*	pClearValues;
+	};
+	RenderpassSubpass2::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfoProduceSubsampledImage, &subpassBeginInfo);
+	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceSubsampledImage);
+	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
+	vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
+	RenderpassSubpass2::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
+
+	// copy subsampled image to ordinary image using sampler that is able to read from subsampled images( subsampled image cannot be copied using vkCmdCopyImageToBuffer )
+	const VkRenderPassBeginInfo renderPassBeginInfoOutputSubsampledImage =
+	{
+		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
+		DE_NULL,												// const void*			pNext;
+		*m_renderPassOutputSubsampledImage,						// VkRenderPass			renderPass;
+		*m_framebufferOutputSubsampledImage,					// VkFramebuffer		framebuffer;
+		makeRect2D(m_renderSize),								// VkRect2D				renderArea;
+		static_cast<deUint32>(attachmentClearValues.size()),	// uint32_t				clearValueCount;
+		attachmentClearValues.data()							// const VkClearValue*	pClearValues;
+	};
+	RenderpassSubpass2::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfoOutputSubsampledImage, &subpassBeginInfo);
+	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineOutputSubsampledImage);
+	vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOutputSubsampledImage, 0, 1, &m_descriptorSetOutputSubsampledImage.get(), 0, DE_NULL);
+	vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
+	RenderpassSubpass2::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
+
+	endCommandBuffer(vk, *m_cmdBuffer);
+}
+
+tcu::TestStatus FragmentDensityMapTestInstance::iterate (void)
+{
+	const DeviceInterface&		vk			= m_context.getDeviceInterface();
+	const VkDevice				vkDevice	= m_context.getDevice();
+	const VkQueue				queue		= m_context.getUniversalQueue();
+
+	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
+
+	return verifyImage();
+}
+
+struct Vec4Sorter
+{
+	bool operator()(const tcu::Vec4& lhs, const tcu::Vec4& rhs) const
+	{
+		if (lhs.x() != rhs.x())
+			return lhs.x() < rhs.x();
+		if (lhs.y() != rhs.y())
+			return lhs.y() < rhs.y();
+		if (lhs.z() != rhs.z())
+			return lhs.z() < rhs.z();
+		return lhs.w() < rhs.w();
+	}
+};
+
+tcu::TestStatus FragmentDensityMapTestInstance::verifyImage (void)
+{
+	const DeviceInterface&				vk						= m_context.getDeviceInterface();
+	const VkDevice						vkDevice				= m_context.getDevice();
+	const VkQueue						queue					= m_context.getUniversalQueue();
+	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
+	SimpleAllocator						memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+	de::UniquePtr<tcu::TextureLevel>	outputImage				(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_outputImage, VK_FORMAT_R8G8B8A8_UNORM, m_renderSize).release());
+	const tcu::ConstPixelBufferAccess&	outputAccess			= outputImage->getAccess();
+	tcu::TestLog&						log						= m_context.getTestContext().getLog();
+
+	// log images
+	log << tcu::TestLog::ImageSet("Result", "Result images")
+		<< tcu::TestLog::Image("Rendered", "Rendered output image", outputAccess)
+		<< tcu::TestLog::EndImageSet;
+
+#if !DRY_RUN_WITHOUT_FDM_EXTENSION
+	deUint32 estimatedColorCount = m_testParams.fragmentArea.x() * m_testParams.fragmentArea.y();
+#else
+	deUint32 estimatedColorCount = 1u;
+#endif
+	tcu::Vec2 density{
+		1.0f / static_cast<float>(m_testParams.fragmentArea.x()),
+		1.0f / static_cast<float>(m_testParams.fragmentArea.y())
+	};
+	float densityMult = density.x() * density.y();
+
+	// create histogram of all image colors, check the value of inverted FragSizeEXT
+	std::map<tcu::Vec4, deUint32, Vec4Sorter> colorCount;
+	for (int y = 0; y < outputAccess.getHeight(); y++)
+	{
+		for (int x = 0; x < outputAccess.getWidth(); x++)
+		{
+			tcu::Vec4 outputColor	= outputAccess.getPixel(x, y);
+			float densityClamped	= outputColor.z() * outputColor.w();
+			if ((densityClamped + 0.01) < densityMult)
+				return tcu::TestStatus::fail("Wrong value of FragSizeEXT variable");
+			auto it = colorCount.find(outputColor);
+			if (it == end(colorCount))
+				it = colorCount.insert({ outputColor, 0u }).first;
+			it->second++;
+		}
+	}
+
+	// check if color count is the same as estimated one
+	for (const auto& color : colorCount)
+	{
+		if (color.second > estimatedColorCount)
+			return tcu::TestStatus::fail("Wrong color count");
+	}
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createFragmentDensityMapTests (tcu::TestContext& testCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup>		fdmTests		(new tcu::TestCaseGroup(testCtx, "fragment_density_map", "VK_EXT_fragment_density_map extension tests"));
+
+	std::vector<tcu::UVec2> fragmentArea
+	{
+		{ 1, 2 },
+		{ 2, 1 },
+		{ 2, 2 }
+	};
+
+	for (const auto& area : fragmentArea)
+	{
+		std::stringstream str;
+		str << "_" << area.x() << "_" << area.y();
+		fdmTests->addChild(new FragmentDensityMapTest(testCtx, std::string("static_subsampled")		+ str.str(), "", TestParams(false, false, area)));
+		fdmTests->addChild(new FragmentDensityMapTest(testCtx, std::string("dynamic_subsampled")	+ str.str(), "", TestParams(true, false, area)));
+		fdmTests->addChild(new FragmentDensityMapTest(testCtx, std::string("static_nonsubsampled")	+ str.str(), "", TestParams(false, true, area)));
+		fdmTests->addChild(new FragmentDensityMapTest(testCtx, std::string("dynamic_nonsubsampled")	+ str.str(), "", TestParams(true, true, area)));
+	}
+
+	return fdmTests.release();
+}
+
+} // renderpass
+
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.hpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.hpp
new file mode 100644
index 0000000..542247f
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTRENDERPASSFRAGMENTDENSITYMAPTESTS_HPP
+#define _VKTRENDERPASSFRAGMENTDENSITYMAPTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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 Tests fragment density map extension ( VK_EXT_fragment_density_map )
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+#include "vktRenderPassTestsUtil.hpp"
+
+namespace vkt
+{
+namespace renderpass
+{
+
+tcu::TestCaseGroup* createFragmentDensityMapTests (tcu::TestContext& testCtx);
+
+} // renderpass
+} // vkt
+
+#endif // _VKTRENDERPASSFRAGMENTDENSITYMAPTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
index 65a9f6a..28dd49c 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp
@@ -176,9 +176,9 @@
 	VkImageUsageFlags depthUsage	= (separateStencilUsage == TEST_DEPTH)	 ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
 	VkImageUsageFlags stencilUsage	= (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
 
-	const VkImageStencilUsageCreateInfoEXT stencilUsageInfo =
+	const VkImageStencilUsageCreateInfo stencilUsageInfo =
 	{
-		VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT,
+		VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
 		DE_NULL,
 		stencilUsage
 	};
@@ -272,9 +272,9 @@
 
 		if (separateStencilUsage)
 		{
-			const VkImageStencilUsageCreateInfoEXT	stencilUsageInfo =
+			const VkImageStencilUsageCreateInfo	stencilUsageInfo =
 			{
-				VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT,			//	VkStructureType			sType
+				VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,				//	VkStructureType			sType
 				DE_NULL,														//	const void*				pNext
 				stencilUsage													//	VkImageUsageFlags		stencilUsage
 			};
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp
index abbe78c..a23b6f7 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp
@@ -32,6 +32,8 @@
 #include "vktRenderPassUnusedAttachmentTests.hpp"
 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
 #include "vktRenderPassDepthStencilResolveTests.hpp"
+#include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
+#include "vktRenderPassFragmentDensityMapTests.hpp"
 
 #include "vktTestCaseUtil.hpp"
 #include "vktTestGroupUtil.hpp"
@@ -6989,6 +6991,7 @@
 	suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassSparseRenderTargetTests(testCtx)	: createRenderPass2SparseRenderTargetTests(testCtx));
 	suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderPassType));
 	suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, renderPassType));
+	suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderPassType));
 
 	renderpassTests->addChild(suballocationTestGroup.release());
 	renderpassTests->addChild(dedicatedAllocationTestGroup.release());
@@ -6996,6 +6999,7 @@
 	if (renderPassType != RENDERPASS_TYPE_LEGACY)
 	{
 		renderpassTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
+		renderpassTests->addChild(createFragmentDensityMapTests(testCtx));
 	}
 
 	return renderpassTests.release();
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.cpp
index 828d7c4..90d2da6 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.cpp
@@ -72,7 +72,7 @@
 												VkImageLayout					initialLayout_,
 												VkImageLayout					finalLayout_)
 {
-	sType			= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
+	sType			= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
 	pNext			= pNext_;
 	flags			= flags_;
 	format			= format_;
@@ -104,7 +104,7 @@
 											VkImageLayout		layout_,
 											VkImageAspectFlags	aspectMask_)
 {
-	sType		= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+	sType		= VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
 	pNext		= pNext_;
 	attachment	= attachment_;
 	layout		= layout_;
@@ -147,15 +147,15 @@
 										  VkPipelineBindPoint				pipelineBindPoint_,
 										  deUint32							viewMask_,
 										  deUint32							inputAttachmentCount_,
-										  const VkAttachmentReference2KHR*	pInputAttachments_,
+										  const VkAttachmentReference2*		pInputAttachments_,
 										  deUint32							colorAttachmentCount_,
-										  const VkAttachmentReference2KHR*	pColorAttachments_,
-										  const VkAttachmentReference2KHR*	pResolveAttachments_,
-										  const VkAttachmentReference2KHR*	pDepthStencilAttachment_,
+										  const VkAttachmentReference2*		pColorAttachments_,
+										  const VkAttachmentReference2*		pResolveAttachments_,
+										  const VkAttachmentReference2*		pDepthStencilAttachment_,
 										  deUint32							preserveAttachmentCount_,
 										  const deUint32*					pPreserveAttachments_)
 {
-	sType					= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+	sType					= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
 	pNext					= pNext_;
 	flags					= flags_;
 	pipelineBindPoint		= pipelineBindPoint_;
@@ -205,7 +205,7 @@
 										VkDependencyFlags		dependencyFlags_,
 										deInt32					viewOffset_)
 {
-	sType			= VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
+	sType			= VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
 	pNext			= pNext_;
 	srcSubpass		= srcSubpass_;
 	dstSubpass		= dstSubpass_;
@@ -252,15 +252,15 @@
 RenderPassCreateInfo2::RenderPassCreateInfo2 (const void*							pNext_,
 											  VkRenderPassCreateFlags				flags_,
 											  deUint32								attachmentCount_,
-											  const VkAttachmentDescription2KHR*	pAttachments_,
+											  const VkAttachmentDescription2*		pAttachments_,
 											  deUint32								subpassCount_,
-											  const VkSubpassDescription2KHR*		pSubpasses_,
+											  const VkSubpassDescription2*			pSubpasses_,
 											  deUint32								dependencyCount_,
-											  const VkSubpassDependency2KHR*		pDependencies_,
+											  const VkSubpassDependency2*			pDependencies_,
 											  deUint32								correlatedViewMaskCount_,
 											  const deUint32*						pCorrelatedViewMasks_)
 {
-	sType					= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
+	sType					= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
 	pNext					= pNext_;
 	flags					= flags_;
 	attachmentCount			= attachmentCount_;
@@ -275,7 +275,7 @@
 
 Move<VkRenderPass>	RenderPassCreateInfo2::createRenderPass (const DeviceInterface& vk, VkDevice device) const
 {
-	return vk::createRenderPass2KHR(vk, device, this);
+	return vk::createRenderPass2(vk, device, this);
 }
 
 SubpassBeginInfo1::SubpassBeginInfo1 (const void*		pNext_,
@@ -290,7 +290,7 @@
 SubpassBeginInfo2::SubpassBeginInfo2 (const void*		pNext_,
 									  VkSubpassContents	contents_)
 {
-	sType		= VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR;
+	sType		= VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
 	pNext		= pNext_;
 	contents	= contents_;
 }
@@ -304,7 +304,7 @@
 
 SubpassEndInfo2::SubpassEndInfo2 (const void*	pNext_)
 {
-	sType	= VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR;
+	sType	= VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
 	pNext	= pNext_;
 }
 
@@ -343,7 +343,7 @@
 											 const VkRenderPassBeginInfo*	pRenderPassBegin,
 											 const SubpassBeginInfo*		pSubpassBeginInfo)
 {
-	vk.cmdBeginRenderPass2KHR(cmdBuffer, pRenderPassBegin, pSubpassBeginInfo);
+	vk.cmdBeginRenderPass2(cmdBuffer, pRenderPassBegin, pSubpassBeginInfo);
 }
 
 void RenderpassSubpass2::cmdNextSubpass (const DeviceInterface&		vk,
@@ -354,7 +354,7 @@
 	DE_ASSERT(pSubpassBeginInfo != DE_NULL);
 	DE_ASSERT(pSubpassEndInfo != DE_NULL);
 
-	vk.cmdNextSubpass2KHR(cmdBuffer, pSubpassBeginInfo, pSubpassEndInfo);
+	vk.cmdNextSubpass2(cmdBuffer, pSubpassBeginInfo, pSubpassEndInfo);
 }
 
 void RenderpassSubpass2::cmdEndRenderPass (const DeviceInterface&	vk,
@@ -363,7 +363,7 @@
 {
 	DE_ASSERT(pSubpassEndInfo != DE_NULL);
 
-	vk.cmdEndRenderPass2KHR(cmdBuffer, pSubpassEndInfo);
+	vk.cmdEndRenderPass2(cmdBuffer, pSubpassEndInfo);
 }
 
 // For internal to RP/RP2 conversions
@@ -614,7 +614,7 @@
 template <typename AttachmentDesc>
 AttachmentDesc createAttachmentDescription (const Attachment& attachment)
 {
-	const AttachmentDesc attachmentDescription	//  VkAttachmentDescription							||  VkAttachmentDescription2KHR
+	const AttachmentDesc attachmentDescription	//  VkAttachmentDescription							||  VkAttachmentDescription2
 	(
 												//													||  VkStructureType					sType;
 		DE_NULL,								//													||  const void*						pNext;
@@ -635,7 +635,7 @@
 template <typename AttachmentRef>
 AttachmentRef createAttachmentReference (const AttachmentReference& referenceInfo)
 {
-	const AttachmentRef	reference		//  VkAttachmentReference				||  VkAttachmentReference2KHR
+	const AttachmentRef	reference		//  VkAttachmentReference				||  VkAttachmentReference2
 	(
 										//										||  VkStructureType				sType;
 		DE_NULL,						//										||  const void*					pNext;
@@ -674,7 +674,7 @@
 	DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
 
 	{
-		const SubpassDesc subpassDescription														//  VkSubpassDescription										||  VkSubpassDescription2KHR
+		const SubpassDesc subpassDescription														//  VkSubpassDescription										||  VkSubpassDescription2
 		(
 																									//																||  VkStructureType						sType;
 			DE_NULL,																				//																||  const void*							pNext;
@@ -682,11 +682,11 @@
 			subpass.getPipelineBindPoint(),															//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
 			0u,																						//																||  deUint32							viewMask;
 			(deUint32)inputAttachmentReferences.size(),												//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
-			inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],			//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
+			inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],			//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2*		pInputAttachments;
 			(deUint32)colorAttachmentReferences.size(),												//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
-			colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],			//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
-			resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],		//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
-			&depthStencilAttachmentReferences[0],													//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
+			colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],			//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2*		pColorAttachments;
+			resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],		//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2*		pResolveAttachments;
+			&depthStencilAttachmentReferences[0],													//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2*		pDepthStencilAttachment;
 			(deUint32)preserveAttachmentReferences->size(),											//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
 			preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0]	//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
 		);
@@ -698,7 +698,7 @@
 template <typename SubpassDep>
 SubpassDep createSubpassDependency (const SubpassDependency& dependencyInfo)
 {
-	const SubpassDep dependency				//  VkSubpassDependency						||  VkSubpassDependency2KHR
+	const SubpassDep dependency				//  VkSubpassDependency						||  VkSubpassDependency2
 	(
 											//											||	VkStructureType				sType
 		DE_NULL,							//											||	const void*					pNext
@@ -758,17 +758,17 @@
 	for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
 		dependencies.push_back(createSubpassDependency<SubpassDep>(renderPassInfo.getDependencies()[depNdx]));
 
-	const RenderPassCreateInfo	renderPassCreator				//  VkRenderPassCreateInfo								||  VkRenderPassCreateInfo2KHR
+	const RenderPassCreateInfo	renderPassCreator				//  VkRenderPassCreateInfo								||  VkRenderPassCreateInfo2
 	(
 																//  VkStructureType					sType;				||  VkStructureType						sType;
 		inputAspectCreateInfo.get(),							//  const void*						pNext;				||  const void*							pNext;
 		(VkRenderPassCreateFlags)0u,							//  VkRenderPassCreateFlags			flags;				||  VkRenderPassCreateFlags				flags;
 		(deUint32)attachments.size(),							//  deUint32						attachmentCount;	||  deUint32							attachmentCount;
-		(attachments.empty() ? DE_NULL : &attachments[0]),		//  const VkAttachmentDescription*	pAttachments;		||  const VkAttachmentDescription2KHR*	pAttachments;
+		(attachments.empty() ? DE_NULL : &attachments[0]),		//  const VkAttachmentDescription*	pAttachments;		||  const VkAttachmentDescription2*		pAttachments;
 		(deUint32)subpasses.size(),								//  deUint32						subpassCount;		||  deUint32							subpassCount;
-		(subpasses.empty() ? DE_NULL : &subpasses[0]),			//  const VkSubpassDescription*		pSubpasses;			||  const VkSubpassDescription2KHR*		pSubpasses;
+		(subpasses.empty() ? DE_NULL : &subpasses[0]),			//  const VkSubpassDescription*		pSubpasses;			||  const VkSubpassDescription2*		pSubpasses;
 		(deUint32)dependencies.size(),							//  deUint32						dependencyCount;	||  deUint32							dependencyCount;
-		(dependencies.empty() ? DE_NULL : &dependencies[0]),	//  const VkSubpassDependency*		pDependencies;		||  const VkSubpassDependency2KHR*		pDependencies;
+		(dependencies.empty() ? DE_NULL : &dependencies[0]),	//  const VkSubpassDependency*		pDependencies;		||  const VkSubpassDependency2*			pDependencies;
 		0u,														//														||  deUint32							correlatedViewMaskCount;
 		DE_NULL													//														||  const deUint32*						pCorrelatedViewMasks;
 	);
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.hpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.hpp
index e2762dd..7ec2510 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.hpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTestsUtil.hpp
@@ -59,7 +59,7 @@
 							 VkImageLayout					finalLayout);
 };
 
-class AttachmentDescription2 : public vk::VkAttachmentDescription2KHR
+class AttachmentDescription2 : public vk::VkAttachmentDescription2
 {
 public:
 	AttachmentDescription2	(const void*					pNext,
@@ -83,7 +83,7 @@
 							 VkImageAspectFlags	aspectMask);
 };
 
-class AttachmentReference2 : public vk::VkAttachmentReference2KHR
+class AttachmentReference2 : public vk::VkAttachmentReference2
 {
 public:
 	AttachmentReference2	(const void*		pNext,
@@ -109,7 +109,7 @@
 						 const deUint32*					pPreserveAttachments);
 };
 
-class SubpassDescription2 : public vk::VkSubpassDescription2KHR
+class SubpassDescription2 : public vk::VkSubpassDescription2
 {
 public:
 	SubpassDescription2	(const void*						pNext,
@@ -117,11 +117,11 @@
 						 VkPipelineBindPoint				pipelineBindPoint,
 						 deUint32							viewMask,
 						 deUint32							inputAttachmentCount,
-						 const VkAttachmentReference2KHR*	pInputAttachments,
+						 const VkAttachmentReference2*		pInputAttachments,
 						 deUint32							colorAttachmentCount,
-						 const VkAttachmentReference2KHR*	pColorAttachments,
-						 const VkAttachmentReference2KHR*	pResolveAttachments,
-						 const VkAttachmentReference2KHR*	pDepthStencilAttachment,
+						 const VkAttachmentReference2*		pColorAttachments,
+						 const VkAttachmentReference2*		pResolveAttachments,
+						 const VkAttachmentReference2*		pDepthStencilAttachment,
 						 deUint32							preserveAttachmentCount,
 						 const deUint32*					pPreserveAttachments);
 };
@@ -140,7 +140,7 @@
 						 deInt32				viewOffset);
 };
 
-class SubpassDependency2 : public vk::VkSubpassDependency2KHR
+class SubpassDependency2 : public vk::VkSubpassDependency2
 {
 public:
 	SubpassDependency2	(const void*			pNext,
@@ -172,17 +172,17 @@
 													 VkDevice device) const;
 };
 
-class RenderPassCreateInfo2 : public VkRenderPassCreateInfo2KHR
+class RenderPassCreateInfo2 : public VkRenderPassCreateInfo2
 {
 public:
 							RenderPassCreateInfo2	(const void*						pNext,
 													 VkRenderPassCreateFlags			flags,
 													 deUint32							attachmentCount,
-													 const VkAttachmentDescription2KHR*	pAttachments,
+													 const VkAttachmentDescription2*	pAttachments,
 													 deUint32							subpassCount,
-													 const VkSubpassDescription2KHR*	pSubpasses,
+													 const VkSubpassDescription2*		pSubpasses,
 													 deUint32							dependencyCount,
-													 const VkSubpassDependency2KHR*		pDependencies,
+													 const VkSubpassDependency2*		pDependencies,
 													 deUint32							correlatedViewMaskCount,
 													 const deUint32*					pCorrelatedViewMasks);
 
@@ -199,7 +199,7 @@
 	VkSubpassContents	contents;
 };
 
-class SubpassBeginInfo2 : public VkSubpassBeginInfoKHR
+class SubpassBeginInfo2 : public VkSubpassBeginInfo
 {
 public:
 						SubpassBeginInfo2	(const void*		pNext,
@@ -212,7 +212,7 @@
 						SubpassEndInfo1	(const void*	pNext);
 };
 
-class SubpassEndInfo2 : public VkSubpassEndInfoKHR
+class SubpassEndInfo2 : public VkSubpassEndInfo
 {
 public:
 						SubpassEndInfo2	(const void*	pNext);
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.cpp
new file mode 100644
index 0000000..51cd1f1
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.cpp
@@ -0,0 +1,803 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2018 Google Inc.
+ * Copyright (c) 2015 Imagination Technologies Ltd.
+ *
+ * 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 Tests sparse input attachments in VkSubpassDescription::pInputAttachments
+ *//*--------------------------------------------------------------------*/
+
+#include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
+#include "vktTestCase.hpp"
+#include "vkImageUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "tcuTestLog.hpp"
+#include "deRandom.hpp"
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <numeric>
+#include <random>
+
+typedef de::SharedPtr<vk::Unique<vk::VkImage> >		VkImageSp;
+typedef de::SharedPtr<vk::Unique<vk::VkImageView> >	VkImageViewSp;
+typedef de::SharedPtr<vk::Unique<vk::VkBuffer> >	VkBufferSp;
+typedef de::SharedPtr<vk::Allocation>				AllocationSp;
+
+namespace vkt
+{
+
+namespace renderpass
+{
+
+using namespace vk;
+
+template<typename T>
+de::SharedPtr<T> safeSharedPtr(T* ptr)
+{
+	try
+	{
+		return de::SharedPtr<T>(ptr);
+	}
+	catch (...)
+	{
+		delete ptr;
+		throw;
+	}
+}
+
+static const deUint32		RENDER_SIZE		= 8u;
+static const unsigned int	DEFAULT_SEED	= 31u;
+
+namespace
+{
+
+struct TestParams
+{
+	RenderPassType		renderPassType;
+	deUint32			activeInputAttachmentCount;
+};
+
+struct Vertex
+{
+	tcu::Vec4 position;
+	tcu::Vec4 uv;
+};
+
+std::vector<Vertex> createFullscreenTriangle (void)
+{
+	std::vector<Vertex>	vertices;
+
+	for (deUint32 i = 0; i < 3; ++i)
+	{
+		float x = static_cast<float>((i << 1) & 2);
+		float y = static_cast<float>(i & 2);
+		vertices.push_back(Vertex{ tcu::Vec4(x * 2.0f - 1.0f, y * 2.0f - 1.0f, 0.0f, 1.0f), tcu::Vec4(x,y,0.0f,0.0f) });
+	}
+	return vertices;
+}
+
+void generateInputAttachmentParams(deUint32 activeAttachmentCount, deUint32 allAttachmentCount, std::vector<deUint32>& attachmentIndices, std::vector<deUint32>& descriptorBindings)
+{
+	attachmentIndices.resize(allAttachmentCount);
+	std::iota(begin(attachmentIndices), begin(attachmentIndices) + activeAttachmentCount, 0);
+	std::fill(begin(attachmentIndices) + activeAttachmentCount, end(attachmentIndices), VK_ATTACHMENT_UNUSED);
+	de::Random random(DEFAULT_SEED);
+	random.shuffle(begin(attachmentIndices), end(attachmentIndices));
+
+	descriptorBindings.resize(activeAttachmentCount+1);
+	descriptorBindings[0] = VK_ATTACHMENT_UNUSED;
+	for (deUint32 i = 0, lastBinding = 1; i < allAttachmentCount; ++i)
+	{
+		if (attachmentIndices[i] != VK_ATTACHMENT_UNUSED)
+			descriptorBindings[lastBinding++] = i;
+	}
+}
+
+class InputAttachmentSparseFillingTest : public vkt::TestCase
+{
+public:
+										InputAttachmentSparseFillingTest	(tcu::TestContext&	testContext,
+																			 const std::string&	name,
+																			 const std::string&	description,
+																			 const TestParams&	testParams);
+	virtual								~InputAttachmentSparseFillingTest	(void);
+	virtual void						initPrograms						(SourceCollections&	sourceCollections) const;
+	virtual TestInstance*				createInstance						(Context&			context) const;
+	virtual void						checkSupport						(Context& context) const;
+
+private:
+	TestParams m_testParams;
+};
+
+class InputAttachmentSparseFillingTestInstance : public vkt::TestInstance
+{
+public:
+										InputAttachmentSparseFillingTestInstance	(Context&			context,
+																					 const TestParams&	testParams);
+	virtual								~InputAttachmentSparseFillingTestInstance	(void);
+	virtual tcu::TestStatus				iterate										(void);
+	template<typename RenderpassSubpass>
+	void								createCommandBuffer							(const DeviceInterface&	vk,
+																					 VkDevice				vkDevice);
+
+	template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
+	Move<VkRenderPass>					createRenderPass							(const DeviceInterface&	vk,
+																					 VkDevice				vkDevice);
+private:
+	tcu::TestStatus						verifyImage									(void);
+
+	const tcu::UVec2					m_renderSize;
+	std::vector<Vertex>					m_vertices;
+	TestParams							m_testParams;
+
+	std::vector<VkImageSp>				m_inputImages;
+	std::vector<AllocationSp>			m_inputImageMemory;
+	std::vector<VkImageViewSp>			m_inputImageViews;
+
+	VkImageSp							m_outputImage;
+	AllocationSp						m_outputImageMemory;
+	VkImageViewSp						m_outputImageView;
+
+	VkBufferSp							m_outputBuffer;
+	AllocationSp						m_outputBufferMemory;
+
+	Move<VkDescriptorSetLayout>			m_descriptorSetLayout;
+	Move<VkDescriptorPool>				m_descriptorPool;
+	Move<VkDescriptorSet>				m_descriptorSet;
+	Move<VkRenderPass>					m_renderPass;
+	Move<VkFramebuffer>					m_framebuffer;
+
+	Move<VkShaderModule>				m_vertexShaderModule;
+	Move<VkShaderModule>				m_fragmentShaderModule;
+
+	Move<VkBuffer>						m_vertexBuffer;
+	de::MovePtr<Allocation>				m_vertexBufferAlloc;
+
+	Move<VkPipelineLayout>				m_pipelineLayout;
+	Move<VkPipeline>					m_graphicsPipeline;
+
+	Move<VkCommandPool>					m_cmdPool;
+	Move<VkCommandBuffer>				m_cmdBuffer;
+};
+
+InputAttachmentSparseFillingTest::InputAttachmentSparseFillingTest (tcu::TestContext&	testContext,
+																	const std::string&	name,
+																	const std::string&	description,
+																	const TestParams&	testParams)
+	: vkt::TestCase	(testContext, name, description), m_testParams(testParams)
+{
+}
+
+InputAttachmentSparseFillingTest::~InputAttachmentSparseFillingTest	(void)
+{
+}
+
+void InputAttachmentSparseFillingTest::initPrograms (SourceCollections& sourceCollections) const
+{
+	std::ostringstream fragmentSource;
+
+	sourceCollections.glslSources.add("vertex") << glu::VertexSource(
+		"#version 450\n"
+		"layout(location = 0) in vec4 position;\n"
+		"layout(location = 1) in vec4 uv;\n"
+		"layout(location = 0) out vec4 outUV;\n"
+		"void main (void)\n"
+		"{\n"
+		"	gl_Position = position;\n"
+		"	outUV = uv;\n"
+		"}\n");
+
+	// We read from X input attachments randomly spread in input attachment array of size 2*X
+	std::ostringstream str;
+	str	<< "#version 450\n"
+		<< "layout(location = 0) in vec4 inUV;\n"
+		<< "layout(binding = 0, rg32ui) uniform uimage2D resultImage;\n";
+
+	std::vector<deUint32> attachmentIndices, descriptorBindings;
+	generateInputAttachmentParams(m_testParams.activeInputAttachmentCount, 2u * m_testParams.activeInputAttachmentCount, attachmentIndices, descriptorBindings);
+
+	for (std::size_t i = 1; i < descriptorBindings.size(); ++i)
+		str << "layout(binding = " << i << ", input_attachment_index = " << descriptorBindings[i] <<") uniform subpassInput attach" << i <<";\n";
+
+	str << "void main (void)\n"
+		<< "{\n"
+		<< "	uvec4 result = uvec4(0);\n";
+
+	for (std::size_t i = 1; i < descriptorBindings.size(); ++i)
+	{
+		str << "	result.x = result.x + 1;\n";
+		str << "	if(subpassLoad(attach" << i << ").x > 0.0)\n";
+		str << "		result.y = result.y + 1;\n";
+	}
+
+	str	<< "	imageStore(resultImage, ivec2(imageSize(resultImage) * inUV.xy), result);\n"
+		<< "}\n";
+
+	sourceCollections.glslSources.add("fragment") << glu::FragmentSource(str.str());
+}
+
+TestInstance* InputAttachmentSparseFillingTest::createInstance(Context& context) const
+{
+	return new InputAttachmentSparseFillingTestInstance(context, m_testParams);
+}
+
+void InputAttachmentSparseFillingTest::checkSupport(Context& context) const
+{
+	if (m_testParams.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
+		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
+
+	const vk::VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
+
+	if( m_testParams.activeInputAttachmentCount > limits.maxPerStageDescriptorInputAttachments )
+		TCU_THROW(NotSupportedError, "Input attachment count exceeds maxPerStageDescriptorInputAttachments");
+
+	if ( 2u * m_testParams.activeInputAttachmentCount > limits.maxPerStageResources)
+		TCU_THROW(NotSupportedError, "Input attachment count including unused elements exceeds maxPerStageResources");
+}
+
+InputAttachmentSparseFillingTestInstance::InputAttachmentSparseFillingTestInstance (Context& context, const TestParams& testParams)
+	: vkt::TestInstance	(context)
+	, m_renderSize		(RENDER_SIZE, RENDER_SIZE)
+	, m_vertices		(createFullscreenTriangle())
+	, m_testParams		(testParams)
+{
+	const DeviceInterface&				vk						= m_context.getDeviceInterface();
+	const VkDevice						vkDevice				= m_context.getDevice();
+	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
+	SimpleAllocator						memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+	const VkComponentMapping			componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+	{
+		const VkImageCreateInfo	inputImageParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
+			DE_NULL,																// const void*				pNext;
+			0u,																		// VkImageCreateFlags		flags;
+			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
+			VK_FORMAT_R8G8B8A8_UNORM,												// VkFormat					format;
+			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
+			1u,																		// deUint32					mipLevels;
+			1u,																		// deUint32					arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
+			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
+			VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags		usage;
+			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
+			1u,																		// deUint32					queueFamilyIndexCount;
+			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
+		};
+
+		VkImageViewCreateInfo inputAttachmentViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,								// VkStructureType			sType;
+			DE_NULL,																// const void*				pNext;
+			0u,																		// VkImageViewCreateFlags	flags;
+			0,																		// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,													// VkImageViewType			viewType;
+			VK_FORMAT_R8G8B8A8_UNORM,												// VkFormat					format;
+			componentMappingRGBA,													// VkChannelMapping			channels;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange	subresourceRange;
+		};
+
+		// Create input attachment images with image views
+		for (deUint32 imageNdx = 0; imageNdx < m_testParams.activeInputAttachmentCount; ++imageNdx)
+		{
+			auto inputImage					= safeSharedPtr(new Unique<VkImage>(vk::createImage(vk, vkDevice, &inputImageParams)));
+
+			auto inputImageAlloc			= safeSharedPtr(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, **inputImage), MemoryRequirement::Any).release());
+			VK_CHECK(vk.bindImageMemory(vkDevice, **inputImage, inputImageAlloc->getMemory(), inputImageAlloc->getOffset()));
+
+			inputAttachmentViewParams.image	= **inputImage;
+			auto inputImageView				= safeSharedPtr(new Unique<VkImageView>(createImageView(vk, vkDevice, &inputAttachmentViewParams)));
+
+			m_inputImages.push_back(inputImage);
+			m_inputImageMemory.push_back(inputImageAlloc);
+			m_inputImageViews.push_back(inputImageView);
+		}
+	}
+
+	{
+		const VkImageCreateInfo	outputImageParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
+			DE_NULL,																// const void*				pNext;
+			0u,																		// VkImageCreateFlags		flags;
+			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
+			VK_FORMAT_R32G32_UINT,													// VkFormat					format;
+			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
+			1u,																		// deUint32					mipLevels;
+			1u,																		// deUint32					arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
+			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
+			VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+				VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
+			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
+			1u,																		// deUint32					queueFamilyIndexCount;
+			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
+		};
+
+		m_outputImage		= safeSharedPtr(new Unique<VkImage>(vk::createImage(vk, vkDevice, &outputImageParams)));
+		m_outputImageMemory = safeSharedPtr(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, **m_outputImage), MemoryRequirement::Any).release());
+		VK_CHECK(vk.bindImageMemory(vkDevice, **m_outputImage, m_outputImageMemory->getMemory(), m_outputImageMemory->getOffset()));
+
+		VkImageViewCreateInfo inputAttachmentViewParams =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,								// VkStructureType			sType;
+			DE_NULL,																// const void*				pNext;
+			0u,																		// VkImageViewCreateFlags	flags;
+			**m_outputImage,														// VkImage					image;
+			VK_IMAGE_VIEW_TYPE_2D,													// VkImageViewType			viewType;
+			VK_FORMAT_R32G32_UINT,													// VkFormat					format;
+			componentMappingRGBA,													// VkChannelMapping			channels;
+			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange	subresourceRange;
+		};
+		m_outputImageView = safeSharedPtr(new Unique<VkImageView>(createImageView(vk, vkDevice, &inputAttachmentViewParams)));
+	}
+
+	{
+		const VkDeviceSize			outputBufferSizeBytes	= m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(VK_FORMAT_R32G32_UINT));
+		const VkBufferCreateInfo	outputBufferParams		=
+		{
+			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
+			DE_NULL,									// pNext
+			(VkBufferCreateFlags)0u,					// flags
+			outputBufferSizeBytes,						// size
+			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
+			VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
+			1u,											// queueFamilyIndexCount
+			&queueFamilyIndex,							// pQueueFamilyIndices
+		};
+		m_outputBuffer			= safeSharedPtr(new Unique<VkBuffer>(createBuffer(vk, vkDevice, &outputBufferParams)));
+		m_outputBufferMemory	= safeSharedPtr(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, **m_outputBuffer), MemoryRequirement::HostVisible).release());
+		VK_CHECK(vk.bindBufferMemory(vkDevice, **m_outputBuffer, m_outputBufferMemory->getMemory(), m_outputBufferMemory->getOffset()));
+	}
+
+	// Create render pass
+	if (testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
+		m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice);
+	else
+		m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice);
+
+	std::vector<VkDescriptorImageInfo>	descriptorImageInfos;
+	std::vector<VkImageView> framebufferImageViews;
+	descriptorImageInfos.push_back(
+		VkDescriptorImageInfo{
+			DE_NULL,				// VkSampleri		sampler;
+			**m_outputImageView,	// VkImageView		imageView;
+			VK_IMAGE_LAYOUT_GENERAL	// VkImageLayout	imageLayout;
+		}
+	);
+	for (auto& inputImageView : m_inputImageViews)
+	{
+		framebufferImageViews.push_back(**inputImageView);
+		descriptorImageInfos.push_back(
+			VkDescriptorImageInfo{
+				DE_NULL,									// VkSampleri		sampler;
+				**inputImageView,							// VkImageView		imageView;
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout;
+			}
+		);
+	}
+
+	// Create framebuffer
+	{
+		const VkFramebufferCreateInfo	framebufferParams	=
+		{
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// VkStructureType			sType;
+			DE_NULL,												// const void*				pNext;
+			0u,														// VkFramebufferCreateFlags	flags;
+			*m_renderPass,											// VkRenderPass				renderPass;
+			static_cast<deUint32>(framebufferImageViews.size()),	// deUint32					attachmentCount;
+			framebufferImageViews.data(),							// const VkImageView*		pAttachments;
+			static_cast<deUint32>(m_renderSize.x()),				// deUint32					width;
+			static_cast<deUint32>(m_renderSize.y()),				// deUint32					height;
+			1u														// deUint32					layers;
+		};
+
+		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
+	}
+
+	// Create pipeline layout
+	{
+		DescriptorSetLayoutBuilder	layoutBuilder;
+		// add output image storage
+		layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
+		// add input attachments
+		for (deUint32 imageNdx = 0; imageNdx < m_testParams.activeInputAttachmentCount; ++imageNdx)
+			layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
+		m_descriptorSetLayout = layoutBuilder.build(vk, vkDevice);
+
+		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType;
+			DE_NULL,												// const void*						pNext;
+			0u,														// VkPipelineLayoutCreateFlags		flags;
+			1u,														// deUint32							setLayoutCount;
+			&m_descriptorSetLayout.get(),							// const VkDescriptorSetLayout*		pSetLayouts;
+			0u,														// deUint32							pushConstantRangeCount;
+			DE_NULL													// const VkPushConstantRange*		pPushConstantRanges;
+		};
+
+		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+	}
+
+	// Update descriptor set
+	{
+		m_descriptorPool = DescriptorPoolBuilder()
+			.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,		1u)
+			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	m_testParams.activeInputAttachmentCount)
+			.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
+		{
+			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType					sType
+			DE_NULL,											// const void*						pNext
+			*m_descriptorPool,									// VkDescriptorPool					descriptorPool
+			1u,													// deUint32							descriptorSetCount
+			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
+		};
+		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
+
+		DescriptorSetUpdateBuilder builder;
+		builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[0]);
+		for( deUint32 i=1; i<static_cast<deUint32>(descriptorImageInfos.size()); ++i)
+			builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(i), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorImageInfos[i]);
+		builder.update(vk, vkDevice);
+	}
+
+	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vertex"), 0);
+	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("fragment"), 0);
+
+	// Create pipelines
+	{
+		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
+		{
+			0u,								// deUint32					binding;
+			sizeof(Vertex),					// deUint32					strideInBytes;
+			VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	inputRate;
+		};
+
+		std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescription	=
+		{
+			{
+				0u,								// deUint32		location;
+				0u,								// deUint32		binding;
+				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat		format;
+				0u								// deUint32		offset;
+			},
+			{
+				1u,								// deUint32		location;
+				0u,								// deUint32		binding;
+				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat		format;
+				DE_OFFSET_OF(Vertex, uv)		// deUint32		offset;
+			}
+		};
+
+		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
+			DE_NULL,														// const void*								pNext;
+			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
+			1u,																// deUint32									vertexBindingDescriptionCount;
+			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+			static_cast<deUint32>(vertexInputAttributeDescription.size()),	// deUint32									vertexAttributeDescriptionCount;
+			vertexInputAttributeDescription.data()							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
+		};
+
+		const std::vector<VkViewport>				viewports							(1, makeViewport(m_renderSize));
+		const std::vector<VkRect2D>					scissors							(1, makeRect2D(m_renderSize));
+
+		{
+			m_graphicsPipeline	= makeGraphicsPipeline(vk,									// const DeviceInterface&						vk
+													  vkDevice,								// const VkDevice								device
+													  *m_pipelineLayout,					// const VkPipelineLayout						pipelineLayout
+													  *m_vertexShaderModule,				// const VkShaderModule							vertexShaderModule
+													  DE_NULL,								// const VkShaderModule							tessellationControlModule
+													  DE_NULL,								// const VkShaderModule							tessellationEvalModule
+													  DE_NULL,								// const VkShaderModule							geometryShaderModule
+													  *m_fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
+													  *m_renderPass,						// const VkRenderPass							renderPass
+													  viewports,							// const std::vector<VkViewport>&				viewports
+													  scissors,								// const std::vector<VkRect2D>&					scissors
+													  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology					topology
+													  0u,									// const deUint32								subpass
+													  0u,									// const deUint32								patchControlPoints
+													  &vertexInputStateParams);				// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
+		}
+	}
+
+	// Create vertex buffer
+	{
+		const VkBufferCreateInfo vertexBufferParams =
+		{
+			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,					// VkStructureType		sType;
+			DE_NULL,												// const void*			pNext;
+			0u,														// VkBufferCreateFlags	flags;
+			(VkDeviceSize)(sizeof(Vertex) * m_vertices.size()),		// VkDeviceSize			size;
+			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,						// VkBufferUsageFlags	usage;
+			VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode		sharingMode;
+			1u,														// deUint32				queueFamilyIndexCount;
+			&queueFamilyIndex										// const deUint32*		pQueueFamilyIndices;
+		};
+
+		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
+		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
+		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
+
+		// Upload vertex data
+		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex));
+		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
+	}
+
+	// Create command pool
+	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
+
+	// Create command buffer
+	if (testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
+		createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
+	else
+		createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
+}
+
+InputAttachmentSparseFillingTestInstance::~InputAttachmentSparseFillingTestInstance (void)
+{
+}
+
+template<typename RenderpassSubpass>
+void InputAttachmentSparseFillingTestInstance::createCommandBuffer (const DeviceInterface&	vk,
+																	VkDevice				vkDevice)
+{
+	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
+
+	// clear output image (rg16ui) to (0,0), set image layout to VK_IMAGE_LAYOUT_GENERAL
+	VkImageSubresourceRange		range				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
+	{
+		const VkImageMemoryBarrier	outputImageInitBarrier =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
+			DE_NULL,												// const void*				pNext;
+			0u,														// VkAccessFlags			srcAccessMask;
+			VK_ACCESS_TRANSFER_WRITE_BIT,							// VkAccessFlags			dstAcessMask;
+			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
+			VK_IMAGE_LAYOUT_GENERAL,								// VkImageLayout			newLayout;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,								// deUint32					destQueueFamilyIndex;
+			**m_outputImage,										// VkImage					image;
+			range													// VkImageSubresourceRange	subresourceRange;
+		};
+		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &outputImageInitBarrier);
+		VkClearValue				clearColor = makeClearValueColorU32(0, 0, 0, 0);
+		vk.cmdClearColorImage(*m_cmdBuffer, **m_outputImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
+		VkMemoryBarrier					memBarrier =
+		{
+			VK_STRUCTURE_TYPE_MEMORY_BARRIER,						// sType
+			DE_NULL,												// pNext
+			VK_ACCESS_TRANSFER_WRITE_BIT,							// srcAccessMask
+			VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT	// dstAccessMask
+		};
+		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+			0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+	}
+	// clear all input attachments (rgba8) to (1,1,1,1), set image layout to VK_IMAGE_LAYOUT_GENERAL
+	for (auto& inputImage : m_inputImages)
+	{
+		const VkImageMemoryBarrier	inputImageInitBarrier =
+		{
+			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
+			DE_NULL,											// const void*				pNext;
+			0u,													// VkAccessFlags			srcAccessMask;
+			VK_ACCESS_MEMORY_WRITE_BIT,							// VkAccessFlags			dstAcessMask;
+			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
+			VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout			newLayout;
+			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
+			**inputImage,										// VkImage					image;
+			range												// VkImageSubresourceRange	subresourceRange;
+		};
+		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &inputImageInitBarrier);
+		VkClearValue				clearColor = makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
+
+		vk.cmdClearColorImage(*m_cmdBuffer, **inputImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
+
+		VkMemoryBarrier					memBarrier =
+		{
+			VK_STRUCTURE_TYPE_MEMORY_BARRIER,					// sType
+			DE_NULL,											// pNext
+			VK_ACCESS_TRANSFER_WRITE_BIT,						// srcAccessMask
+			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT					// dstAccessMask
+		};
+		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+			0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+	}
+
+	// Render pass does not use clear values - input images were prepared beforehand
+	const VkRenderPassBeginInfo renderPassBeginInfo =
+	{
+		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
+		DE_NULL,												// const void*			pNext;
+		*m_renderPass,											// VkRenderPass			renderPass;
+		*m_framebuffer,											// VkFramebuffer		framebuffer;
+		makeRect2D(m_renderSize),								// VkRect2D				renderArea;
+		0,														// uint32_t				clearValueCount;
+		DE_NULL													// const VkClearValue*	pClearValues;
+	};
+	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
+	RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
+
+	const VkDeviceSize			vertexBufferOffset = 0;
+	vk.cmdBindPipeline			(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
+	vk.cmdBindDescriptorSets	(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
+	vk.cmdBindVertexBuffers		(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
+	vk.cmdDraw					(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
+
+	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo(DE_NULL);
+	RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
+
+	copyImageToBuffer(vk, *m_cmdBuffer, **m_outputImage, **m_outputBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+	endCommandBuffer(vk, *m_cmdBuffer);
+}
+
+template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
+Move<VkRenderPass> InputAttachmentSparseFillingTestInstance::createRenderPass (const DeviceInterface&	vk,
+																			   VkDevice					vkDevice)
+{
+	const VkImageAspectFlags	aspectMask						= m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
+	std::vector<AttachmentDesc>	attachmentDescriptions;
+	std::vector<AttachmentRef>	attachmentRefs;
+
+	std::vector<deUint32>		attachmentIndices;
+	std::vector<deUint32>		descriptorBindings;
+	generateInputAttachmentParams(m_testParams.activeInputAttachmentCount, 2u * m_testParams.activeInputAttachmentCount, attachmentIndices, descriptorBindings);
+
+	for (deUint32 i = 0; i < m_testParams.activeInputAttachmentCount; ++i)
+	{
+		attachmentDescriptions.push_back(
+			AttachmentDesc(
+				DE_NULL,									// const void*						pNext
+				(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags
+				VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat							format
+				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples
+				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				loadOp
+				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp
+				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp
+				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp
+				VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout					initialLayout
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout					finalLayout
+			)
+		);
+	}
+	for (std::size_t i = 0; i < attachmentIndices.size(); ++i)
+		attachmentRefs.push_back(
+			AttachmentRef(
+				DE_NULL,									// const void*			pNext
+				attachmentIndices[i],						// deUint32				attachment
+				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout		layout
+				aspectMask									// VkImageAspectFlags	aspectMask
+			)
+		);
+
+	std::vector<SubpassDesc>		subpassDescriptions			=
+	{
+		SubpassDesc (
+			DE_NULL,
+			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
+			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
+			0u,													// deUint32							viewMask
+			static_cast<deUint32>(attachmentRefs.size()),		// deUint32							inputAttachmentCount
+			attachmentRefs.data(),								// const VkAttachmentReference*		pInputAttachments
+			0u,													// deUint32							colorAttachmentCount
+			DE_NULL,											// const VkAttachmentReference*		pColorAttachments
+			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments
+			DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment
+			0u,													// deUint32							preserveAttachmentCount
+			DE_NULL												// const deUint32*					pPreserveAttachments
+		),
+	};
+
+	const RenderPassCreateInfo	renderPassInfo					(
+		DE_NULL,												// const void*						pNext
+		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
+		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount
+		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
+		static_cast<deUint32>(subpassDescriptions.size()),		// deUint32							subpassCount
+		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
+		0u,														// deUint32							dependencyCount
+		DE_NULL,												// const VkSubpassDependency*		pDependencies
+		0u,														// deUint32							correlatedViewMaskCount
+		DE_NULL													// const deUint32*					pCorrelatedViewMasks
+	);
+
+	return renderPassInfo.createRenderPass(vk, vkDevice);
+}
+
+tcu::TestStatus InputAttachmentSparseFillingTestInstance::iterate (void)
+{
+	const DeviceInterface&		vk			= m_context.getDeviceInterface();
+	const VkDevice				vkDevice	= m_context.getDevice();
+	const VkQueue				queue		= m_context.getUniversalQueue();
+
+	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
+
+	return verifyImage();
+}
+
+tcu::TestStatus InputAttachmentSparseFillingTestInstance::verifyImage (void)
+{
+	const DeviceInterface&				vk						= m_context.getDeviceInterface();
+	const VkDevice						vkDevice				= m_context.getDevice();
+
+	invalidateAlloc(vk, vkDevice, *m_outputBufferMemory);
+	const tcu::ConstPixelBufferAccess resultAccess(mapVkFormat(VK_FORMAT_R32G32_UINT), m_renderSize.x(), m_renderSize.y(), 1u, m_outputBufferMemory->getHostPtr());
+
+	// Log result image
+	m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result images")
+		<< tcu::TestLog::Image("Rendered", "Rendered image", resultAccess)
+		<< tcu::TestLog::EndImageSet;
+
+	// Check the unused image data hasn't changed.
+	for (int y = 0; y < resultAccess.getHeight(); y++)
+		for (int x = 0; x < resultAccess.getWidth(); x++)
+		{
+			tcu::UVec4 color = resultAccess.getPixelUint(x, y);
+			if( color.x() != m_testParams.activeInputAttachmentCount)
+				return tcu::TestStatus::fail("Wrong attachment count");
+			if( color.y() != m_testParams.activeInputAttachmentCount )
+				return tcu::TestStatus::fail("Wrong active attachment count");
+		}
+
+	return tcu::TestStatus::pass("Pass");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createRenderPassUnusedAttachmentSparseFillingTests (tcu::TestContext& testCtx, const RenderPassType renderPassType)
+{
+	de::MovePtr<tcu::TestCaseGroup>		unusedAttTests		(new tcu::TestCaseGroup(testCtx, "attachment_sparse_filling", "Unused attachment tests"));
+
+	const std::vector<deUint32> activeInputAttachmentCount
+	{
+		1u,
+		3u,
+		7u,
+		15u,
+		31u,
+		63u,
+		127u
+	};
+
+	for (std::size_t attachmentNdx = 0; attachmentNdx < activeInputAttachmentCount.size(); ++attachmentNdx)
+	{
+		TestParams testParams{ renderPassType, activeInputAttachmentCount[attachmentNdx] };
+		unusedAttTests->addChild(new InputAttachmentSparseFillingTest(testCtx, std::string("input_attachment_") + de::toString(activeInputAttachmentCount[attachmentNdx]), "", testParams));
+	}
+
+	return unusedAttTests.release();
+}
+
+} // renderpass
+
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.hpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.hpp
new file mode 100644
index 0000000..2bb0faf
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedAttachmentSparseFillingTests.hpp
@@ -0,0 +1,41 @@
+#ifndef _VKTRENDERPASSUNUSEDATTACHMENTSPARSEFILLINGTESTS_HPP
+#define _VKTRENDERPASSUNUSEDATTACHMENTSPARSEFILLINGTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2018 Google Inc.
+ * Copyright (c) 2015 Imagination Technologies Ltd.
+ *
+ * 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 Tests sparse input attachments in VkSubpassDescription::pInputAttachments
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+#include "vktRenderPassTestsUtil.hpp"
+
+namespace vkt
+{
+namespace renderpass
+{
+
+tcu::TestCaseGroup* createRenderPassUnusedAttachmentSparseFillingTests (tcu::TestContext& testCtx, const RenderPassType renderPassType);
+
+} // renderpass
+} // vkt
+
+#endif // _VKTRENDERPASSUNUSEDATTACHMENTSPARSEFILLINGTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedClearAttachmentTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedClearAttachmentTests.cpp
index 8d68f43..59b5004 100644
--- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedClearAttachmentTests.cpp
+++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassUnusedClearAttachmentTests.cpp
@@ -28,6 +28,8 @@
 #include "vkRefUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkObjUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "tcuTextureUtil.hpp"
 #include <sstream>
 #include <functional>
 #include <vector>
@@ -45,6 +47,7 @@
 constexpr size_t	COLOR_ATTACHMENTS_NUMBER	= 4; // maxColorAttachments is guaranteed to be at least 4.
 constexpr VkFormat	FORMAT_COLOR				= VK_FORMAT_R8G8B8A8_UNORM;
 constexpr VkFormat	FORMAT_DEPTH				= VK_FORMAT_D32_SFLOAT;
+constexpr VkFormat	FORMAT_STENCIL				= VK_FORMAT_S8_UINT;
 constexpr VkFormat	FORMAT_DEPTH_STENCIL		= VK_FORMAT_D32_SFLOAT_S8_UINT;
 const deBool		DE_BOOL_VALUES[]			= { DE_FALSE, DE_TRUE };
 
@@ -52,51 +55,89 @@
 {
 	DEPTH_STENCIL_NONE			= 0,
 	DEPTH_STENCIL_DEPTH_ONLY	= 1,
-	DEPTH_STENCIL_BOTH			= 2,
-	DEPTH_STENCIL_MAX_ENUM		= 3
+	DEPTH_STENCIL_STENCIL_ONLY	= 2,
+	DEPTH_STENCIL_BOTH			= 3,
+	DEPTH_STENCIL_MAX_ENUM		= 4
 };
 
-std::string depthStencilTypeName(DepthStencilType type)
+std::string getFormatBriefName (VkFormat format)
+{
+	switch (format)
+	{
+	case VK_FORMAT_D32_SFLOAT:			return "d32";
+	case VK_FORMAT_S8_UINT:				return "s8";
+	case VK_FORMAT_D32_SFLOAT_S8_UINT:	return "d32s8";
+	default:								break;
+	}
+
+	return "";
+}
+
+std::string depthStencilTypeName (DepthStencilType type, VkFormat format)
 {
 	DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
 
+	const std::string formatName = getFormatBriefName(format);
+
 	switch (type)
 	{
-	case DEPTH_STENCIL_NONE:		return "nods";
-	case DEPTH_STENCIL_DEPTH_ONLY:	return "depthonly";
-	case DEPTH_STENCIL_BOTH:		return "depthstencil";
-	default:						return "UNKNOWN";		// Unreachable.
+	case DEPTH_STENCIL_NONE:			return "nods";
+	case DEPTH_STENCIL_DEPTH_ONLY:		return "depthonly_" + formatName;
+	case DEPTH_STENCIL_STENCIL_ONLY:	return "stencilonly_" + formatName;
+	case DEPTH_STENCIL_BOTH:			return "depthstencil_" + formatName;
+	default:							return "UNKNOWN";		// Unreachable.
 	}
 
-	return "UNKNOWN";										// Unreachable.
+	return "UNKNOWN";											// Unreachable.
 }
 
-VkImageAspectFlags getAspectMask(DepthStencilType type)
+VkImageAspectFlags getClearAspectMask (DepthStencilType type)
 {
 	VkImageAspectFlags aspectMask = 0u;
 
-	switch (type)
-	{
-	case DEPTH_STENCIL_BOTH:
-		aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
-		// Fallthrough.
-	case DEPTH_STENCIL_DEPTH_ONLY:
+	if (type == DEPTH_STENCIL_DEPTH_ONLY || type == DEPTH_STENCIL_BOTH)
 		aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
-		break;
-	default:
-		break;
-	}
+
+	if (type == DEPTH_STENCIL_STENCIL_ONLY || type == DEPTH_STENCIL_BOTH)
+		aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
 
 	return aspectMask;
 }
 
-VkFormat getFormat(DepthStencilType type)
+VkImageAspectFlags getFormatAspectMask (VkFormat format)
 {
-	if (type == DEPTH_STENCIL_BOTH)
-		return FORMAT_DEPTH_STENCIL;
+	const auto			order		= mapVkFormat(format).order;
+	VkImageAspectFlags	aspectMask	= 0u;
+
+	if (tcu::hasDepthComponent(order))
+		aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
+
+	if (tcu::hasStencilComponent(order))
+		aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+
+	if (!aspectMask)
+		aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT;
+
+	return aspectMask;
+}
+
+std::vector<VkFormat> getFormats (DepthStencilType type)
+{
+	DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
+
+	std::vector<VkFormat> formats;
+
+	if (type != DEPTH_STENCIL_NONE)
+		formats.push_back(FORMAT_DEPTH_STENCIL);
+	else
+		formats.push_back(VK_FORMAT_UNDEFINED);
+
 	if (type == DEPTH_STENCIL_DEPTH_ONLY)
-		return FORMAT_DEPTH;
-	return VK_FORMAT_UNDEFINED;
+		formats.push_back(FORMAT_DEPTH);
+	else if (type == DEPTH_STENCIL_STENCIL_ONLY)
+		formats.push_back(FORMAT_STENCIL);
+
+	return formats;
 }
 
 bool isDepthOnly(DepthStencilType type)
@@ -104,6 +145,11 @@
 	return (type == DEPTH_STENCIL_DEPTH_ONLY);
 }
 
+bool isStencilOnly(DepthStencilType type)
+{
+	return (type == DEPTH_STENCIL_STENCIL_ONLY);
+}
+
 bool hasDepthStencil(DepthStencilType type)
 {
 	return (type != DEPTH_STENCIL_NONE);
@@ -111,16 +157,18 @@
 
 struct TestParams
 {
-	TestParams(size_t numColorAttachments, DepthStencilType depthStencilType_, deBool depthStencilUsed_, RenderPassType renderPassType_)
+	TestParams(size_t numColorAttachments, DepthStencilType depthStencilType_, deBool depthStencilUsed_, VkFormat depthStencilFormat_, RenderPassType renderPassType_)
 		: colorUsed(numColorAttachments, DE_FALSE)
 		, depthStencilType(depthStencilType_)
 		, depthStencilUsed(depthStencilUsed_)
+		, depthStencilFormat(depthStencilFormat_)
 		, renderPassType(renderPassType_)
 		{}
 
 	std::vector<deBool>	colorUsed;
 	DepthStencilType	depthStencilType;
 	deBool				depthStencilUsed;
+	VkFormat		depthStencilFormat;
 	RenderPassType		renderPassType;
 };
 
@@ -212,7 +260,7 @@
 		checkFormatSupported(context, FORMAT_COLOR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
 	if (hasDepthStencil(m_testParams.depthStencilType))
-		checkFormatSupported(context, getFormat(m_testParams.depthStencilType), VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+		checkFormatSupported(context, m_testParams.depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
 }
 
 TestInstance* UnusedClearAttachmentTest::createInstance (Context& context) const
@@ -269,7 +317,7 @@
 									 const TestParams		testParams)
 {
 	const VkImageAspectFlags	colorAspectMask					= VK_IMAGE_ASPECT_COLOR_BIT;
-	const VkImageAspectFlags	dsAspectMask					= getAspectMask(testParams.depthStencilType);
+	const VkImageAspectFlags	dsClearAspectMask				= getClearAspectMask(testParams.depthStencilType);
 	const bool					isDepthStencil					= hasDepthStencil(testParams.depthStencilType);
 
 	// Create attachment descriptions.
@@ -290,17 +338,19 @@
 	if (isDepthStencil)
 	{
 		const bool					depthOnly		= isDepthOnly(testParams.depthStencilType);
-		const VkFormat				attachFormat	= getFormat(testParams.depthStencilType);
+		const bool					stencilOnly		= isStencilOnly(testParams.depthStencilType);
+		const VkAttachmentLoadOp	depthLoadOp		= (stencilOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
+		const VkAttachmentStoreOp	depthStoreOp	= (stencilOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
 		const VkAttachmentLoadOp	stencilLoadOp	= (depthOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
 		const VkAttachmentStoreOp	stencilStoreOp	= (depthOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
 
 		attachmentDescriptions.emplace_back(
 			nullptr,											// const void*						pNext
 			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
-			attachFormat,										// VkFormat							format
+			testParams.depthStencilFormat,						// VkFormat							format
 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples
-			VK_ATTACHMENT_LOAD_OP_LOAD,							// VkAttachmentLoadOp				loadOp
-			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
+			depthLoadOp,										// VkAttachmentLoadOp				loadOp
+			depthStoreOp,										// VkAttachmentStoreOp				storeOp
 			stencilLoadOp,										// VkAttachmentLoadOp				stencilLoadOp
 			stencilStoreOp,										// VkAttachmentStoreOp				stencilStoreOp
 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
@@ -327,7 +377,7 @@
 			DE_NULL,
 			(testParams.depthStencilUsed ? static_cast<deUint32>(testParams.colorUsed.size()) : VK_ATTACHMENT_UNUSED),
 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-			dsAspectMask
+			dsClearAspectMask
 		));
 	}
 
@@ -420,7 +470,7 @@
 			DE_NULL,																		// const void*				pNext;
 			0u,																				// VkImageCreateFlags		flags;
 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
-			getFormat(m_testParams.depthStencilType),										// VkFormat					format;
+			m_testParams.depthStencilFormat,												// VkFormat					format;
 			{ kImageWidth, kImageHeight, 1u },												// VkExtent3D				extent;
 			1u,																				// deUint32					mipLevels;
 			1u,																				// deUint32					arrayLayers;
@@ -532,8 +582,8 @@
 
 		if (hasDepthStencil(m_testParams.depthStencilType))
 		{
-			const VkFormat				format		= getFormat(m_testParams.depthStencilType);
-			const VkImageAspectFlags	aspectMask	= getAspectMask(m_testParams.depthStencilType);
+			const VkImageAspectFlags clearAspectMask	= getClearAspectMask(m_testParams.depthStencilType);
+			const VkImageAspectFlags formatAspectMask	= getFormatAspectMask(m_testParams.depthStencilFormat);
 
 			// Create, allocate and bind image memory.
 			m_depthImage = createImage(vk, vkDevice, &depthImageParams);
@@ -549,9 +599,9 @@
 					0u,											// VkImageViewCreateFlags	flags;
 					*m_depthImage,								// VkImage					image;
 					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
-					format,										// VkFormat					format;
+					m_testParams.depthStencilFormat,			// VkFormat					format;
 					componentMapping,							// VkChannelMapping			channels;
-					{ aspectMask, 0u, 1u, 0u, 1u }				// VkImageSubresourceRange	subresourceRange;
+					{ clearAspectMask, 0u, 1u, 0u, 1u }			// VkImageSubresourceRange	subresourceRange;
 				};
 
 				m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
@@ -579,7 +629,7 @@
 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
 					*m_depthImage,							// VkImage					image;
 					{										// VkImageSubresourceRange	subresourceRange;
-						aspectMask,							// VkImageAspect			aspect;
+						formatAspectMask,					// VkImageAspect			aspect;
 						0u,									// deUint32					baseMipLevel;
 						1u,									// deUint32					mipLevels;
 						0u,									// deUint32					baseArraySlice;
@@ -600,7 +650,7 @@
 					VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
 					*m_depthImage,										// VkImage					image;
 					{													// VkImageSubresourceRange	subresourceRange;
-						aspectMask,										// VkImageAspect			aspect;
+						formatAspectMask,								// VkImageAspect			aspect;
 						0u,												// deUint32					baseMipLevel;
 						1u,												// deUint32					mipLevels;
 						0u,												// deUint32					baseArraySlice;
@@ -610,11 +660,11 @@
 
 				const VkImageSubresourceRange	clearRange	=
 				{
-					aspectMask,	// VkImageAspectFlags	aspectMask;
-					0u,			// deUint32				baseMipLevel;
-					1u,			// deUint32				levelCount;
-					0u,			// deUint32				baseArrayLayer;
-					1u			// deUint32				layerCount;
+					clearAspectMask,	// VkImageAspectFlags	aspectMask;
+					0u,					// deUint32				baseMipLevel;
+					1u,					// deUint32				levelCount;
+					0u,					// deUint32				baseArrayLayer;
+					1u					// deUint32				layerCount;
 				};
 
 				// Clear image and transfer layout.
@@ -801,9 +851,9 @@
 	if (hasDepthStencil(m_testParams.depthStencilType))
 	{
 		const VkClearAttachment clearAttachment = {
-			getAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
-			0u,												// uint32_t				colorAttachment;
-			m_clearColorDepth								// VkClearValue			clearValue;
+			getClearAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
+			0u,													// uint32_t				colorAttachment;
+			m_clearColorDepth									// VkClearValue			clearValue;
 		};
 		clearAttachments.push_back(clearAttachment);
 	}
@@ -862,29 +912,36 @@
 
 	if (hasDepthStencil(m_testParams.depthStencilType))
 	{
-		const bool							depthOnly	= isDepthOnly(m_testParams.depthStencilType);
-		const VkFormat						format		= getFormat(m_testParams.depthStencilType);
-		de::MovePtr<tcu::TextureLevel>		depthPixels	= pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, format, m_renderSize);
-		const tcu::ConstPixelBufferAccess&	depthAccess	= depthPixels->getAccess();
-		const float							refDepth	= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.depth : m_initialColorDepth.depthStencil.depth);
+		const bool depthOnly	= isDepthOnly(m_testParams.depthStencilType);
+		const bool stencilOnly	= isStencilOnly(m_testParams.depthStencilType);
 
-		for (int y = 0; y < depthAccess.getHeight(); ++y)
-		for (int x = 0; x < depthAccess.getWidth(); ++x)
+		if (!stencilOnly)
 		{
-			const float value = depthAccess.getPixDepth(x, y);
-			if (de::abs(value - refDepth) > 0.001f)
-			{
-				std::ostringstream msg;
+			de::MovePtr<tcu::TextureLevel>		depthPixels	= pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize);
+			const tcu::ConstPixelBufferAccess&	depthAccess	= depthPixels->getAccess();
+			const float							refDepth	= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.depth : m_initialColorDepth.depthStencil.depth);
 
-				msg << "Depth/stencil attachment with mismatched depth value at pixel ("
-					<< x << ", " << y << "): expected value " << refDepth << " and found " << value;
-				return tcu::TestStatus::fail(msg.str());
+			for (int y = 0; y < depthAccess.getHeight(); ++y)
+			for (int x = 0; x < depthAccess.getWidth(); ++x)
+			{
+				const float value = depthAccess.getPixDepth(x, y);
+				if (de::abs(value - refDepth) > 0.001f)
+				{
+					std::ostringstream msg;
+
+					msg << "Depth/stencil attachment with mismatched depth value at pixel ("
+						<< x << ", " << y << "): expected value " << refDepth << " and found " << value;
+					return tcu::TestStatus::fail(msg.str());
+				}
 			}
 		}
 
 		if (!depthOnly)
 		{
-			de::MovePtr<tcu::TextureLevel>		stencilPixels	= pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, format, m_renderSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
+			// Note read*Attachment leaves the attachment in the VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout, so the current layout
+			// depends on if we have previously read the depth aspect or not.
+			const VkImageLayout					currentLayout	= (stencilOnly ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
+			de::MovePtr<tcu::TextureLevel>		stencilPixels	= pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize, currentLayout);
 			const tcu::ConstPixelBufferAccess&	stencilAccess	= stencilPixels->getAccess();
 			const deUint32						refStencil		= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.stencil : m_initialColorDepth.depthStencil.stencil);
 
@@ -932,6 +989,7 @@
 {
 	return (value ? "used" : "unused");
 }
+
 std::string getCombName(const std::vector<deBool>& array)
 {
 	std::ostringstream name;
@@ -949,39 +1007,44 @@
 
 	for (int depthStencilType = 0; depthStencilType < DEPTH_STENCIL_MAX_ENUM; ++depthStencilType)
 	{
-		for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
+		const DepthStencilType	dsType		= static_cast<DepthStencilType>(depthStencilType);
+		const auto				dsFormats	= getFormats(dsType);
+
+		for (const auto dsFormat : dsFormats)
 		{
-			deBool							depthStencilUse	= DE_BOOL_VALUES[i];
-			DepthStencilType				dsType			= static_cast<DepthStencilType>(depthStencilType);
-			std::string						dsCase			= depthStencilTypeName(dsType);
-			std::vector<TestParams>			testTypes;
-
-			if (hasDepthStencil(dsType))
-				testTypes.emplace_back(0, dsType, depthStencilUse, renderPassType);						// No color attachments.
-			testTypes.emplace_back(1, dsType, depthStencilUse, renderPassType);							// Single color attachment.
-			testTypes.emplace_back(COLOR_ATTACHMENTS_NUMBER, dsType, depthStencilUse, renderPassType);	// Multiple color attachments.
-
-			for (auto& params : testTypes)
+			for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
 			{
-				if (!params.colorUsed.empty())
+				const deBool			depthStencilUse	= DE_BOOL_VALUES[i];
+				const std::string		dsCase			= depthStencilTypeName(dsType, dsFormat);
+				std::vector<TestParams>	testTypes;
+
+				if (hasDepthStencil(dsType))
+					testTypes.emplace_back(0, dsType, depthStencilUse, dsFormat, renderPassType);						// No color attachments.
+				testTypes.emplace_back(1, dsType, depthStencilUse, dsFormat, renderPassType);							// Single color attachment.
+				testTypes.emplace_back(COLOR_ATTACHMENTS_NUMBER, dsType, depthStencilUse, dsFormat, renderPassType);	// Multiple color attachments.
+
+				for (auto& params : testTypes)
 				{
-					runCallbackOnCombination(params.colorUsed, [&](const std::vector<deBool>& array) {
-						std::string name = getCombName(array) + "_" + dsCase;
-						if (hasDepthStencil(dsType))
-							name += std::string("_") + getUsed(depthStencilUse);
+					if (!params.colorUsed.empty())
+					{
+						runCallbackOnCombination(params.colorUsed, [&](const std::vector<deBool>& array) {
+							std::string name = getCombName(array) + "_" + dsCase;
+							if (hasDepthStencil(dsType))
+								name += std::string("_") + getUsed(depthStencilUse);
+							testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, "", params));
+						});
+					}
+					else
+					{
+						std::string name = dsCase + "_" + getUsed(depthStencilUse);
 						testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, "", params));
-					});
-				}
-				else
-				{
-					std::string name = dsCase + "_" + getUsed(depthStencilUse);
-					testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, "", params));
+					}
+
 				}
 
+				if (!hasDepthStencil(dsType))
+					break;
 			}
-
-			if (!hasDepthStencil(dsType))
-				break;
 		}
 	}
 
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/CMakeLists.txt b/external/vulkancts/modules/vulkan/shaderexecutor/CMakeLists.txt
index 6ef8eb4..015b0b5 100644
--- a/external/vulkancts/modules/vulkan/shaderexecutor/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/CMakeLists.txt
@@ -7,6 +7,8 @@
 	vktShaderBuiltinTests.hpp
 	vktShaderCommonFunctionTests.cpp
 	vktShaderCommonFunctionTests.hpp
+	vktShaderFConvertTests.cpp
+	vktShaderFConvertTests.hpp
 	vktShaderIntegerFunctionTests.cpp
 	vktShaderIntegerFunctionTests.hpp
 	vktShaderPackingFunctionTests.cpp
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/vktAtomicOperationTests.cpp b/external/vulkancts/modules/vulkan/shaderexecutor/vktAtomicOperationTests.cpp
index 53db259..62b2cdb 100644
--- a/external/vulkancts/modules/vulkan/shaderexecutor/vktAtomicOperationTests.cpp
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/vktAtomicOperationTests.cpp
@@ -473,9 +473,9 @@
 		if (!context.isDeviceFunctionalitySupported("VK_KHR_shader_atomic_int64"))
 			TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_shader_atomic_int64");
 
-		VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shaderAtomicInt64Features;
-		deMemset(&shaderAtomicInt64Features, 0x0, sizeof(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR));
-		shaderAtomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
+		VkPhysicalDeviceShaderAtomicInt64Features shaderAtomicInt64Features;
+		deMemset(&shaderAtomicInt64Features, 0x0, sizeof(VkPhysicalDeviceShaderAtomicInt64Features));
+		shaderAtomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;
 		shaderAtomicInt64Features.pNext = DE_NULL;
 
 		VkPhysicalDeviceFeatures2 features;
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinPrecisionTests.cpp b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinPrecisionTests.cpp
index cea4ed6..bad8cb9 100644
--- a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinPrecisionTests.cpp
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinPrecisionTests.cpp
@@ -2950,91 +2950,24 @@
 DEFINE_DERIVED_FLOAT1_INPUTRANGE_16BIT(Tan16Bit, tan, x, sin(x) * (constant((deFloat16)FLOAT16_1_0) / cos(x)), Interval(false, -DE_PI_DOUBLE, DE_PI_DOUBLE));
 
 template <class T>
-class ArcTrigFunc : public CFloatFunc1<T>
+class ATan : public CFloatFunc1<T>
 {
 public:
-					ArcTrigFunc	(const string&		name,
-								 DoubleFunc1&		func,
-								 const Interval&	domain,
-								 const Interval&	codomain)
-						: CFloatFunc1<T>	(name, func)
-						, m_domain			(domain)
-						, m_codomain		(codomain) {}
+			ATan		(void) : CFloatFunc1<T>	("atan", deAtanOver) {}
 
 protected:
-	double			precision	(const EvalContext& ctx, double ret, double x) const;
-
-	// We could implement getCodomain with m_codomain, but choose not to,
-	// because it seems too strict with trascendental constants like pi.
-
-	const Interval	m_domain;
-	const Interval	m_codomain;
-};
-
-template<> //half precision
-double ArcTrigFunc<Signature<deFloat16, deFloat16> >::precision (const EvalContext& ctx, double ret, double x) const
-{
-	if (!m_domain.contains(x))
-		return TCU_NAN;
-
-	// From the spec 5 ULP.
-	return ctx.format.ulp(ret, 5.0);
-}
-
-template<>
-double ArcTrigFunc<Signature<float, float> >::precision(const EvalContext& ctx, double ret, double x) const
-{
-	if (!m_domain.contains(x))
-		return TCU_NAN;
-
-	if (ctx.floatPrecision == glu::PRECISION_HIGHP)
-		return ctx.format.ulp(ret, 4096.0);
-	else
-		return ctx.format.ulp(ret, 5.0);
-}
-
-class ASin : public CFloatFunc1<Signature<float, float> >
-{
-public:
-	ASin(void) : CFloatFunc1<Signature<float, float> >("asin", deAsin) {}
-
-protected:
-	double			precision(const EvalContext& ctx, double ret, double x) const
+	double	precision	(const EvalContext& ctx, double ret, double x) const
 	{
-		DE_UNREF(ret);
-		if (!de::inBounds(x, -1.0, 1.0))
+		if (x < -DE_PI_DOUBLE * 0.5 || x > DE_PI_DOUBLE * 0.5)
 			return TCU_NAN;
 
 		if (ctx.floatPrecision == glu::PRECISION_HIGHP)
-		{
-			// Absolute error of 2^-11
-			return deLdExp(1.0, -11);
-		}
+			return ctx.format.ulp(ret, 4096.0);
 		else
-		{
-			// Absolute error of 2^-8
-			return deLdExp(1.0, -8);
-		}
+			return ctx.format.ulp(ret, ctx.isShaderFloat16Int8 ? 5.0 : 2.0);
 	}
 };
 
-class ACos : public ArcTrigFunc<Signature<float, float> >
-{
-public:
-	ACos (void) : ArcTrigFunc<Signature<float, float> > ("acos", deAcos,
-								  Interval(-1.0, 1.0),
-								  Interval(0.0, DE_PI_DOUBLE)) {}
-};
-
-template <class T>
-class ATan : public ArcTrigFunc<T>
-{
-public:
-	ATan (void) : ArcTrigFunc<T>("atan", deAtanOver,
-								  Interval::unbounded(),
-								  Interval(-DE_PI_DOUBLE * 0.5, DE_PI_DOUBLE * 0.5)) {}
-};
-
 template <class T>
 class ATan2 : public CFloatFunc2<T>
 {
@@ -3089,18 +3022,16 @@
 DEFINE_DERIVED_FLOAT1_16BIT(Cosh16Bit, cosh, x, (exp(x) + exp(-x)) / constant((deFloat16)FLOAT16_2_0));
 DEFINE_DERIVED_FLOAT1_16BIT(Tanh16Bit, tanh, x, sinh(x) / cosh(x));
 
-// These are not defined as derived forms in the GLSL ES spec, but
-// that gives us a reasonable precision.
-DEFINE_DERIVED_FLOAT1(ASin16BitInOut32b, asin, x, atan2(x, sqrt(constant(1.0f) - pow(x, constant(2.0f)))));
-DEFINE_DERIVED_FLOAT1(ACos16BitInOut32b, acos, x, atan2(sqrt(constant(1.0f) - pow(x, constant(2.0f))), x));
+DEFINE_DERIVED_FLOAT1(ASin, asin, x, atan2(x, sqrt(constant(1.0f) - x * x)));
+DEFINE_DERIVED_FLOAT1(ACos, acos, x, atan2(sqrt(constant(1.0f) - x * x), x));
 DEFINE_DERIVED_FLOAT1(ASinh, asinh, x, log(x + sqrt(x * x + constant(1.0f))));
 DEFINE_DERIVED_FLOAT1(ACosh, acosh, x, log(x + sqrt(alternatives((x + constant(1.0f)) * (x - constant(1.0f)),
 																 (x * x - constant(1.0f))))));
 DEFINE_DERIVED_FLOAT1(ATanh, atanh, x, constant(0.5f) * log((constant(1.0f) + x) /
 															(constant(1.0f) - x)));
 
-DEFINE_DERIVED_FLOAT1_16BIT(ASin16Bit, asin, x, atan2(x, sqrt(constant((deFloat16)FLOAT16_1_0) - pow(x, constant((deFloat16)FLOAT16_2_0)))));
-DEFINE_DERIVED_FLOAT1_16BIT(ACos16Bit, acos, x, atan2(sqrt(constant((deFloat16)FLOAT16_1_0) - pow(x, constant((deFloat16)FLOAT16_2_0))), x));
+DEFINE_DERIVED_FLOAT1_16BIT(ASin16Bit, asin, x, atan2(x, sqrt(constant((deFloat16)FLOAT16_1_0) - x * x)));
+DEFINE_DERIVED_FLOAT1_16BIT(ACos16Bit, acos, x, atan2(sqrt(constant((deFloat16)FLOAT16_1_0) - x * x), x));
 DEFINE_DERIVED_FLOAT1_16BIT(ASinh16Bit, asinh, x, log(x + sqrt(x * x + constant((deFloat16)FLOAT16_1_0))));
 DEFINE_DERIVED_FLOAT1_16BIT(ACosh16Bit, acosh, x, log(x + sqrt(alternatives((x + constant((deFloat16)FLOAT16_1_0)) * (x - constant((deFloat16)FLOAT16_1_0)),
 																 (x * x - constant((deFloat16)FLOAT16_1_0))))));
@@ -6379,7 +6310,7 @@
 	funcs.addFactory(SharedPtr<const CaseFactory>(new GenFuncCaseFactory<typename F::Sig>(makeVectorizedFuncs<F>(), name)));
 }
 
-MovePtr<const CaseFactories> createBuiltinCases (bool is16BitTest = false)
+MovePtr<const CaseFactories> createBuiltinCases ()
 {
 	MovePtr<BuiltinFuncs>	funcs	(new BuiltinFuncs());
 
@@ -6396,16 +6327,8 @@
 	addScalarFactory<Cos<Signature<float, float> > >(*funcs);
 	addScalarFactory<Tan>(*funcs);
 
-	if (is16BitTest)
-		addScalarFactory<ASin16BitInOut32b>(*funcs);
-	else
-		addScalarFactory<ASin>(*funcs);
-
-	if (is16BitTest)
-		addScalarFactory<ACos16BitInOut32b>(*funcs);
-	else
-		addScalarFactory<ACos>(*funcs);
-
+	addScalarFactory<ASin>(*funcs);
+	addScalarFactory<ACos>(*funcs);
 	addScalarFactory<ATan2< Signature<float, float, float> > >(*funcs, "atan2");
 	addScalarFactory<ATan<Signature<float, float> > >(*funcs);
 	addScalarFactory<Sinh>(*funcs);
@@ -6591,7 +6514,7 @@
 	const int numRandoms	= userRandoms > 0 ? userRandoms : defRandoms;
 
 	MovePtr<const CaseFactories> cases = (test16Bit && !storage32Bit)	? createBuiltinCases16Bit()
-																		: createBuiltinCases(storage32Bit);
+																		: createBuiltinCases();
 	for (size_t ndx = 0; ndx < cases->getFactories().size(); ++ndx)
 	{
 		if (!test16Bit)
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinTests.cpp b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinTests.cpp
index c1f98b2..0a1a4c6 100644
--- a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinTests.cpp
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinTests.cpp
@@ -31,6 +31,7 @@
 #include "vktShaderCommonFunctionTests.hpp"
 #include "vktShaderIntegerFunctionTests.hpp"
 #include "vktShaderPackingFunctionTests.hpp"
+#include "vktShaderFConvertTests.hpp"
 
 namespace vkt
 {
@@ -50,6 +51,7 @@
 	builtinTests->addChild(new BuiltinPrecisionTests(testCtx));
 	builtinTests->addChild(new BuiltinPrecision16BitTests(testCtx));
 	builtinTests->addChild(new BuiltinPrecision16Storage32BitTests(testCtx));
+	builtinTests->addChild(createPrecisionFconvertGroup(testCtx));
 
 	return builtinTests.release();
 }
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.cpp b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.cpp
new file mode 100644
index 0000000..f577c66
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.cpp
@@ -0,0 +1,947 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Valve Corporation.
+ * Copyright (c) 2019 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 OpFConvert tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "vktShaderFConvertTests.hpp"
+#include "vktTestCase.hpp"
+
+#include "vkBufferWithMemory.hpp"
+#include "vkObjUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkPrograms.hpp"
+
+#include "deDefs.hpp"
+#include "deRandom.hpp"
+
+#include "tcuFloat.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuFormatUtil.hpp"
+
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <memory>
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <limits>
+
+namespace vkt
+{
+namespace shaderexecutor
+{
+
+namespace
+{
+
+constexpr deUint32	kRandomSeed								= 0xdeadbeef;
+constexpr size_t	kRandomSourcesPerType					= 240;
+constexpr size_t	kMinVectorLength						= 1;
+constexpr size_t	kMaxVectorLength						= 4;
+constexpr size_t	kArrayAlignment							= 16;					// Bytes.
+constexpr size_t	kEffectiveLength[kMaxVectorLength + 1]	= { 0, 1, 2, 4, 4 };	// Effective length of a vector of size i.
+constexpr size_t	kGCFNumFloats							= 12;					// Greatest Common Factor of the number of floats in a test.
+
+// Get a random normal number.
+// Works for implementations of tcu::Float as T.
+template <class T>
+T getRandomNormal (de::Random& rnd)
+{
+	static constexpr typename T::StorageType	kLeadingMantissaBit	= (static_cast<typename T::StorageType>(1) << T::MANTISSA_BITS);
+	static constexpr int						kSignValues[]		= { -1, 1 };
+
+	int						signBit		= rnd.getInt(0, 1);
+	int						exponent	= rnd.getInt(1 - T::EXPONENT_BIAS, T::EXPONENT_BIAS + 1);
+	typename T::StorageType	mantissa	= static_cast<typename T::StorageType>(rnd.getUint64() & static_cast<deUint64>(kLeadingMantissaBit - 1));
+
+	// Construct number.
+	return T::construct(kSignValues[signBit], exponent, (kLeadingMantissaBit | mantissa));
+}
+
+// Get a list of hand-picked interesting samples for tcu::Float class T.
+template <class T>
+const std::vector<T>& interestingSamples ()
+{
+	static const std::vector<T> samples =
+	{
+		T::zero				(-1),
+		T::zero				( 1),
+		//T::inf				(-1),
+		//T::inf				( 1),
+		//T::nan				(  ),
+		T::largestNormal	(-1),
+		T::largestNormal	( 1),
+		T::smallestNormal	(-1),
+		T::smallestNormal	( 1),
+	};
+
+	return samples;
+}
+
+// Get some random interesting numbers.
+// Works for implementations of tcu::Float as T.
+template <class T>
+std::vector<T> getRandomInteresting (de::Random& rnd, size_t numSamples)
+{
+	auto&			samples = interestingSamples<T>();
+	std::vector<T>	result;
+
+	result.reserve(numSamples);
+	std::generate_n(std::back_inserter(result), numSamples, [&rnd, &samples]() { return rnd.choose<T>(begin(samples), end(samples)); });
+
+	return result;
+}
+
+// Helper class to build each vector only once in a thread-safe way.
+template <class T>
+struct StaticVectorHelper
+{
+	std::vector<T> v;
+
+	StaticVectorHelper (de::Random& rnd)
+	{
+		v.reserve(kRandomSourcesPerType);
+		for (size_t i = 0; i < kRandomSourcesPerType; ++i)
+			v.push_back(getRandomNormal<T>(rnd));
+	}
+};
+
+// Get a list of random normal input values for type T.
+template <class T>
+const std::vector<T>& getRandomNormals (de::Random& rnd)
+{
+	static StaticVectorHelper<T> helper(rnd);
+	return helper.v;
+}
+
+// Convert a vector of tcu::Float elements of type T1 to type T2.
+template <class T1, class T2>
+std::vector<T2> convertVector (const std::vector<T1>& orig)
+{
+	std::vector<T2> result;
+	result.reserve(orig.size());
+
+	std::transform(begin(orig), end(orig), std::back_inserter(result),
+		[](T1 f) { return T2::convert(f); });
+
+	return result;
+}
+
+// Get converted normal values for other tcu::Float types smaller than T, which should be exact conversions when converting back to
+// those types.
+template <class T>
+std::vector<T> getOtherNormals (de::Random& rnd);
+
+template<>
+std::vector<tcu::Float16> getOtherNormals<tcu::Float16> (de::Random&)
+{
+	// Nothing below tcu::Float16.
+	return std::vector<tcu::Float16>();
+}
+
+template<>
+std::vector<tcu::Float32> getOtherNormals<tcu::Float32> (de::Random& rnd)
+{
+	// The ones from tcu::Float16.
+	return convertVector<tcu::Float16, tcu::Float32>(getRandomNormals<tcu::Float16>(rnd));
+}
+
+template<>
+std::vector<tcu::Float64> getOtherNormals<tcu::Float64> (de::Random& rnd)
+{
+	// The ones from both tcu::Float16 and tcu::Float64.
+	auto v1 = convertVector<tcu::Float16, tcu::Float64>(getRandomNormals<tcu::Float16>(rnd));
+	auto v2 = convertVector<tcu::Float32, tcu::Float64>(getRandomNormals<tcu::Float32>(rnd));
+
+	v1.reserve(v1.size() + v2.size());
+	std::copy(begin(v2), end(v2), std::back_inserter(v1));
+	return v1;
+}
+
+// Get the full list of input values for type T.
+template <class T>
+std::vector<T> getInputValues (de::Random& rnd)
+{
+	auto&	interesting		= interestingSamples<T>();
+	auto&	normals			= getRandomNormals<T>(rnd);
+	auto	otherNormals	= getOtherNormals<T>(rnd);
+
+	const size_t numValues		= interesting.size() + normals.size() + otherNormals.size();
+	const size_t extraValues	= numValues % kGCFNumFloats;
+	const size_t needed			= ((extraValues == 0) ? 0 : (kGCFNumFloats - extraValues));
+
+	auto extra = getRandomInteresting<T> (rnd, needed);
+
+	std::vector<T> values;
+	values.reserve(interesting.size() + normals.size() + otherNormals.size() + extra.size());
+
+	std::copy(begin(interesting),	end(interesting),	std::back_inserter(values));
+	std::copy(begin(normals),		end(normals),		std::back_inserter(values));
+	std::copy(begin(otherNormals),	end(otherNormals),	std::back_inserter(values));
+	std::copy(begin(extra),			end(extra),			std::back_inserter(values));
+
+	// Shuffle samples around a bit to make it more interesting.
+	rnd.shuffle(begin(values), end(values));
+
+	return values;
+}
+
+// This singleton makes sure generated samples are stable no matter the test order.
+class InputGenerator
+{
+public:
+	static const InputGenerator& getInstance ()
+	{
+		static InputGenerator instance;
+		return instance;
+	}
+
+	const std::vector<tcu::Float16>& getInputValues16 () const
+	{
+		return m_values16;
+	}
+
+	const std::vector<tcu::Float32>& getInputValues32 () const
+	{
+		return m_values32;
+	}
+
+	const std::vector<tcu::Float64>& getInputValues64 () const
+	{
+		return m_values64;
+	}
+
+private:
+	InputGenerator ()
+		: m_rnd(kRandomSeed)
+		, m_values16(getInputValues<tcu::Float16>(m_rnd))
+		, m_values32(getInputValues<tcu::Float32>(m_rnd))
+		, m_values64(getInputValues<tcu::Float64>(m_rnd))
+	{
+	}
+
+	// Cannot copy or assign.
+	InputGenerator(const InputGenerator&)				= delete;
+	InputGenerator& operator=(const InputGenerator&)	= delete;
+
+	de::Random					m_rnd;
+	std::vector<tcu::Float16>	m_values16;
+	std::vector<tcu::Float32>	m_values32;
+	std::vector<tcu::Float64>	m_values64;
+};
+
+// Check single result is as expected.
+// Works for implementations of tcu::Float as T1 and T2.
+template <class T1, class T2>
+bool validConversion (const T1& orig, const T2& result)
+{
+	const T2	acceptedResults[]	= { T2::convert(orig, tcu::ROUND_DOWNWARD), T2::convert(orig, tcu::ROUND_UPWARD) };
+	bool		valid				= false;
+
+	for (const auto& validResult : acceptedResults)
+	{
+		if (validResult.isNaN() && result.isNaN())
+			valid = true;
+		else if (validResult.isInf() && result.isInf())
+			valid = true;
+		else if (validResult.isZero() && result.isZero())
+			valid = true;
+		else if (validResult.isDenorm() && (result.isDenorm() || result.isZero()))
+			valid = true;
+		else if (validResult.bits() == result.bits()) // Exact conversion, up or down.
+			valid = true;
+	}
+
+	return valid;
+}
+
+// Check results vector is as expected.
+template <class T1, class T2>
+bool validConversion (const std::vector<T1>& orig, const std::vector<T2>& converted, tcu::TestLog& log)
+{
+	DE_ASSERT(orig.size() == converted.size());
+
+	bool allValid = true;
+
+	for (size_t i = 0; i < orig.size(); ++i)
+	{
+		const bool valid = validConversion(orig[i], converted[i]);
+
+		{
+			const double origD = orig[i].asDouble();
+			const double convD = converted[i].asDouble();
+
+			std::ostringstream msg;
+			msg << "[" << i << "] "
+				<< std::setprecision(std::numeric_limits<double>::digits10 + 2) << std::scientific
+				<< origD << " converted to " << convD << ": " << (valid ? "OK" : "FAILURE");
+
+			log << tcu::TestLog::Message << msg.str() << tcu::TestLog::EndMessage;
+		}
+
+		if (!valid)
+			allValid = false;
+	}
+
+	return allValid;
+}
+
+// Helps calculate buffer sizes and other parameters for the given number of values and vector length using a given floating point
+// type. This is mostly used in packFloats() below, but we also need this information in the iterate() method for the test instance,
+// so it has been separated.
+struct BufferSizeInfo
+{
+	template <class T>
+	static BufferSizeInfo calculate (size_t numValues_, size_t vectorLength_)
+	{
+		// The vector length must be a known number.
+		DE_ASSERT(vectorLength_ >= kMinVectorLength && vectorLength_ <= kMaxVectorLength);
+		// The number of values must be appropriate for the vector length.
+		DE_ASSERT(numValues_ % vectorLength_ == 0);
+
+		BufferSizeInfo info;
+
+		info.numValues		= numValues_;
+		info.vectorLength	= vectorLength_;
+		info.totalVectors	= numValues_ / vectorLength_;
+
+		const size_t elementSize		= sizeof(typename T::StorageType);
+		const size_t effectiveLength	= kEffectiveLength[vectorLength_];
+		const size_t vectorSize			= elementSize * effectiveLength;
+		const size_t extraBytes			= vectorSize % kArrayAlignment;
+
+		info.vectorStrideBytes	= vectorSize + ((extraBytes == 0) ? 0 : (kArrayAlignment - extraBytes));
+		info.memorySizeBytes	= info.vectorStrideBytes * info.totalVectors;
+
+		return info;
+	}
+
+	size_t numValues;
+	size_t vectorLength;
+	size_t totalVectors;
+	size_t vectorStrideBytes;
+	size_t memorySizeBytes;
+};
+
+// Pack an array of tcu::Float values into a buffer to be read from a shader, as if it was an array of vectors with each vector
+// having size vectorLength (e.g. 3 for a vec3). Note: assumes std140.
+template <class T>
+std::vector<deUint8> packFloats (const std::vector<T>& values, size_t vectorLength)
+{
+	BufferSizeInfo sizeInfo = BufferSizeInfo::calculate<T>(values.size(), vectorLength);
+
+	std::vector<deUint8> memory(sizeInfo.memorySizeBytes);
+	for (size_t i = 0; i < sizeInfo.totalVectors; ++i)
+	{
+		T* vectorPtr = reinterpret_cast<T*>(memory.data() + sizeInfo.vectorStrideBytes * i);
+		for (size_t j = 0; j < vectorLength; ++j)
+			vectorPtr[j] = values[i*vectorLength + j];
+	}
+
+	return memory;
+}
+
+// Unpack an array of vectors into an array of values, undoing what packFloats would do.
+// expectedNumValues is used for verification.
+template <class T>
+std::vector<T> unpackFloats (const std::vector<deUint8>& memory, size_t vectorLength, size_t expectedNumValues)
+{
+	DE_ASSERT(vectorLength >= kMinVectorLength && vectorLength <= kMaxVectorLength);
+
+	const size_t effectiveLength	= kEffectiveLength[vectorLength];
+	const size_t elementSize		= sizeof(typename T::StorageType);
+	const size_t vectorSize			= elementSize * effectiveLength;
+	const size_t extraBytes			= vectorSize % kArrayAlignment;
+	const size_t vectorBlockSize	= vectorSize + ((extraBytes == 0) ? 0 : (kArrayAlignment - extraBytes));
+
+	DE_ASSERT(memory.size() % vectorBlockSize == 0);
+	const size_t numStoredVectors	= memory.size() / vectorBlockSize;
+	const size_t numStoredValues	= numStoredVectors * vectorLength;
+
+	DE_UNREF(expectedNumValues); // For release builds.
+	DE_ASSERT(numStoredValues == expectedNumValues);
+	std::vector<T> values;
+	values.reserve(numStoredValues);
+
+	for (size_t i = 0; i < numStoredVectors; ++i)
+	{
+		const T* vectorPtr = reinterpret_cast<const T*>(memory.data() + vectorBlockSize * i);
+		for (size_t j = 0; j < vectorLength; ++j)
+			values.push_back(vectorPtr[j]);
+	}
+
+	return values;
+}
+
+enum FloatType
+{
+	FLOAT_TYPE_16_BITS = 0,
+	FLOAT_TYPE_32_BITS,
+	FLOAT_TYPE_64_BITS,
+	FLOAT_TYPE_MAX_ENUM,
+};
+
+static const char* const kFloatNames[FLOAT_TYPE_MAX_ENUM] =
+{
+	"f16",
+	"f32",
+	"f64",
+};
+
+static const char* const kGLSLTypes[][kMaxVectorLength + 1] =
+{
+	{ nullptr, "float16_t",	"f16vec2",	"f16vec3",	"f16vec4"	},
+	{ nullptr, "float",		"vec2",		"vec3",		"vec4"		},
+	{ nullptr, "double",	"dvec2",	"dvec3",	"dvec4"		},
+};
+
+struct TestParams
+{
+	FloatType	from;
+	FloatType	to;
+	size_t		vectorLength;
+
+	std::string	getInputTypeStr		() const
+	{
+		DE_ASSERT(from >= 0 && from < FLOAT_TYPE_MAX_ENUM);
+		DE_ASSERT(vectorLength >= kMinVectorLength && vectorLength <= kMaxVectorLength);
+		return kGLSLTypes[from][vectorLength];
+	}
+
+	std::string getOutputTypeStr	() const
+	{
+		DE_ASSERT(to >= 0 && to < FLOAT_TYPE_MAX_ENUM);
+		DE_ASSERT(vectorLength >= kMinVectorLength && vectorLength <= kMaxVectorLength);
+		return kGLSLTypes[to][vectorLength];
+	}
+};
+
+class FConvertTestInstance : public TestInstance
+{
+public:
+							FConvertTestInstance	(Context& context, const TestParams& params)
+								: TestInstance(context)
+								, m_params(params)
+								{}
+
+	virtual tcu::TestStatus	iterate					(void);
+
+private:
+	TestParams	m_params;
+};
+
+class FConvertTestCase : public TestCase
+{
+public:
+								FConvertTestCase	(tcu::TestContext& context, const std::string& name, const std::string& desc, const TestParams& params)
+									: TestCase	(context, name, desc)
+									, m_params	(params)
+									{}
+
+								~FConvertTestCase	(void) {}
+	virtual TestInstance*		createInstance		(Context& context) const { return new FConvertTestInstance(context, m_params); }
+	virtual	void				initPrograms		(vk::SourceCollections& programCollection) const;
+	virtual void				checkSupport		(Context& context) const;
+
+private:
+	TestParams	m_params;
+};
+
+void FConvertTestCase::initPrograms (vk::SourceCollections& programCollection) const
+{
+	const std::string		inputType		= m_params.getInputTypeStr();
+	const std::string		outputType		= m_params.getOutputTypeStr();
+	const InputGenerator&	inputGenerator	= InputGenerator::getInstance();
+
+	size_t numValues = 0;
+	switch (m_params.from)
+	{
+	case FLOAT_TYPE_16_BITS:
+		numValues = inputGenerator.getInputValues16().size();
+		break;
+	case FLOAT_TYPE_32_BITS:
+		numValues = inputGenerator.getInputValues32().size();
+		break;
+	case FLOAT_TYPE_64_BITS:
+		numValues = inputGenerator.getInputValues64().size();
+		break;
+	default:
+		DE_ASSERT(false);
+		break;
+	}
+
+	const size_t arraySize = numValues / m_params.vectorLength;
+
+	std::ostringstream shader;
+
+	shader
+		<< "#version 450 core\n"
+		<< ((m_params.from == FLOAT_TYPE_16_BITS || m_params.to == FLOAT_TYPE_16_BITS) ?
+			"#extension GL_EXT_shader_16bit_storage: require\n"					// This is needed to use 16-bit float types in buffers.
+			"#extension GL_EXT_shader_explicit_arithmetic_types: require\n"		// This is needed for some conversions.
+			: "")
+		<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+		<< "layout(set = 0, binding = 0, std140) buffer issbodef { " << inputType << " val[" << arraySize << "]; } issbo;\n"
+		<< "layout(set = 0, binding = 1, std140) buffer ossbodef { " << outputType << " val[" << arraySize << "]; } ossbo;\n"
+		<< "void main()\n"
+		<< "{\n"
+		<< "	ossbo.val[gl_WorkGroupID.x] = " << outputType << "(issbo.val[gl_WorkGroupID.x]);\n"
+		<< "}\n";
+
+	programCollection.glslSources.add("comp") << glu::ComputeSource(shader.str());
+}
+
+void FConvertTestCase::checkSupport (Context& context) const
+{
+	if (m_params.from == FLOAT_TYPE_64_BITS || m_params.to == FLOAT_TYPE_64_BITS)
+	{
+		// Check for 64-bit float support.
+		auto features = context.getDeviceFeatures();
+		if (!features.shaderFloat64)
+			TCU_THROW(NotSupportedError, "64-bit floats not supported in shader code");
+	}
+
+	if (m_params.from == FLOAT_TYPE_16_BITS || m_params.to == FLOAT_TYPE_16_BITS)
+	{
+		// Check for 16-bit float support.
+		auto& features16 = context.getShaderFloat16Int8Features();
+		if (!features16.shaderFloat16)
+			TCU_THROW(NotSupportedError, "16-bit floats not supported in shader code");
+
+		auto& storage16 = context.get16BitStorageFeatures();
+		if (!storage16.storageBuffer16BitAccess)
+			TCU_THROW(NotSupportedError, "16-bit floats not supported for storage buffers");
+	}
+}
+
+tcu::TestStatus FConvertTestInstance::iterate (void)
+{
+	BufferSizeInfo			inputBufferSizeInfo;
+	BufferSizeInfo			outputBufferSizeInfo;
+	std::vector<deUint8>	inputMemory;
+
+	// Calculate buffer sizes and convert input values to a packed input memory format, depending on the input and output types.
+	switch (m_params.from)
+	{
+	case FLOAT_TYPE_16_BITS:
+		{
+			auto& inputValues = InputGenerator::getInstance().getInputValues16();
+			inputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float16>(inputValues.size(), m_params.vectorLength);
+			switch (m_params.to)
+			{
+			case FLOAT_TYPE_32_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float32>(inputValues.size(), m_params.vectorLength);
+				break;
+			case FLOAT_TYPE_64_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float64>(inputValues.size(), m_params.vectorLength);
+				break;
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+			inputMemory = packFloats(inputValues, m_params.vectorLength);
+		}
+		break;
+
+	case FLOAT_TYPE_32_BITS:
+		{
+			auto& inputValues = InputGenerator::getInstance().getInputValues32();
+			inputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float32>(inputValues.size(), m_params.vectorLength);
+			switch (m_params.to)
+			{
+			case FLOAT_TYPE_16_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float16>(inputValues.size(), m_params.vectorLength);
+				break;
+			case FLOAT_TYPE_64_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float64>(inputValues.size(), m_params.vectorLength);
+				break;
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+			inputMemory = packFloats(inputValues, m_params.vectorLength);
+		}
+		break;
+
+	case FLOAT_TYPE_64_BITS:
+		{
+			auto& inputValues = InputGenerator::getInstance().getInputValues64();
+			inputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float64>(inputValues.size(), m_params.vectorLength);
+			switch (m_params.to)
+			{
+			case FLOAT_TYPE_16_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float16>(inputValues.size(), m_params.vectorLength);
+				break;
+			case FLOAT_TYPE_32_BITS:
+				outputBufferSizeInfo = BufferSizeInfo::calculate<tcu::Float32>(inputValues.size(), m_params.vectorLength);
+				break;
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+			inputMemory = packFloats(inputValues, m_params.vectorLength);
+		}
+		break;
+
+	default:
+		DE_ASSERT(false);
+		break;
+	}
+
+	// Prepare input and output buffers.
+	auto&	vkd			= m_context.getDeviceInterface();
+	auto	device		= m_context.getDevice();
+	auto&	allocator	= m_context.getDefaultAllocator();
+
+	de::MovePtr<vk::BufferWithMemory> inputBuffer(
+		new vk::BufferWithMemory(vkd, device, allocator,
+								 vk::makeBufferCreateInfo(inputBufferSizeInfo.memorySizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
+								 vk::MemoryRequirement::HostVisible)
+	);
+
+	de::MovePtr<vk::BufferWithMemory> outputBuffer(
+		new vk::BufferWithMemory(vkd, device, allocator,
+								 vk::makeBufferCreateInfo(outputBufferSizeInfo.memorySizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
+								 vk::MemoryRequirement::HostVisible)
+	);
+
+	// Copy values to input buffer.
+	{
+		auto& alloc = inputBuffer->getAllocation();
+		deMemcpy(reinterpret_cast<deUint8*>(alloc.getHostPtr()) + alloc.getOffset(), inputMemory.data(), inputMemory.size());
+		vk::flushAlloc(vkd, device, alloc);
+	}
+
+	// Create an array with the input and output buffers to make it easier to iterate below.
+	const vk::VkBuffer buffers[] = { inputBuffer->get(), outputBuffer->get() };
+
+	// Create descriptor set layout.
+	std::vector<vk::VkDescriptorSetLayoutBinding> bindings;
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(buffers); ++i)
+	{
+		const vk::VkDescriptorSetLayoutBinding binding =
+		{
+			static_cast<deUint32>(i),								// uint32_t              binding;
+			vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,					// VkDescriptorType      descriptorType;
+			1u,														// uint32_t              descriptorCount;
+			vk::VK_SHADER_STAGE_COMPUTE_BIT,						// VkShaderStageFlags    stageFlags;
+			DE_NULL,													// const VkSampler*      pImmutableSamplers;
+		};
+		bindings.push_back(binding);
+	}
+
+	const vk::VkDescriptorSetLayoutCreateInfo layoutCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType                        sType;
+		DE_NULL,													// const void*                            pNext;
+		0,															// VkDescriptorSetLayoutCreateFlags       flags;
+		static_cast<deUint32>(bindings.size()),						// uint32_t                               bindingCount;
+		bindings.data()												// const VkDescriptorSetLayoutBinding*    pBindings;
+	};
+	auto descriptorSetLayout = vk::createDescriptorSetLayout(vkd, device, &layoutCreateInfo);
+
+	// Create descriptor set.
+	vk::DescriptorPoolBuilder poolBuilder;
+	for (const auto& b : bindings)
+		poolBuilder.addType(b.descriptorType, 1u);
+	auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+	const vk::VkDescriptorSetAllocateInfo allocateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                 sType;
+		DE_NULL,											// const void*                     pNext;
+		*descriptorPool,									// VkDescriptorPool                descriptorPool;
+		1u,													// uint32_t                        descriptorSetCount;
+		&descriptorSetLayout.get()							// const VkDescriptorSetLayout*    pSetLayouts;
+	};
+	auto descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
+
+	// Update descriptor set.
+	std::vector<vk::VkDescriptorBufferInfo>	descriptorBufferInfos;
+	std::vector<vk::VkWriteDescriptorSet>	descriptorWrites;
+
+	for (const auto& buffer : buffers)
+	{
+		const vk::VkDescriptorBufferInfo bufferInfo =
+		{
+			buffer,			// VkBuffer        buffer;
+			0u,				// VkDeviceSize    offset;
+			VK_WHOLE_SIZE,	// VkDeviceSize    range;
+		};
+		descriptorBufferInfos.push_back(bufferInfo);
+	}
+
+	for (size_t i = 0; i < bindings.size(); ++i)
+	{
+		const vk::VkWriteDescriptorSet write =
+		{
+			vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType                  sType;
+			DE_NULL,									// const void*                      pNext;
+			*descriptorSet,								// VkDescriptorSet                  dstSet;
+			static_cast<deUint32>(i),					// uint32_t                         dstBinding;
+			0u,											// uint32_t                         dstArrayElement;
+			1u,											// uint32_t                         descriptorCount;
+			bindings[i].descriptorType,					// VkDescriptorType                 descriptorType;
+			DE_NULL,									// const VkDescriptorImageInfo*     pImageInfo;
+			&descriptorBufferInfos[i],					// const VkDescriptorBufferInfo*    pBufferInfo;
+			DE_NULL,									// const VkBufferView*              pTexelBufferView;
+		};
+		descriptorWrites.push_back(write);
+	}
+	vkd.updateDescriptorSets(device, static_cast<deUint32>(descriptorWrites.size()), descriptorWrites.data(), 0u, DE_NULL);
+
+	// Prepare barriers in advance so data is visible to the shaders and the host.
+	std::vector<vk::VkBufferMemoryBarrier> hostToDevBarriers;
+	std::vector<vk::VkBufferMemoryBarrier> devToHostBarriers;
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(buffers); ++i)
+	{
+		const vk::VkBufferMemoryBarrier hostToDev =
+		{
+			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,						// VkStructureType	sType;
+			DE_NULL,															// const void*		pNext;
+			vk::VK_ACCESS_HOST_WRITE_BIT,										// VkAccessFlags	srcAccessMask;
+			(vk::VK_ACCESS_SHADER_READ_BIT | vk::VK_ACCESS_SHADER_WRITE_BIT),	// VkAccessFlags	dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,											// deUint32			srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,											// deUint32			dstQueueFamilyIndex;
+			buffers[i],															// VkBuffer			buffer;
+			0u,																	// VkDeviceSize		offset;
+			VK_WHOLE_SIZE,														// VkDeviceSize		size;
+		};
+		hostToDevBarriers.push_back(hostToDev);
+
+		const vk::VkBufferMemoryBarrier devToHost =
+		{
+			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,						// VkStructureType	sType;
+			DE_NULL,															// const void*		pNext;
+			vk::VK_ACCESS_SHADER_WRITE_BIT,										// VkAccessFlags	srcAccessMask;
+			vk::VK_ACCESS_HOST_READ_BIT,										// VkAccessFlags	dstAccessMask;
+			VK_QUEUE_FAMILY_IGNORED,											// deUint32			srcQueueFamilyIndex;
+			VK_QUEUE_FAMILY_IGNORED,											// deUint32			dstQueueFamilyIndex;
+			buffers[i],															// VkBuffer			buffer;
+			0u,																	// VkDeviceSize		offset;
+			VK_WHOLE_SIZE,														// VkDeviceSize		size;
+		};
+		devToHostBarriers.push_back(devToHost);
+	}
+
+	// Create command pool and command buffer.
+	auto queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+
+	const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// VkStructureType				sType;
+		DE_NULL,										// const void*					pNext;
+		vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,		// VkCommandPoolCreateFlags		flags;
+		queueFamilyIndex,								// deUint32						queueFamilyIndex;
+	};
+	auto cmdPool = vk::createCommandPool(vkd, device, &cmdPoolCreateInfo);
+
+	const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
+		DE_NULL,											// const void*				pNext;
+		*cmdPool,											// VkCommandPool			commandPool;
+		vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
+		1u,													// deUint32					commandBufferCount;
+	};
+	auto cmdBuffer = vk::allocateCommandBuffer(vkd, device, &cmdBufferAllocateInfo);
+
+	// Create pipeline layout.
+	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
+		DE_NULL,											// const void*						pNext;
+		0,													// VkPipelineLayoutCreateFlags		flags;
+		1u,													// deUint32							setLayoutCount;
+		&descriptorSetLayout.get(),							// const VkDescriptorSetLayout*		pSetLayouts;
+		0u,													// deUint32							pushConstantRangeCount;
+		DE_NULL,											// const VkPushConstantRange*		pPushConstantRanges;
+	};
+	auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
+
+	// Create compute pipeline.
+	const vk::Unique<vk::VkShaderModule> shader(vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0));
+
+	const vk::VkComputePipelineCreateInfo computeCreateInfo =
+	{
+		vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType                    sType;
+		DE_NULL,											// const void*                        pNext;
+		0,													// VkPipelineCreateFlags              flags;
+		{													// VkPipelineShaderStageCreateInfo    stage;
+			vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
+			DE_NULL,													// const void*                         pNext;
+			0,															// VkPipelineShaderStageCreateFlags    flags;
+			vk::VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits               stage;
+			*shader,													// VkShaderModule                      module;
+			"main",														// const char*                         pName;
+			DE_NULL,													// const VkSpecializationInfo*         pSpecializationInfo;
+		},
+		*pipelineLayout,									// VkPipelineLayout                   layout;
+		DE_NULL,											// VkPipeline                         basePipelineHandle;
+		0,													// int32_t                            basePipelineIndex;
+	};
+	auto computePipeline = vk::createComputePipeline(vkd, device, DE_NULL, &computeCreateInfo);
+
+	// Run the shader.
+	vk::beginCommandBuffer(vkd, *cmdBuffer);
+		vkd.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
+		vkd.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &descriptorSet.get(), 0u, DE_NULL);
+		vkd.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0u, DE_NULL, static_cast<deUint32>(hostToDevBarriers.size()), hostToDevBarriers.data(), 0u, DE_NULL);
+		vkd.cmdDispatch(*cmdBuffer, static_cast<deUint32>(inputBufferSizeInfo.totalVectors), 1u, 1u);
+		vkd.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0, 0u, DE_NULL, static_cast<deUint32>(devToHostBarriers.size()), devToHostBarriers.data(), 0u, DE_NULL);
+	vk::endCommandBuffer(vkd, *cmdBuffer);
+	vk::submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
+
+	// Invalidate output allocation.
+	vk::invalidateAlloc(vkd, device, outputBuffer->getAllocation());
+
+	// Copy output buffer data.
+	std::vector<deUint8> outputMemory(outputBufferSizeInfo.memorySizeBytes);
+	{
+		auto& alloc = outputBuffer->getAllocation();
+		deMemcpy(outputMemory.data(), reinterpret_cast<deUint8*>(alloc.getHostPtr()) + alloc.getOffset(), outputBufferSizeInfo.memorySizeBytes);
+	}
+
+	// Unpack and verify output data.
+	auto& testLog = m_context.getTestContext().getLog();
+	bool conversionOk = false;
+	switch (m_params.to)
+	{
+	case FLOAT_TYPE_16_BITS:
+		{
+			auto outputValues = unpackFloats<tcu::Float16>(outputMemory, m_params.vectorLength, inputBufferSizeInfo.numValues);
+			switch (m_params.from)
+			{
+			case FLOAT_TYPE_32_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues32();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			case FLOAT_TYPE_64_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues64();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+		}
+		break;
+
+	case FLOAT_TYPE_32_BITS:
+		{
+			auto outputValues = unpackFloats<tcu::Float32>(outputMemory, m_params.vectorLength, inputBufferSizeInfo.numValues);
+			switch (m_params.from)
+			{
+			case FLOAT_TYPE_16_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues16();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			case FLOAT_TYPE_64_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues64();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+		}
+		break;
+
+	case FLOAT_TYPE_64_BITS:
+		{
+			auto outputValues = unpackFloats<tcu::Float64>(outputMemory, m_params.vectorLength, inputBufferSizeInfo.numValues);
+			switch (m_params.from)
+			{
+			case FLOAT_TYPE_16_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues16();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			case FLOAT_TYPE_32_BITS:
+				{
+					auto& inputValues = InputGenerator::getInstance().getInputValues32();
+					conversionOk = validConversion(inputValues, outputValues, testLog);
+				}
+				break;
+
+			default:
+				DE_ASSERT(false);
+				break;
+			}
+		}
+		break;
+
+	default:
+		DE_ASSERT(false);
+		break;
+	}
+
+	return (conversionOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail"));
+}
+
+} // anonymous
+
+tcu::TestCaseGroup*	createPrecisionFconvertGroup (tcu::TestContext& testCtx)
+{
+	tcu::TestCaseGroup* newGroup = new tcu::TestCaseGroup(testCtx, "precision_fconvert", "OpFConvert precision tests");
+
+	for (int i = 0; i < FLOAT_TYPE_MAX_ENUM; ++i)
+	for (int j = 0; j < FLOAT_TYPE_MAX_ENUM; ++j)
+	for (size_t k = kMinVectorLength; k <= kMaxVectorLength; ++k)
+	{
+		// No actual conversion if the types are the same.
+		if (i == j)
+			continue;
+
+		TestParams params = {
+			static_cast<FloatType>(i),
+			static_cast<FloatType>(j),
+			k,
+		};
+
+		std::string testName = std::string() + kFloatNames[i] + "_to_" + kFloatNames[j] + "_size_" + std::to_string(k);
+		std::string testDescription = std::string("Conversion from ") + kFloatNames[i] + " to " + kFloatNames[j] + " with vectors of size " + std::to_string(k);
+
+		newGroup->addChild(new FConvertTestCase(testCtx, testName, testDescription, params));
+	}
+
+	return newGroup;
+}
+
+} // shaderexecutor
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.hpp b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.hpp
new file mode 100644
index 0000000..7c13e6e
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/shaderexecutor/vktShaderFConvertTests.hpp
@@ -0,0 +1,40 @@
+#ifndef _VKTSHADERFCONVERTTESTS_HPP
+#define _VKTSHADERFCONVERTTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 Valve Corporation.
+ * Copyright (c) 2019 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 OpFConvert tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace shaderexecutor
+{
+
+tcu::TestCaseGroup*	createPrecisionFconvertGroup (tcu::TestContext& testCtx);
+
+} // shaderexecutor
+} // vkt
+
+#endif // _VKTSHADERFCONVERTTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDiscardTests.cpp b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDiscardTests.cpp
index 8af40be..750d354 100644
--- a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDiscardTests.cpp
+++ b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDiscardTests.cpp
@@ -156,7 +156,7 @@
 
 void ShaderDiscardCase::checkSupport(Context& context) const
 {
-	if (m_demote && !context.getShaderDemoteToHelperInvocationFeatures().shaderDemoteToHelperInvocation)
+	if (m_demote && !context.getShaderDemoteToHelperInvocationFeaturesEXT().shaderDemoteToHelperInvocation)
 		TCU_THROW(NotSupportedError, "VK_EXT_shader_demote_to_helper_invocation not supported");
 }
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBase.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBase.cpp
index 4476c3f..9676539 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBase.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBase.cpp
@@ -46,9 +46,9 @@
 	deUint32 queueCount;
 };
 
-deUint32 findMatchingQueueFamilyIndex (const std::vector<vk::VkQueueFamilyProperties>&	queueFamilyProperties,
-									   const VkQueueFlags								queueFlags,
-									   const deUint32									startIndex)
+deUint32 findMatchingQueueFamilyIndex	(const std::vector<VkQueueFamilyProperties>&	queueFamilyProperties,
+										 const VkQueueFlags								queueFlags,
+										 const deUint32									startIndex)
 {
 	for (deUint32 queueNdx = startIndex; queueNdx < queueFamilyProperties.size(); ++queueNdx)
 	{
@@ -63,13 +63,13 @@
 
 void SparseResourcesBaseInstance::createDeviceSupportingQueues(const QueueRequirementsVec& queueRequirements)
 {
-	typedef std::map<vk::VkQueueFlags, std::vector<Queue> >		QueuesMap;
-	typedef std::map<deUint32, QueueFamilyQueuesCount>			SelectedQueuesMap;
-	typedef std::map<deUint32, std::vector<float> >				QueuePrioritiesMap;
+	typedef std::map<VkQueueFlags, std::vector<Queue> >	QueuesMap;
+	typedef std::map<deUint32, QueueFamilyQueuesCount>	SelectedQueuesMap;
+	typedef std::map<deUint32, std::vector<float> >		QueuePrioritiesMap;
 
-	std::vector<VkPhysicalDeviceGroupProperties>				devGroupProperties;
-	std::vector<const char*>									deviceExtensions;
-	VkDeviceGroupDeviceCreateInfo								deviceGroupInfo =
+	std::vector<VkPhysicalDeviceGroupProperties>		devGroupProperties;
+	std::vector<const char*>							deviceExtensions;
+	VkDeviceGroupDeviceCreateInfo						deviceGroupInfo =
 	{
 		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,		//stype
 		DE_NULL,													//pNext
@@ -163,12 +163,12 @@
 
 		const VkDeviceQueueCreateInfo queueInfo =
 		{
-			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType             sType;
-			DE_NULL,										// const void*                 pNext;
-			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags    flags;
-			queueFamilyIter->first,							// uint32_t                    queueFamilyIndex;
-			queueFamilyIter->second.queueCount,				// uint32_t                    queueCount;
-			&queuePriorities[queueFamilyIter->first][0],	// const float*                pQueuePriorities;
+			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType			sType;
+			DE_NULL,										// const void*				pNext;
+			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags	flags;
+			queueFamilyIter->first,							// uint32_t					queueFamilyIndex;
+			queueFamilyIter->second.queueCount,				// uint32_t					queueCount;
+			&queuePriorities[queueFamilyIter->first][0],	// const float*				pQueuePriorities;
 		};
 
 		queueInfos.push_back(queueInfo);
@@ -177,16 +177,16 @@
 	const VkPhysicalDeviceFeatures	deviceFeatures	= getPhysicalDeviceFeatures(instanceDriver, physicalDevice);
 	const VkDeviceCreateInfo		deviceInfo		=
 	{
-		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,						// VkStructureType                    sType;
-		m_useDeviceGroups ? &deviceGroupInfo : DE_NULL,				// const void*                        pNext;
-		(VkDeviceCreateFlags)0,										// VkDeviceCreateFlags                flags;
-		static_cast<deUint32>(queueInfos.size())	,				// uint32_t                           queueCreateInfoCount;
-		&queueInfos[0],												// const VkDeviceQueueCreateInfo*     pQueueCreateInfos;
-		0u,															// uint32_t                           enabledLayerCount;
-		DE_NULL,													// const char* const*                 ppEnabledLayerNames;
-		deUint32(deviceExtensions.size()),							// uint32_t                           enabledExtensionCount;
-		deviceExtensions.size() ? &deviceExtensions[0] : DE_NULL,	// const char* const*                 ppEnabledExtensionNames;
-		&deviceFeatures,											// const VkPhysicalDeviceFeatures*    pEnabledFeatures;
+		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,						// VkStructureType					sType;
+		m_useDeviceGroups ? &deviceGroupInfo : DE_NULL,				// const void*						pNext;
+		(VkDeviceCreateFlags)0,										// VkDeviceCreateFlags				flags;
+		static_cast<deUint32>(queueInfos.size())	,				// uint32_t							queueCreateInfoCount;
+		&queueInfos[0],												// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
+		0u,															// uint32_t							enabledLayerCount;
+		DE_NULL,													// const char* const*				ppEnabledLayerNames;
+		deUint32(deviceExtensions.size()),							// uint32_t							enabledExtensionCount;
+		deviceExtensions.size() ? &deviceExtensions[0] : DE_NULL,	// const char* const*				ppEnabledExtensionNames;
+		&deviceFeatures,											// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
 	};
 
 	m_logicalDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), instance, instanceDriver, physicalDevice, &deviceInfo);
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp
index 24ae508..1c666c3 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp
@@ -299,7 +299,7 @@
 		const Unique<VkBuffer>			outputBuffer(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
 
-		// Create command buffer for compute and data transfer oparations
+		// Create command buffer for compute and data transfer operations
 		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
 		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp
index d32af1c..103a0d3 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp
@@ -246,7 +246,7 @@
 			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
 		}
 
-		// Create command buffer for transfer oparations
+		// Create command buffer for transfer operations
 		const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
 		const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseResidency.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseResidency.cpp
index d8c3cf7..587f7fd 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseResidency.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseResidency.cpp
@@ -292,7 +292,7 @@
 		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
 
-		// Create command buffer for compute and data transfer oparations
+		// Create command buffer for compute and data transfer operations
 		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
 		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageAlignedMipSize.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageAlignedMipSize.cpp
index 3767d9f..d1ae4a9 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageAlignedMipSize.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageAlignedMipSize.cpp
@@ -56,29 +56,29 @@
 class ImageAlignedMipSizeCase : public TestCase
 {
 public:
-					ImageAlignedMipSizeCase	(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const std::string&			description,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format);
+	ImageAlignedMipSizeCase			(tcu::TestContext&	testCtx,
+									 const std::string&	name,
+									 const std::string&	description,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format);
 
-	void			initPrograms			(SourceCollections&			sourceCollections) const {DE_UNREF(sourceCollections);};
-	TestInstance*	createInstance			(Context&					context) const;
-	virtual void	checkSupport			(Context&					context) const;
+	void			initPrograms	(SourceCollections&	sourceCollections) const {DE_UNREF(sourceCollections);};
+	TestInstance*	createInstance	(Context&			context) const;
+	virtual void	checkSupport	(Context&			context) const;
 
 private:
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageAlignedMipSizeCase::ImageAlignedMipSizeCase (tcu::TestContext&			testCtx,
-												  const std::string&		name,
-												  const std::string&		description,
-												  const ImageType			imageType,
-												  const tcu::UVec3&			imageSize,
-												  const tcu::TextureFormat&	format)
+ImageAlignedMipSizeCase::ImageAlignedMipSizeCase	(tcu::TestContext&	testCtx,
+													 const std::string&	name,
+													 const std::string&	description,
+													 const ImageType	imageType,
+													 const tcu::UVec3&	imageSize,
+													 const VkFormat		format)
 	: TestCase		(testCtx, name, description)
 	, m_imageType	(imageType)
 	, m_imageSize	(imageSize)
@@ -103,23 +103,23 @@
 class ImageAlignedMipSizeInstance : public SparseResourcesBaseInstance
 {
 public:
-					ImageAlignedMipSizeInstance(Context&					context,
-												const ImageType				imageType,
-												const tcu::UVec3&			imageSize,
-												const tcu::TextureFormat&	format);
+	ImageAlignedMipSizeInstance	(Context&			context,
+								 const ImageType	imageType,
+								 const tcu::UVec3&	imageSize,
+								 const VkFormat		format);
 
-	tcu::TestStatus	iterate						(void);
+	tcu::TestStatus	iterate		(void);
 
 private:
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageAlignedMipSizeInstance::ImageAlignedMipSizeInstance (Context&					context,
-														  const ImageType			imageType,
-														  const tcu::UVec3&			imageSize,
-														  const tcu::TextureFormat&	format)
+ImageAlignedMipSizeInstance::ImageAlignedMipSizeInstance	(Context&			context,
+															 const ImageType	imageType,
+															 const tcu::UVec3&	imageSize,
+															 const VkFormat		format)
 	: SparseResourcesBaseInstance	(context)
 	, m_imageType					(imageType)
 	, m_imageSize					(imageSize)
@@ -129,20 +129,21 @@
 
 tcu::TestStatus ImageAlignedMipSizeInstance::iterate (void)
 {
-	const InstanceInterface&				instance = m_context.getInstanceInterface();
-	const VkPhysicalDevice					physicalDevice = m_context.getPhysicalDevice();
-	const VkPhysicalDeviceProperties		physicalDeviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
+	const InstanceInterface&				instance					= m_context.getInstanceInterface();
+	const VkPhysicalDevice					physicalDevice				= m_context.getPhysicalDevice();
+	const VkPhysicalDeviceProperties		physicalDeviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
 	VkImageCreateInfo						imageCreateInfo;
 	VkSparseImageMemoryRequirements			aspectRequirements;
 	VkExtent3D								imageGranularity;
-	const VkPhysicalDeviceSparseProperties	sparseProperties = physicalDeviceProperties.sparseProperties;
-	VkImageFormatProperties					imageFormatProperties;
+	const VkPhysicalDeviceSparseProperties	sparseProperties			= physicalDeviceProperties.sparseProperties;
+	const PlanarFormatDescription			formatDescription			= getPlanarFormatDescription(m_format);
+
 
 	imageCreateInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
 	imageCreateInfo.pNext					= DE_NULL;
 	imageCreateInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 	imageCreateInfo.imageType				= mapImageType(m_imageType);
-	imageCreateInfo.format					= mapTextureFormat(m_format);
+	imageCreateInfo.format					= m_format;
 	imageCreateInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 	imageCreateInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
 	imageCreateInfo.samples					= VK_SAMPLE_COUNT_1_BIT;
@@ -159,15 +160,28 @@
 		imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 	}
 
-	imageFormatProperties = getPhysicalDeviceImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags);
-
-	imageCreateInfo.mipLevels				= getImageMaxMipLevels(imageFormatProperties, imageCreateInfo.extent);
-
 	// Check if device supports sparse operations for image format
 	if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageCreateInfo))
 		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
 
 	{
+		VkImageFormatProperties imageFormatProperties;
+
+		if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+			imageCreateInfo.format,
+			imageCreateInfo.imageType,
+			imageCreateInfo.tiling,
+			imageCreateInfo.usage,
+			imageCreateInfo.flags,
+			&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+		{
+			TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+		}
+
+		imageCreateInfo.mipLevels = getMipmapCount(m_format, formatDescription, imageFormatProperties, imageCreateInfo.extent);
+	}
+
+	{
 		QueueRequirementsVec queueRequirements;
 		queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
 
@@ -178,10 +192,10 @@
 		const DeviceInterface&								deviceInterface				= getDeviceInterface();
 
 		// Create sparse image
-		const Unique<VkImage>								sparseImage					(createImage(deviceInterface, getDevice(), &imageCreateInfo));
+		const Unique<VkImage>								imageSparse					(createImage(deviceInterface, getDevice(), &imageCreateInfo));
 
 		// Get sparse image sparse memory requirements
-		const std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements	= getImageSparseMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
+		const std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements	= getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
 		DE_ASSERT(sparseMemoryRequirements.size() != 0);
 
@@ -202,9 +216,9 @@
 		do
 		{
 			extent = mipLevelExtents(imageCreateInfo.extent, lod);
-			if (extent.width % imageGranularity.width != 0
+			if (   extent.width  % imageGranularity.width  != 0
 				|| extent.height % imageGranularity.height != 0
-				|| extent.depth % imageGranularity.depth != 0)
+				|| extent.depth  % imageGranularity.depth  != 0)
 			{
 				break;
 			}
@@ -239,44 +253,32 @@
 {
 	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "aligned_mip_size", "Aligned mip size"));
 
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSize;
+		{ IMAGE_TYPE_2D,		 { tcu::UVec3(512u, 256u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,	 { tcu::UVec3(512u, 256u, 6u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,		 { tcu::UVec3(256u, 256u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY, { tcu::UVec3(256u, 256u, 6u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,		 { tcu::UVec3(512u, 256u, 16u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
-	static const ImageParameters imageParametersArray[] =
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		{ IMAGE_TYPE_2D,		 tcu::UVec3(512u, 256u, 1u)		},
-		{ IMAGE_TYPE_2D_ARRAY,	 tcu::UVec3(512u, 256u, 6u)		},
-		{ IMAGE_TYPE_CUBE,		 tcu::UVec3(256u, 256u, 1u)		},
-		{ IMAGE_TYPE_CUBE_ARRAY, tcu::UVec3(256u, 256u, 6u)		},
-		{ IMAGE_TYPE_3D,		 tcu::UVec3(512u, 256u, 16u)	}
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RG,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
-	};
-
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
-	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
+		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
 		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&	format		= formats[formatNdx];
-			const tcu::UVec3			imageSize	= imageParametersArray[imageTypeNdx].imageSize;
-			const std::string			name		= getShaderImageFormatQualifier(format);
+			VkFormat			format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3			imageSizeAlignment	= getImageSizeAlignment(format);
+			const std::string	name				= getImageFormatID(format);
+			const tcu::UVec3	imageSize			= imageParameters[imageTypeNdx].imageSizes[0];
+
+			// skip test for images with odd sizes for some YCbCr formats
+			if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+				continue;
+			if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+				continue;
 
 			imageTypeGroup->addChild(new ImageAlignedMipSizeCase(testCtx, name.c_str(), "", imageType, imageSize, format));
 		}
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageBlockShapes.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageBlockShapes.cpp
index 60dc98c..79feb21 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageBlockShapes.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageBlockShapes.cpp
@@ -56,37 +56,37 @@
 class ImageBlockShapesCase : public TestCase
 {
 public:
-					ImageBlockShapesCase	(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const std::string&			description,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format,
-											 deUint32					numSamples);
+	ImageBlockShapesCase			(tcu::TestContext&	testCtx,
+									 const std::string&	name,
+									 const std::string&	description,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format,
+									 deUint32			numSamples);
 
 	void			initPrograms			(SourceCollections&			sourceCollections) const {DE_UNREF(sourceCollections);};
 	TestInstance*	createInstance			(Context&					context) const;
 	virtual void	checkSupport			(Context&					context) const;
 
 private:
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
-	const deUint32				m_numSamples;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
+	const deUint32		m_numSamples;
 };
 
-ImageBlockShapesCase::ImageBlockShapesCase (tcu::TestContext&			testCtx,
-											const std::string&			name,
-											const std::string&			description,
-											const ImageType				imageType,
-											const tcu::UVec3&			imageSize,
-											const tcu::TextureFormat&	format,
-											deUint32					numSamples)
-	: TestCase				(testCtx, name, description)
-	, m_imageType			(imageType)
-	, m_imageSize			(imageSize)
-	, m_format				(format)
-	, m_numSamples			(numSamples)
+ImageBlockShapesCase::ImageBlockShapesCase (tcu::TestContext&	testCtx,
+											const std::string&	name,
+											const std::string&	description,
+											const ImageType		imageType,
+											const tcu::UVec3&	imageSize,
+											const VkFormat		format,
+											deUint32			numSamples)
+	: TestCase		(testCtx, name, description)
+	, m_imageType	(imageType)
+	, m_imageSize	(imageSize)
+	, m_format		(format)
+	, m_numSamples	(numSamples)
 {
 }
 
@@ -107,26 +107,26 @@
 class ImageBlockShapesInstance : public SparseResourcesBaseInstance
 {
 public:
-					ImageBlockShapesInstance(Context&							context,
-											 const ImageType					imageType,
-											 const tcu::UVec3&					imageSize,
-											 const tcu::TextureFormat&			format,
-											 deUint32							numSamples);
+	ImageBlockShapesInstance	(Context&			context,
+								 const ImageType	imageType,
+								 const tcu::UVec3&	imageSize,
+								 const VkFormat		format,
+								 deUint32			numSamples);
 
-	tcu::TestStatus	iterate						(void);
+	tcu::TestStatus	iterate		(void);
 
 private:
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
-	const deUint32				m_numSamples;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
+	const deUint32		m_numSamples;
 };
 
-ImageBlockShapesInstance::ImageBlockShapesInstance (Context&					context,
-													const ImageType				imageType,
-													const tcu::UVec3&			imageSize,
-													const tcu::TextureFormat&	format,
-													deUint32					numSamples)
+ImageBlockShapesInstance::ImageBlockShapesInstance (Context&			context,
+													const ImageType		imageType,
+													const tcu::UVec3&	imageSize,
+													const VkFormat		format,
+													deUint32			numSamples)
 	: SparseResourcesBaseInstance	(context)
 	, m_imageType					(imageType)
 	, m_imageSize					(imageSize)
@@ -137,21 +137,19 @@
 
 tcu::TestStatus ImageBlockShapesInstance::iterate (void)
 {
-	const InstanceInterface&				instance = m_context.getInstanceInterface();
-	const VkPhysicalDevice					physicalDevice = m_context.getPhysicalDevice();
-	const VkPhysicalDeviceProperties		physicalDeviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
-	VkImageCreateInfo						imageCreateInfo;
-	VkSparseImageMemoryRequirements			aspectRequirements;
-	VkExtent3D								imageGranularity;
-	const VkPhysicalDeviceSparseProperties	sparseProperties = physicalDeviceProperties.sparseProperties;
-	const deUint32							pixelSize = tcu::getPixelSize(m_format) * 8;
-	VkExtent3D								expectedGranularity;
+	const InstanceInterface&						instance					= m_context.getInstanceInterface();
+	const VkPhysicalDevice							physicalDevice				= m_context.getPhysicalDevice();
+	const VkPhysicalDeviceProperties				physicalDeviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
+	VkImageCreateInfo								imageCreateInfo;
+	std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements;
+	const VkPhysicalDeviceSparseProperties			sparseProperties			= physicalDeviceProperties.sparseProperties;
+	const PlanarFormatDescription					formatDescription			= getPlanarFormatDescription(m_format);
 
 	imageCreateInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
 	imageCreateInfo.pNext					= DE_NULL;
 	imageCreateInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 	imageCreateInfo.imageType				= mapImageType(m_imageType);
-	imageCreateInfo.format					= mapTextureFormat(m_format);
+	imageCreateInfo.format					= m_format;
 	imageCreateInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 	imageCreateInfo.mipLevels				= 1u;
 	imageCreateInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
@@ -170,9 +168,20 @@
 	}
 
 	// Check the format supports given number of samples
-	const VkImageFormatProperties formatProperties = getPhysicalDeviceImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags);
+	VkImageFormatProperties	imageFormatProperties;
 
-	if (!(formatProperties.sampleCounts & imageCreateInfo.samples))
+	if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+		imageCreateInfo.format,
+		imageCreateInfo.imageType,
+		imageCreateInfo.tiling,
+		imageCreateInfo.usage,
+		imageCreateInfo.flags,
+		&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+	{
+		TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+	}
+
+	if (!(imageFormatProperties.sampleCounts & imageCreateInfo.samples))
 		TCU_THROW(NotSupportedError, "The image format does not support the number of samples specified");
 
 	// Check if device supports sparse operations for image format
@@ -187,233 +196,236 @@
 	}
 
 	{
-		const DeviceInterface&								deviceInterface				= getDeviceInterface();
+		const DeviceInterface&		deviceInterface	= getDeviceInterface();
 
 		// Create sparse image
-		const Unique<VkImage>								sparseImage					(createImage(deviceInterface, getDevice(), &imageCreateInfo));
+		const Unique<VkImage>		imageSparse( createImage(deviceInterface, getDevice(), &imageCreateInfo) );
 
 		// Get sparse image sparse memory requirements
-		const std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements	= getImageSparseMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
+		sparseMemoryRequirements	= getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
 		DE_ASSERT(sparseMemoryRequirements.size() != 0);
-
-		const deUint32										colorAspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
-
-		if (colorAspectIndex == NO_MATCH_FOUND)
-			TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
-
-		aspectRequirements	= sparseMemoryRequirements[colorAspectIndex];
-		imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
 	}
 
-	if (m_imageType == IMAGE_TYPE_3D)
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 	{
-		if (!sparseProperties.residencyStandard3DBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard3DBlockShape disabled)");
+		const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+		const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
 
-		switch (pixelSize)
+		if (aspectIndex == NO_MATCH_FOUND)
+			TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+		VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+		VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
+		deUint32						pixelSize			= static_cast<deUint32>(formatDescription.planes[planeNdx].elementSizeBytes) * 8u;
+		VkExtent3D						expectedGranularity;
+
+		if (m_imageType == IMAGE_TYPE_3D)
 		{
-			case 8:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 32;
-				expectedGranularity.depth	= 32;
-				break;
-			case 16:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 32;
-				expectedGranularity.depth	= 32;
-				break;
-			case 32:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 32;
-				expectedGranularity.depth	= 16;
-				break;
-			case 64:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 16;
-				expectedGranularity.depth	= 16;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 16;
-				expectedGranularity.height	= 16;
-				expectedGranularity.depth	= 16;
-				break;
-		};
-	}
-	else if (m_numSamples == 2)
-	{
-		if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
+			if (!sparseProperties.residencyStandard3DBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard3DBlockShape disabled)");
 
-		expectedGranularity.depth = 1;
-
-		switch (pixelSize)
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 32;
+					expectedGranularity.depth = 32;
+					break;
+				case 16:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 32;
+					expectedGranularity.depth = 32;
+					break;
+				case 32:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 32;
+					expectedGranularity.depth = 16;
+					break;
+				case 64:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 16;
+					expectedGranularity.depth = 16;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 16;
+					expectedGranularity.height = 16;
+					expectedGranularity.depth = 16;
+					break;
+			};
+		}
+		else if (m_numSamples == 2)
 		{
-			case 8:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 256;
-				break;
-			case 16:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 128;
-				break;
-			case 32:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 128;
-				break;
-			case 64:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 64;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 64;
-				break;
-		};
-	}
-	else if (m_numSamples == 4)
-	{
-		if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
+			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
 
-		expectedGranularity.depth = 1;
+			expectedGranularity.depth = 1;
 
-		switch (pixelSize)
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 256;
+					break;
+				case 16:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 128;
+					break;
+				case 32:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 128;
+					break;
+				case 64:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 64;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 64;
+					break;
+			};
+		}
+		else if (m_numSamples == 4)
 		{
-			case 8:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 128;
-				break;
-			case 16:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 64;
-				break;
-			case 32:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 64;
-				break;
-			case 64:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 32;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 32;
-				break;
-		};
-	}
-	else if (m_numSamples == 8)
-	{
-		if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
+			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
 
-		expectedGranularity.depth = 1;
+			expectedGranularity.depth = 1;
 
-		switch (pixelSize)
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 128;
+					break;
+				case 16:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 64;
+					break;
+				case 32:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 64;
+					break;
+				case 64:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 32;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 32;
+					break;
+			};
+		}
+		else if (m_numSamples == 8)
 		{
-			case 8:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 128;
-				break;
-			case 16:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 64;
-				break;
-			case 32:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 64;
-				break;
-			case 64:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 32;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 16;
-				expectedGranularity.height	= 32;
-				break;
-		};
-	}
-	else if (m_numSamples == 16)
-	{
-		if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
+			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
 
-		expectedGranularity.depth = 1;
+			expectedGranularity.depth = 1;
 
-		switch (pixelSize)
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 128;
+					break;
+				case 16:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 64;
+					break;
+				case 32:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 64;
+					break;
+				case 64:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 32;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 16;
+					expectedGranularity.height = 32;
+					break;
+			};
+		}
+		else if (m_numSamples == 16)
 		{
-			case 8:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 64;
-				break;
-			case 16:
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 32;
-				break;
-			case 32:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 32;
-				break;
-			case 64:
-				expectedGranularity.width	= 32;
-				expectedGranularity.height	= 16;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 16;
-				expectedGranularity.height	= 16;
-				break;
-		};
-	}
-	else
-	{
-		DE_ASSERT(m_numSamples == 1);
+			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
 
-		if (!sparseProperties.residencyStandard2DBlockShape)
-			return tcu::TestStatus::pass("Pass (residencyStandard2DBlockShape disabled)");
+			expectedGranularity.depth = 1;
 
-		expectedGranularity.depth = 1;
-
-		switch (pixelSize)
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 64;
+					break;
+				case 16:
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 32;
+					break;
+				case 32:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 32;
+					break;
+				case 64:
+					expectedGranularity.width = 32;
+					expectedGranularity.height = 16;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 16;
+					expectedGranularity.height = 16;
+					break;
+			};
+		}
+		else
 		{
-			case 8:
-				expectedGranularity.width	= 256;
-				expectedGranularity.height	= 256;
-				break;
-			case 16:
-				expectedGranularity.width	= 256;
-				expectedGranularity.height	= 128;
-				break;
-			case 32:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 128;
-				break;
-			case 64:
-				expectedGranularity.width	= 128;
-				expectedGranularity.height	= 64;
-				break;
-			default:
-				DE_ASSERT(pixelSize == 128);
-				expectedGranularity.width	= 64;
-				expectedGranularity.height	= 64;
-				break;
-		};
-	}
+			DE_ASSERT(m_numSamples == 1);
 
-	if (imageGranularity.width == expectedGranularity.width
-		&& imageGranularity.height == expectedGranularity.height
-		&& imageGranularity.depth == expectedGranularity.depth)
-	{
-		return tcu::TestStatus::pass("Passed");
+			if (!sparseProperties.residencyStandard2DBlockShape)
+				return tcu::TestStatus::pass("Pass (residencyStandard2DBlockShape disabled)");
+
+			expectedGranularity.depth = 1;
+
+			switch (pixelSize)
+			{
+				case 8:
+					expectedGranularity.width = 256;
+					expectedGranularity.height = 256;
+					break;
+				case 16:
+					expectedGranularity.width = 256;
+					expectedGranularity.height = 128;
+					break;
+				case 32:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 128;
+					break;
+				case 64:
+					expectedGranularity.width = 128;
+					expectedGranularity.height = 64;
+					break;
+				default:
+					DE_ASSERT(pixelSize == 128);
+					expectedGranularity.width = 64;
+					expectedGranularity.height = 64;
+					break;
+			};
+		}
+
+		if (   imageGranularity.width  != expectedGranularity.width
+			|| imageGranularity.height != expectedGranularity.height
+			|| imageGranularity.depth  != expectedGranularity.depth)
+		{
+			return tcu::TestStatus::fail("Non-standard block shape used");
+		}
 	}
-	else
-	{
-		return tcu::TestStatus::fail("Non-standard block shape used");
-	}
+	return tcu::TestStatus::pass("Passed");
 }
 
 TestInstance* ImageBlockShapesCase::createInstance (Context& context) const
@@ -427,53 +439,45 @@
 {
 	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_block_shapes", "Standard block shape"));
 
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSize;
-	};
-
-	static const ImageParameters imageParametersArray[] =
-	{
-		{ IMAGE_TYPE_2D,		 tcu::UVec3(512u, 256u, 1u)		},
-		{ IMAGE_TYPE_2D_ARRAY,	 tcu::UVec3(512u, 256u, 6u)		},
-		{ IMAGE_TYPE_CUBE,		 tcu::UVec3(256u, 256u, 1u)		},
-		{ IMAGE_TYPE_CUBE_ARRAY, tcu::UVec3(256u, 256u, 6u)		},
-		{ IMAGE_TYPE_3D,		 tcu::UVec3(512u, 256u, 16u)	}
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RG,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
+		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u, 1u) },		getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u, 6u) },		getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u, 1u) },		getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u, 6u) },		getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,			{ tcu::UVec3(512u, 256u, 16u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
 	static const deUint32 sampleCounts[] = { 1u, 2u, 4u, 8u, 16u };
 
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
+		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
 		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&		format = formats[formatNdx];
-			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+			VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
 			for (deInt32 sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); ++sampleCountNdx)
 			{
-				const tcu::UVec3	imageSize	= imageParametersArray[imageTypeNdx].imageSize;
-				const deUint32		sampleCount	= sampleCounts[sampleCountNdx];
-				const std::string	name		= std::string("samples_") + de::toString(sampleCount);
+				for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
+				{
+					const tcu::UVec3	imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
 
-				formatGroup->addChild(new ImageBlockShapesCase(testCtx, name.c_str(), "", imageType, imageSize, format, sampleCount));
+					// skip test for images with odd sizes for some YCbCr formats
+					if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+						continue;
+					if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+						continue;
+
+					const deUint32		sampleCount = sampleCounts[sampleCountNdx];
+					const std::string	name = std::string("samples_") + de::toString(sampleCount);
+
+					formatGroup->addChild(new ImageBlockShapesCase(testCtx, name.c_str(), "", imageType, imageSize, format, sampleCount));
+				}
 			}
 			imageTypeGroup->addChild(formatGroup.release());
 		}
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
index eaa6f51..858eb58 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
@@ -43,7 +43,10 @@
 #include "deStringUtil.hpp"
 #include "deUniquePtr.hpp"
 #include "deSharedPtr.hpp"
+
 #include "tcuTexture.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuTexVerifierUtil.hpp"
 
 #include <deMath.h>
 #include <string>
@@ -58,15 +61,12 @@
 namespace
 {
 
-enum ShaderParameters
-{
-	MODULO_DIVISOR = 128
-};
+const deUint32 MODULO_DIVISOR = 127;
 
-const std::string getCoordStr  (const ImageType		imageType,
-								const std::string&	x,
-								const std::string&	y,
-								const std::string&	z)
+const std::string getCoordStr	(const ImageType	imageType,
+								 const std::string&	x,
+								 const std::string&	y,
+								 const std::string&	z)
 {
 	switch (imageType)
 	{
@@ -85,7 +85,7 @@
 			return "ivec3(" + x + "," + y + "," + z + ")";
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected image type");
 			return "";
 	}
 }
@@ -93,42 +93,42 @@
 class ImageSparseMemoryAliasingCase : public TestCase
 {
 public:
-					ImageSparseMemoryAliasingCase	(tcu::TestContext&			testCtx,
-													 const std::string&			name,
-													 const std::string&			description,
-													 const ImageType			imageType,
-													 const tcu::UVec3&			imageSize,
-													 const tcu::TextureFormat&	format,
-													 const glu::GLSLVersion		glslVersion,
-													 const bool					useDeviceGroups);
+	ImageSparseMemoryAliasingCase	(tcu::TestContext&		testCtx,
+									 const std::string&		name,
+									 const std::string&		description,
+									 const ImageType		imageType,
+									 const tcu::UVec3&		imageSize,
+									 const VkFormat			format,
+									 const glu::GLSLVersion	glslVersion,
+									 const bool				useDeviceGroups);
 
-	void			initPrograms					(SourceCollections&			sourceCollections) const;
-	TestInstance*	createInstance					(Context&					context) const;
-	virtual void	checkSupport					(Context&					context) const;
+	void			initPrograms	(SourceCollections&		sourceCollections) const;
+	TestInstance*	createInstance	(Context&				context) const;
+	virtual void	checkSupport	(Context&				context) const;
 
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
-	const glu::GLSLVersion		m_glslVersion;
+	const bool				m_useDeviceGroups;
+	const ImageType			m_imageType;
+	const tcu::UVec3		m_imageSize;
+	const VkFormat			m_format;
+	const glu::GLSLVersion	m_glslVersion;
 };
 
-ImageSparseMemoryAliasingCase::ImageSparseMemoryAliasingCase (tcu::TestContext&			testCtx,
-															  const std::string&		name,
-															  const std::string&		description,
-															  const ImageType			imageType,
-															  const tcu::UVec3&			imageSize,
-															  const tcu::TextureFormat&	format,
-															  const glu::GLSLVersion	glslVersion,
-															  const bool				useDeviceGroups)
-	: TestCase				(testCtx, name, description)
-	, m_useDeviceGroups		(useDeviceGroups)
-	, m_imageType			(imageType)
-	, m_imageSize			(imageSize)
-	, m_format				(format)
-	, m_glslVersion			(glslVersion)
+ImageSparseMemoryAliasingCase::ImageSparseMemoryAliasingCase	(tcu::TestContext&		testCtx,
+																 const std::string&		name,
+																 const std::string&		description,
+																 const ImageType		imageType,
+																 const tcu::UVec3&		imageSize,
+																 const VkFormat			format,
+																 const glu::GLSLVersion	glslVersion,
+																 const bool				useDeviceGroups)
+	: TestCase			(testCtx, name, description)
+	, m_useDeviceGroups	(useDeviceGroups)
+	, m_imageType		(imageType)
+	, m_imageSize		(imageSize)
+	, m_format			(format)
+	, m_glslVersion		(glslVersion)
 {
 }
 
@@ -151,26 +151,26 @@
 class ImageSparseMemoryAliasingInstance : public SparseResourcesBaseInstance
 {
 public:
-					ImageSparseMemoryAliasingInstance	(Context&								context,
-														 const ImageType						imageType,
-														 const tcu::UVec3&						imageSize,
-														 const tcu::TextureFormat&				format,
-														 const bool								useDeviceGroups);
+	ImageSparseMemoryAliasingInstance	(Context&			context,
+										 const ImageType	imageType,
+										 const tcu::UVec3&	imageSize,
+										 const VkFormat		format,
+										 const bool			useDeviceGroups);
 
-	tcu::TestStatus	iterate								(void);
+	tcu::TestStatus	iterate				(void);
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageSparseMemoryAliasingInstance::ImageSparseMemoryAliasingInstance (Context&					context,
-																	  const ImageType			imageType,
-																	  const tcu::UVec3&			imageSize,
-																	  const tcu::TextureFormat&	format,
-																	  const bool				useDeviceGroups)
+ImageSparseMemoryAliasingInstance::ImageSparseMemoryAliasingInstance	(Context&			context,
+																		 const ImageType	imageType,
+																		 const tcu::UVec3&	imageSize,
+																		 const VkFormat		format,
+																		 const bool			useDeviceGroups)
 	: SparseResourcesBaseInstance	(context, useDeviceGroups)
 	, m_useDeviceGroups				(useDeviceGroups)
 	, m_imageType					(imageType)
@@ -181,7 +181,8 @@
 
 tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
 {
-	const InstanceInterface&			instance				= m_context.getInstanceInterface();
+	const float					epsilon					= 1e-5f;
+	const InstanceInterface&	instance				= m_context.getInstanceInterface();
 
 	{
 		// Create logical device supporting both sparse and compute queues
@@ -192,20 +193,20 @@
 		createDeviceSupportingQueues(queueRequirements);
 	}
 
-	const VkPhysicalDevice				physicalDevice			= getPhysicalDevice();
-	const tcu::UVec3					maxWorkGroupSize		= tcu::UVec3(128u, 128u, 64u);
-	const tcu::UVec3					maxWorkGroupCount		= tcu::UVec3(65535u, 65535u, 65535u);
-	const deUint32						maxWorkGroupInvocations	= 128u;
-	VkImageCreateInfo					imageSparseInfo;
-	VkSparseImageMemoryRequirements		aspectRequirements;
-	std::vector<DeviceMemorySp>			deviceMemUniquePtrVec;
+	const VkPhysicalDevice		physicalDevice			= getPhysicalDevice();
+	const tcu::UVec3			maxWorkGroupSize		= tcu::UVec3(128u, 128u, 64u);
+	const tcu::UVec3			maxWorkGroupCount		= tcu::UVec3(65535u, 65535u, 65535u);
+	const deUint32				maxWorkGroupInvocations	= 128u;
+	VkImageCreateInfo			imageSparseInfo;
+	std::vector<DeviceMemorySp>	deviceMemUniquePtrVec;
 
 	//vsk getting queues should be outside the loop
 	//see these in all image files
 
-	const DeviceInterface&	deviceInterface	= getDeviceInterface();
-	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-	const Queue&			computeQueue	= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const DeviceInterface&			deviceInterface		= getDeviceInterface();
+	const Queue&					sparseQueue			= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+	const Queue&					computeQueue		= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
 
 	// Go through all physical devices
 	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
@@ -219,7 +220,7 @@
 												  VK_IMAGE_CREATE_SPARSE_ALIASED_BIT   |
 												  VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 		imageSparseInfo.imageType				= mapImageType(m_imageType);
-		imageSparseInfo.format					= mapTextureFormat(m_format);
+		imageSparseInfo.format					= m_format;
 		imageSparseInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 		imageSparseInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
 		imageSparseInfo.samples					= VK_SAMPLE_COUNT_1_BIT;
@@ -235,24 +236,27 @@
 		if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
 			imageSparseInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 
+		// Check if device supports sparse operations for image format
+		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
+			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
+
 		{
 			// Assign maximum allowed mipmap levels to image
 			VkImageFormatProperties imageFormatProperties;
-			instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+			if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
 				imageSparseInfo.format,
 				imageSparseInfo.imageType,
 				imageSparseInfo.tiling,
 				imageSparseInfo.usage,
 				imageSparseInfo.flags,
-				&imageFormatProperties);
+				&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+			{
+				TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+			}
 
-			imageSparseInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageSparseInfo.extent);
+			imageSparseInfo.mipLevels = getMipmapCount(m_format, formatDescription, imageFormatProperties, imageSparseInfo.extent);
 		}
 
-		// Check if device supports sparse operations for image format
-		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
-			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
-
 		// Create sparse image
 		const Unique<VkImage> imageRead(createImage(deviceInterface, getDevice(), &imageSparseInfo));
 		const Unique<VkImage> imageWrite(createImage(deviceInterface, getDevice(), &imageSparseInfo));
@@ -263,11 +267,9 @@
 
 		const VkSemaphore imageMemoryBindSemaphores[] = { memoryBindSemaphoreTransfer.get(), memoryBindSemaphoreCompute.get() };
 
-		{
-			std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
-			std::vector<VkSparseMemoryBind>		 imageReadMipTailBinds;
-			std::vector<VkSparseMemoryBind>		 imageWriteMipTailBinds;
+		std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements;
 
+		{
 			// Get sparse image general memory requirements
 			const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageRead);
 
@@ -277,23 +279,6 @@
 
 			DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
 
-			// Get sparse image sparse memory requirements
-			const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageRead);
-
-			DE_ASSERT(sparseMemoryRequirements.size() != 0);
-
-			const deUint32 colorAspectIndex = getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
-
-			if (colorAspectIndex == NO_MATCH_FOUND)
-				TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
-
-			aspectRequirements = sparseMemoryRequirements[colorAspectIndex];
-
-			const VkImageAspectFlags	aspectMask			= aspectRequirements.formatProperties.aspectMask;
-			const VkExtent3D			imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
-
-			DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
-
 			const deUint32 memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
 			if (memoryType == NO_MATCH_FOUND)
@@ -301,47 +286,88 @@
 
 			if (firstDeviceID != secondDeviceID)
 			{
-				VkPeerMemoryFeatureFlags	peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
-				const deUint32				heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+				VkPeerMemoryFeatureFlags	peerMemoryFeatureFlags	= (VkPeerMemoryFeatureFlags)0;
+				const deUint32				heapIndex				= getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
 				deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
 
-				if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT)    == 0) ||
-					((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT)    == 0) ||
+				if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT) == 0) ||
+					((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT) == 0) ||
 					((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT) == 0))
 				{
 					TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC, COPY_DST, and GENERIC_DST");
 				}
 			}
 
-			// Bind memory for each layer
-			for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
+			// Get sparse image sparse memory requirements
+			sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageRead);
+
+			DE_ASSERT(sparseMemoryRequirements.size() != 0);
+
+			std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
+			std::vector<VkSparseMemoryBind>		 imageReadMipTailBinds;
+			std::vector<VkSparseMemoryBind>		 imageWriteMipTailBinds;
+
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 			{
-				for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+				const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+				const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
+
+				if (aspectIndex == NO_MATCH_FOUND)
+					TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+				VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+
+				DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
+
+				VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
+
+				// Bind memory for each layer
+				for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
 				{
-					const VkExtent3D			mipExtent		= mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
-					const tcu::UVec3			sparseBlocks	= alignedDivide(mipExtent, imageGranularity);
-					const deUint32				numSparseBlocks = sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
-					const VkImageSubresource	subresource		= { aspectMask, mipLevelNdx, layerNdx };
+					for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+					{
+						const VkExtent3D			mipExtent			= getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipLevelNdx);
+						const tcu::UVec3			sparseBlocks		= alignedDivide(mipExtent, imageGranularity);
+						const deUint32				numSparseBlocks		= sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
+						const VkImageSubresource	subresource			= { aspect, mipLevelNdx, layerNdx };
 
-					const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
-						imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
+						const VkSparseImageMemoryBind imageMemoryBind	= makeSparseImageMemoryBind(deviceInterface, getDevice(),
+							imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
 
-					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
-					imageResidencyMemoryBinds.push_back(imageMemoryBind);
+						imageResidencyMemoryBinds.push_back(imageMemoryBind);
+					}
+
+					if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
+					{
+						const VkSparseMemoryBind imageReadMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+							aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
+
+						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageReadMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+						imageReadMipTailBinds.push_back(imageReadMipTailMemoryBind);
+
+						const VkSparseMemoryBind imageWriteMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+							aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
+
+						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageWriteMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+						imageWriteMipTailBinds.push_back(imageWriteMipTailMemoryBind);
+					}
 				}
 
-				if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
+				if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
 				{
 					const VkSparseMemoryBind imageReadMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
+						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
 
 					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageReadMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
 					imageReadMipTailBinds.push_back(imageReadMipTailMemoryBind);
 
 					const VkSparseMemoryBind imageWriteMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
+						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
 
 					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageWriteMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
@@ -349,23 +375,6 @@
 				}
 			}
 
-			if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
-			{
-				const VkSparseMemoryBind imageReadMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
-
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageReadMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-				imageReadMipTailBinds.push_back(imageReadMipTailMemoryBind);
-
-				const VkSparseMemoryBind imageWriteMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
-
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageWriteMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-				imageWriteMipTailBinds.push_back(imageWriteMipTailMemoryBind);
-			}
-
 			const VkDeviceGroupBindSparseInfo devGroupBindSparseInfo =
 			{
 				VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR,	//VkStructureType							sType;
@@ -390,18 +399,18 @@
 				imageMemoryBindSemaphores								//const VkSemaphore*						pSignalSemaphores;
 			};
 
-			VkSparseImageMemoryBindInfo		  imageResidencyBindInfo[2];
-			VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo[2];
+			VkSparseImageMemoryBindInfo			imageResidencyBindInfo[2];
+			VkSparseImageOpaqueMemoryBindInfo	imageMipTailBindInfo[2];
 
 			if (imageResidencyMemoryBinds.size() > 0)
 			{
 				imageResidencyBindInfo[0].image		= *imageRead;
 				imageResidencyBindInfo[0].bindCount = static_cast<deUint32>(imageResidencyMemoryBinds.size());
-				imageResidencyBindInfo[0].pBinds	= &imageResidencyMemoryBinds[0];
+				imageResidencyBindInfo[0].pBinds	= imageResidencyMemoryBinds.data();
 
 				imageResidencyBindInfo[1].image		= *imageWrite;
 				imageResidencyBindInfo[1].bindCount = static_cast<deUint32>(imageResidencyMemoryBinds.size());
-				imageResidencyBindInfo[1].pBinds	= &imageResidencyMemoryBinds[0];
+				imageResidencyBindInfo[1].pBinds	= imageResidencyMemoryBinds.data();
 
 				bindSparseInfo.imageBindCount		= 2u;
 				bindSparseInfo.pImageBinds			= imageResidencyBindInfo;
@@ -411,11 +420,11 @@
 			{
 				imageMipTailBindInfo[0].image		= *imageRead;
 				imageMipTailBindInfo[0].bindCount	= static_cast<deUint32>(imageReadMipTailBinds.size());
-				imageMipTailBindInfo[0].pBinds		= &imageReadMipTailBinds[0];
+				imageMipTailBindInfo[0].pBinds		= imageReadMipTailBinds.data();
 
 				imageMipTailBindInfo[1].image		= *imageWrite;
 				imageMipTailBindInfo[1].bindCount	= static_cast<deUint32>(imageWriteMipTailBinds.size());
-				imageMipTailBindInfo[1].pBinds		= &imageWriteMipTailBinds[0];
+				imageMipTailBindInfo[1].pBinds		= imageWriteMipTailBinds.data();
 
 				bindSparseInfo.imageOpaqueBindCount = 2u;
 				bindSparseInfo.pImageOpaqueBinds	= imageMipTailBindInfo;
@@ -425,40 +434,75 @@
 			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
 		}
 
-		// Create command buffer for compute and transfer oparations
-		const Unique<VkCommandPool>	  commandPool  (makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
-		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+		deUint32							imageSizeInBytes = 0;
+		std::vector<std::vector<deUint32>>	planeOffsets( imageSparseInfo.mipLevels );
+		std::vector<std::vector<deUint32>>	planeRowPitches( imageSparseInfo.mipLevels );
 
-		std::vector<VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
-
+		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
 		{
-			deUint32 bufferOffset = 0u;
-			for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+			planeOffsets[mipmapNdx].resize(formatDescription.numPlanes, 0);
+			planeRowPitches[mipmapNdx].resize(formatDescription.numPlanes, 0);
+		}
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
 			{
-				bufferImageCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, bufferOffset);
-				bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				const tcu::UVec3	gridSize			= getShaderGridSize(m_imageType, m_imageSize, mipmapNdx);
+				planeOffsets[mipmapNdx][planeNdx]		= imageSizeInBytes;
+				const deUint32		planeW				= gridSize.x() / (formatDescription.blockWidth * formatDescription.planes[planeNdx].widthDivisor);
+				planeRowPitches[mipmapNdx][planeNdx]	= formatDescription.planes[planeNdx].elementSizeBytes * planeW;
+				imageSizeInBytes						+= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 			}
 		}
 
+		std::vector <VkBufferImageCopy>	bufferImageCopy(formatDescription.numPlanes * imageSparseInfo.mipLevels);
+		{
+			deUint32 bufferOffset = 0;
+
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				{
+					bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx] =
+					{
+						bufferOffset,																		//	VkDeviceSize				bufferOffset;
+						0u,																					//	deUint32					bufferRowLength;
+						0u,																					//	deUint32					bufferImageHeight;
+						makeImageSubresourceLayers(aspect, mipmapNdx, 0u, imageSparseInfo.arrayLayers),		//	VkImageSubresourceLayers	imageSubresource;
+						makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
+						vk::getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx)	//	VkExtent3D					imageExtent;
+					};
+					bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				}
+			}
+		}
+
+		// Create command buffer for compute and transfer operations
+		const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
+		const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
 		// Start recording commands
 		beginCommandBuffer(deviceInterface, *commandBuffer);
 
-		const deUint32					imageSizeInBytes		= getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 		const VkBufferCreateInfo		inputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 		const Unique<VkBuffer>			inputBuffer				(createBuffer(deviceInterface, getDevice(), &inputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	inputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *inputBuffer, MemoryRequirement::HostVisible));
 
 		std::vector<deUint8> referenceData(imageSizeInBytes);
 
-		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
-		{
-			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
-			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			for (deUint32 mipmapNdx = 0u; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx].bufferOffset);
 
-			deMemset(&referenceData[bufferOffset], mipLevelNdx + 1u, mipLevelSizeInBytes);
-		}
+				deMemset(&referenceData[bufferOffset], mipmapNdx + 1u, mipLevelSizeInBytes);
+			}
 
-		deMemcpy(inputBufferAlloc->getHostPtr(), &referenceData[0], imageSizeInBytes);
+		deMemcpy(inputBufferAlloc->getHostPtr(), referenceData.data(), imageSizeInBytes);
 
 		flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
 
@@ -476,49 +520,70 @@
 		}
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferDstBarrier = makeImageMemoryBarrier
-			(
-				0u,
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_IMAGE_LAYOUT_UNDEFINED,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				*imageRead,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
-				);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferDstBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferDstBarriers.emplace_back(makeImageMemoryBarrier
+				(
+					0u,
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					*imageRead,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
+				));
+			}
+
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferDstBarriers.size()), imageSparseTransferDstBarriers.data());
 		}
 
-		deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageRead, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+		deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageRead, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferSrcBarrier = makeImageMemoryBarrier
-			(
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_ACCESS_TRANSFER_READ_BIT,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-				*imageRead,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
-			);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferSrcBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferSrcBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferSrcBarriers.emplace_back(makeImageMemoryBarrier
+				(
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_ACCESS_TRANSFER_READ_BIT,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+					*imageRead,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
+				));
+			}
+
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferSrcBarriers.size()), imageSparseTransferSrcBarriers.data());
 		}
 
 		{
-			const VkImageMemoryBarrier imageSparseShaderStorageBarrier = makeImageMemoryBarrier
-			(
-				0u,
-				VK_ACCESS_SHADER_WRITE_BIT,
-				VK_IMAGE_LAYOUT_UNDEFINED,
-				VK_IMAGE_LAYOUT_GENERAL,
-				*imageWrite,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
-			);
+			std::vector<VkImageMemoryBarrier> imageSparseShaderStorageBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseShaderStorageBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseShaderStorageBarriers.emplace_back(makeImageMemoryBarrier
+				(
+					0u,
+					VK_ACCESS_SHADER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED,
+					VK_IMAGE_LAYOUT_GENERAL,
+					*imageWrite,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
+				));
+			}
+
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseShaderStorageBarriers.size()), imageSparseShaderStorageBarriers.data());
 		}
 
 		// Create descriptor set layout
@@ -569,10 +634,10 @@
 			imageViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), *imageWrite, mapImageViewType(m_imageType), imageSparseInfo.format, subresourceRange));
 			VkImageView imageView	= **imageViews[mipLevelNdx];
 
-			const VkDescriptorImageInfo sparseImageInfo = makeDescriptorImageInfo(DE_NULL, imageView, VK_IMAGE_LAYOUT_GENERAL);
+			const VkDescriptorImageInfo descriptorImageSparseInfo = makeDescriptorImageInfo(DE_NULL, imageView, VK_IMAGE_LAYOUT_GENERAL);
 
 			DescriptorSetUpdateBuilder()
-				.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &sparseImageInfo)
+				.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageSparseInfo)
 				.update(deviceInterface, getDevice());
 
 			deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
@@ -589,7 +654,9 @@
 			if (maxWorkGroupCount.x() < xWorkGroupCount ||
 				maxWorkGroupCount.y() < yWorkGroupCount ||
 				maxWorkGroupCount.z() < zWorkGroupCount)
+			{
 				TCU_THROW(NotSupportedError, "Image size is not supported");
+			}
 
 			deviceInterface.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
 		}
@@ -604,7 +671,7 @@
 		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
 
-		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageRead, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageRead, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
 			const VkBufferMemoryBarrier outputBufferBarrier = makeBufferMemoryBarrier
@@ -631,38 +698,111 @@
 		// Retrieve data from buffer to host memory
 		invalidateAlloc(deviceInterface, getDevice(), *outputBufferAlloc);
 
-		const deUint8* outputData = static_cast<const deUint8*>(outputBufferAlloc->getHostPtr());
+		deUint8* outputData = static_cast<deUint8*>(outputBufferAlloc->getHostPtr());
+
+		std::vector<std::vector<void*>> planePointers(imageSparseInfo.mipLevels);
+
+		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			planePointers[mipmapNdx].resize(formatDescription.numPlanes);
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				planePointers[mipmapNdx][planeNdx] = outputData + static_cast<size_t>(planeOffsets[mipmapNdx][planeNdx]);
 
 		// Wait for sparse queue to become idle
 		deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-		for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+		for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
 		{
-			const tcu::UVec3				  gridSize		= getShaderGridSize(m_imageType, m_imageSize, mipLevelNdx);
-			const deUint32					  bufferOffset	= static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
-			const tcu::ConstPixelBufferAccess pixelBuffer	= tcu::ConstPixelBufferAccess(m_format, gridSize.x(), gridSize.y(), gridSize.z(), outputData + bufferOffset);
+			if (!formatDescription.hasChannelNdx(channelNdx))
+				continue;
 
-			for (deUint32 offsetZ = 0u; offsetZ < gridSize.z(); ++offsetZ)
-			for (deUint32 offsetY = 0u; offsetY < gridSize.y(); ++offsetY)
-			for (deUint32 offsetX = 0u; offsetX < gridSize.x(); ++offsetX)
+			deUint32							planeNdx			= formatDescription.channels[channelNdx].planeNdx;
+			const VkImageAspectFlags			aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+			const deUint32						aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
+
+			if (aspectIndex == NO_MATCH_FOUND)
+				TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+			VkSparseImageMemoryRequirements		aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+			float								fixedPointError		= tcu::TexVerifierUtil::computeFixedPointError(formatDescription.channels[channelNdx].sizeBits);;
+
+			for (deUint32 mipmapNdx = 0; mipmapNdx < aspectRequirements.imageMipTailFirstLod; ++mipmapNdx)
 			{
-				const deUint32 index			= offsetX + (offsetY + offsetZ * gridSize.y()) * gridSize.x();
-				const tcu::UVec4 referenceValue = tcu::UVec4(index % MODULO_DIVISOR, index % MODULO_DIVISOR, index % MODULO_DIVISOR, 1u);
-				const tcu::UVec4 outputValue	= pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
+				const	tcu::UVec3						gridSize		= getShaderGridSize(m_imageType, m_imageSize, mipmapNdx);
+				const	tcu::ConstPixelBufferAccess		pixelBuffer		= vk::getChannelAccess(formatDescription, gridSize, planeRowPitches[mipmapNdx].data(), (const void* const*)planePointers[mipmapNdx].data(), channelNdx);
+				tcu::IVec3								pixelDivider	= pixelBuffer.getDivider();
 
-				if (deMemCmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format.order)) != 0)
+				for (deUint32 offsetZ = 0u; offsetZ < gridSize.z(); ++offsetZ)
+				for (deUint32 offsetY = 0u; offsetY < gridSize.y(); ++offsetY)
+				for (deUint32 offsetX = 0u; offsetX < gridSize.x(); ++offsetX)
+				{
+					const deUint32	index			= offsetX + gridSize.x() * offsetY + gridSize.x() * gridSize.y() * offsetZ;
+					deUint32		iReferenceValue;
+					float			fReferenceValue;
+					float			acceptableError	= epsilon;
+
+					switch (channelNdx)
+					{
+						case 0:
+						case 1:
+						case 2:
+							iReferenceValue = index % MODULO_DIVISOR;
+							fReferenceValue = static_cast<float>(iReferenceValue) / static_cast<float>(MODULO_DIVISOR);
+							break;
+						case 3:
+							iReferenceValue = 1u;
+							fReferenceValue = 1.f;
+							break;
+						default:	DE_FATAL("Unexpected channel index");	break;
+					}
+
+					switch (formatDescription.channels[channelNdx].type)
+					{
+						case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+						case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+						{
+							const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (outputValue.x() != iReferenceValue)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+						case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+						{
+							acceptableError += fixedPointError;
+							const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (deAbs(outputValue.x() - fReferenceValue) > acceptableError)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+						{
+							const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (deAbs(outputValue.x() - fReferenceValue) > acceptableError)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						default:	DE_FATAL("Unexpected channel type");	break;
+					}
+				}
+			}
+
+			for (deUint32 mipmapNdx = aspectRequirements.imageMipTailFirstLod; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx);
+				const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx].bufferOffset);
+
+				if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
 					return tcu::TestStatus::fail("Failed");
 			}
 		}
-
-		for (deUint32 mipLevelNdx = aspectRequirements.imageMipTailFirstLod; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
-		{
-			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
-			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
-
-			if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
-				return tcu::TestStatus::fail("Failed");
-		}
 	}
 
 	return tcu::TestStatus::pass("Passed");
@@ -670,16 +810,33 @@
 
 void ImageSparseMemoryAliasingCase::initPrograms(SourceCollections&	sourceCollections) const
 {
-	const char* const	versionDecl				= glu::getGLSLVersionDeclaration(m_glslVersion);
-	const std::string	imageTypeStr			= getShaderImageType(m_format, m_imageType);
-	const std::string	formatQualifierStr		= getShaderImageFormatQualifier(m_format);
-	const std::string	formatDataStr			= getShaderImageDataType(m_format);
-	const deUint32		maxWorkGroupInvocations = 128u;
-	const tcu::UVec3	maxWorkGroupSize		= tcu::UVec3(128u, 128u, 64u);
+	const char* const				versionDecl				= glu::getGLSLVersionDeclaration(m_glslVersion);
+	const PlanarFormatDescription	formatDescription		= getPlanarFormatDescription(m_format);
+	const std::string				imageTypeStr			= getShaderImageType(formatDescription, m_imageType);
+	const std::string				formatQualifierStr		= getShaderImageFormatQualifier(m_format);
+	const std::string				formatDataStr			= getShaderImageDataType(formatDescription);
+	const deUint32					maxWorkGroupInvocations = 128u;
+	const tcu::UVec3				maxWorkGroupSize		= tcu::UVec3(128u, 128u, 64u);
+	VkExtent3D						layerExtent				= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
+	VkImageFormatProperties			imageFormatProperties;
+	imageFormatProperties.maxMipLevels						= 20;
+	const deUint32					mipLevels				= getMipmapCount(m_format, formatDescription, imageFormatProperties, layerExtent);
 
-	const tcu::UVec3	layerSize				= getLayerSize(m_imageType, m_imageSize);
-	const deUint32		widestEdge				= std::max(std::max(layerSize.x(), layerSize.y()), layerSize.z());
-	const deUint32		mipLevels				= static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u;
+	std::ostringstream formatValueStr;
+	switch (formatDescription.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			formatValueStr << "( index % " << MODULO_DIVISOR << ", index % " << MODULO_DIVISOR << ", index % " << MODULO_DIVISOR << ", 1)";
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			formatValueStr << "( float( index % " << MODULO_DIVISOR << ") / " << MODULO_DIVISOR << ".0, float( index % " << MODULO_DIVISOR << ") / " << MODULO_DIVISOR << ".0, float( index % " << MODULO_DIVISOR << ") / " << MODULO_DIVISOR << ".0, 1.0)";
+			break;
+		default:	DE_FATAL("Unexpected channel type");	break;
+	}
+
 
 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; ++mipLevelNdx)
 	{
@@ -700,9 +857,9 @@
 			<< "	if( gl_GlobalInvocationID.y < " << gridSize.y() << " ) \n"
 			<< "	if( gl_GlobalInvocationID.z < " << gridSize.z() << " ) \n"
 			<< "	{\n"
-			<< "		int index = int(gl_GlobalInvocationID.x + (gl_GlobalInvocationID.y + gl_GlobalInvocationID.z*" << gridSize.y() << ")*" << gridSize.x() << ");\n"
+			<< "		int index = int( gl_GlobalInvocationID.x + "<< gridSize.x() << " * gl_GlobalInvocationID.y + " << gridSize.x() << " * " << gridSize.y() << " * gl_GlobalInvocationID.z );\n"
 			<< "		imageStore(u_image, " << getCoordStr(m_imageType, "gl_GlobalInvocationID.x", "gl_GlobalInvocationID.y", "gl_GlobalInvocationID.z") << ","
-			<< formatDataStr << "( index % " << MODULO_DIVISOR << ", index % " << MODULO_DIVISOR << ", index % " << MODULO_DIVISOR << ", 1 )); \n"
+			<< formatDataStr << formatValueStr.str() <<"); \n"
 			<< "	}\n"
 			<< "}\n";
 
@@ -721,46 +878,36 @@
 
 tcu::TestCaseGroup* createImageSparseMemoryAliasingTestsCommon(tcu::TestContext& testCtx, de::MovePtr<tcu::TestCaseGroup> testGroup, const bool useDeviceGroup = false)
 {
-	static const deUint32 sizeCountPerImageType = 4u;
 
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSizes[sizeCountPerImageType];
+		{ IMAGE_TYPE_2D,		{ tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(503u, 137u, 1u),	tcu::UVec3(11u, 37u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,	{ tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,		{ tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(137u, 137u, 1u),	tcu::UVec3(11u, 11u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,{ tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(137u, 137u, 3u),	tcu::UVec3(11u, 11u, 3u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,		{ tcu::UVec3(256u, 256u, 16u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
-	static const ImageParameters imageParametersArray[] =
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		{ IMAGE_TYPE_2D,		{ tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(503u, 137u, 1u),	tcu::UVec3(11u, 37u, 1u) } },
-		{ IMAGE_TYPE_2D_ARRAY,	{ tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) } },
-		{ IMAGE_TYPE_CUBE,		{ tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(137u, 137u, 1u),	tcu::UVec3(11u, 11u, 1u) } },
-		{ IMAGE_TYPE_CUBE_ARRAY,{ tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(137u, 137u, 3u),	tcu::UVec3(11u, 11u, 3u) } },
-		{ IMAGE_TYPE_3D,		{ tcu::UVec3(256u, 256u, 16u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) } }
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
-	};
-
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
-	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
+		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
 		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&		format = formats[formatNdx];
-			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+			VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
-			for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
+			for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
 			{
-				const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
+				const tcu::UVec3 imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
+
+				// skip test for images with odd sizes for some YCbCr formats
+				if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+					continue;
+				if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+					continue;
 
 				std::ostringstream stream;
 				stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
index e3e93d7..c0e753d 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
@@ -57,37 +57,37 @@
 class ImageSparseBindingCase : public TestCase
 {
 public:
-					ImageSparseBindingCase	(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const std::string&			description,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format,
-											 const bool					useDeviceGroups = false);
+	ImageSparseBindingCase			(tcu::TestContext&	testCtx,
+									 const std::string&	name,
+									 const std::string&	description,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format,
+									 const bool			useDeviceGroups = false);
 
-	TestInstance*	createInstance			(Context&					context) const;
+	TestInstance*	createInstance	(Context&			context) const;
 	virtual void	checkSupport			(Context&					context) const;
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageSparseBindingCase::ImageSparseBindingCase (tcu::TestContext&			testCtx,
-												const std::string&			name,
-												const std::string&			description,
-												const ImageType				imageType,
-												const tcu::UVec3&			imageSize,
-												const tcu::TextureFormat&	format,
-												const bool					useDeviceGroups)
+ImageSparseBindingCase::ImageSparseBindingCase (tcu::TestContext&	testCtx,
+												const std::string&	name,
+												const std::string&	description,
+												const ImageType		imageType,
+												const tcu::UVec3&	imageSize,
+												const VkFormat		format,
+												const bool			useDeviceGroups)
 
-	: TestCase				(testCtx, name, description)
-	, m_useDeviceGroups		(useDeviceGroups)
-	, m_imageType			(imageType)
-	, m_imageSize			(imageSize)
-	, m_format				(format)
+	: TestCase			(testCtx, name, description)
+	, m_useDeviceGroups	(useDeviceGroups)
+	, m_imageType		(imageType)
+	, m_imageSize		(imageSize)
+	, m_format			(format)
 {
 }
 
@@ -102,26 +102,26 @@
 class ImageSparseBindingInstance : public SparseResourcesBaseInstance
 {
 public:
-					ImageSparseBindingInstance	(Context&					context,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format,
-												 const bool					useDeviceGroups);
+	ImageSparseBindingInstance	(Context&			context,
+								 const ImageType	imageType,
+								 const tcu::UVec3&	imageSize,
+								 const VkFormat		format,
+								 const bool			useDeviceGroups);
 
-	tcu::TestStatus	iterate						(void);
+	tcu::TestStatus	iterate		(void);
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageSparseBindingInstance::ImageSparseBindingInstance (Context&					context,
-														const ImageType				imageType,
-														const tcu::UVec3&			imageSize,
-														const tcu::TextureFormat&	format,
-														const bool					useDeviceGroups)
+ImageSparseBindingInstance::ImageSparseBindingInstance (Context&			context,
+														const ImageType		imageType,
+														const tcu::UVec3&	imageSize,
+														const VkFormat		format,
+														const bool			useDeviceGroups)
 
 	: SparseResourcesBaseInstance	(context, useDeviceGroups)
 	, m_useDeviceGroups				(useDeviceGroups)
@@ -148,12 +148,13 @@
 	VkImageCreateInfo			imageSparseInfo;
 	std::vector<DeviceMemorySp>	deviceMemUniquePtrVec;
 
-	const DeviceInterface&	deviceInterface	= getDeviceInterface();
-	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-	const Queue&			computeQueue	= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const DeviceInterface&			deviceInterface		= getDeviceInterface();
+	const Queue&					sparseQueue			= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+	const Queue&					computeQueue		= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
 
 	// Go through all physical devices
-	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
+	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; ++physDevID)
 	{
 		const deUint32	firstDeviceID	= physDevID;
 		const deUint32	secondDeviceID	= (firstDeviceID + 1) % m_numPhysicalDevices;
@@ -162,7 +163,7 @@
 		imageSparseInfo.pNext					= DE_NULL;												//const void*			pNext;
 		imageSparseInfo.flags					= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;					//VkImageCreateFlags	flags;
 		imageSparseInfo.imageType				= mapImageType(m_imageType);							//VkImageType			imageType;
-		imageSparseInfo.format					= mapTextureFormat(m_format);							//VkFormat				format;
+		imageSparseInfo.format					= m_format;												//VkFormat				format;
 		imageSparseInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));	//VkExtent3D			extent;
 		imageSparseInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);				//deUint32				arrayLayers;
 		imageSparseInfo.samples					= VK_SAMPLE_COUNT_1_BIT;								//VkSampleCountFlagBits	samples;
@@ -179,17 +180,23 @@
 			imageSparseInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 		}
 
+		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
+			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
+
 		{
 			VkImageFormatProperties imageFormatProperties;
-			instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+			if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
 				imageSparseInfo.format,
 				imageSparseInfo.imageType,
 				imageSparseInfo.tiling,
 				imageSparseInfo.usage,
 				imageSparseInfo.flags,
-				&imageFormatProperties);
+				&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+			{
+				TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+			}
 
-			imageSparseInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageSparseInfo.extent);
+			imageSparseInfo.mipLevels = getMipmapCount(m_format, formatDescription, imageFormatProperties, imageSparseInfo.extent);
 		}
 
 		// Create sparse image
@@ -199,18 +206,18 @@
 		const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
 
 		// Get sparse image general memory requirements
-		const VkMemoryRequirements imageSparseMemRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
+		const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
 		// Check if required image memory size does not exceed device limits
-		if (imageSparseMemRequirements.size > getPhysicalDeviceProperties(instance, getPhysicalDevice(secondDeviceID)).limits.sparseAddressSpaceSize)
+		if (imageMemoryRequirements.size > getPhysicalDeviceProperties(instance, getPhysicalDevice(secondDeviceID)).limits.sparseAddressSpaceSize)
 			TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits");
 
-		DE_ASSERT((imageSparseMemRequirements.size % imageSparseMemRequirements.alignment) == 0);
+		DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
 
 		{
 			std::vector<VkSparseMemoryBind>	sparseMemoryBinds;
-			const deUint32					numSparseBinds	= static_cast<deUint32>(imageSparseMemRequirements.size / imageSparseMemRequirements.alignment);
-			const deUint32					memoryType		= findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageSparseMemRequirements, MemoryRequirement::Any);
+			const deUint32					numSparseBinds	= static_cast<deUint32>(imageMemoryRequirements.size / imageMemoryRequirements.alignment);
+			const deUint32					memoryType		= findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
 			if (memoryType == NO_MATCH_FOUND)
 				return tcu::TestStatus::fail("No matching memory type found");
@@ -231,14 +238,14 @@
 			for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseBinds; ++sparseBindNdx)
 			{
 				const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					imageSparseMemRequirements.alignment, memoryType, imageSparseMemRequirements.alignment * sparseBindNdx);
+					imageMemoryRequirements.alignment, memoryType, imageMemoryRequirements.alignment * sparseBindNdx);
 
 				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(sparseMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
 				sparseMemoryBinds.push_back(sparseMemoryBind);
 			}
 
-			const VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo = makeSparseImageOpaqueMemoryBindInfo(*imageSparse, numSparseBinds, &sparseMemoryBinds[0]);
+			const VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo = makeSparseImageOpaqueMemoryBindInfo(*imageSparse, static_cast<deUint32>(sparseMemoryBinds.size()), sparseMemoryBinds.data());
 
 			const VkDeviceGroupBindSparseInfo devGroupBindSparseInfo =
 			{
@@ -268,90 +275,114 @@
 			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
 		}
 
-		// Create command buffer for compute and transfer oparations
-		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
-		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+		deUint32 imageSizeInBytes = 0;
 
-		std::vector<VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				imageSizeInBytes += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 
+		std::vector<VkBufferImageCopy> bufferImageCopy(formatDescription.numPlanes * imageSparseInfo.mipLevels);
 		{
 			deUint32 bufferOffset = 0;
-			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 			{
-				bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, static_cast<VkDeviceSize>(bufferOffset));
-				bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				{
+					bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx] =
+					{
+						bufferOffset,																		//	VkDeviceSize				bufferOffset;
+						0u,																					//	deUint32					bufferRowLength;
+						0u,																					//	deUint32					bufferImageHeight;
+						makeImageSubresourceLayers(aspect, mipmapNdx, 0u, imageSparseInfo.arrayLayers),		//	VkImageSubresourceLayers	imageSubresource;
+						makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
+						vk::getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx)	//	VkExtent3D					imageExtent;
+					};
+					bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				}
 			}
 		}
 
+		// Create command buffer for compute and transfer operations
+		const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
+		const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
 		// Start recording commands
 		beginCommandBuffer(deviceInterface, *commandBuffer);
 
-		const deUint32					imageSizeInBytes		= getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 		const VkBufferCreateInfo		inputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 		const Unique<VkBuffer>			inputBuffer				(createBuffer(deviceInterface, getDevice(), &inputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	inputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *inputBuffer, MemoryRequirement::HostVisible));
 
-		std::vector<deUint8> referenceData(imageSizeInBytes);
-
+		std::vector<deUint8>			referenceData(imageSizeInBytes);
 		for (deUint32 valueNdx = 0; valueNdx < imageSizeInBytes; ++valueNdx)
 		{
-			referenceData[valueNdx] = static_cast<deUint8>((valueNdx % imageSparseMemRequirements.alignment) + 1u);
+			referenceData[valueNdx] = static_cast<deUint8>((valueNdx % imageMemoryRequirements.alignment) + 1u);
 		}
 
-		deMemcpy(inputBufferAlloc->getHostPtr(), &referenceData[0], imageSizeInBytes);
-
-		flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
-
 		{
-			const VkBufferMemoryBarrier inputBufferBarrier = makeBufferMemoryBarrier
-			(
+			deMemcpy(inputBufferAlloc->getHostPtr(), referenceData.data(), imageSizeInBytes);
+			flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
+
+			const VkBufferMemoryBarrier inputBufferBarrier = makeBufferMemoryBarrier (
 				VK_ACCESS_HOST_WRITE_BIT,
 				VK_ACCESS_TRANSFER_READ_BIT,
 				*inputBuffer,
 				0u,
 				imageSizeInBytes
 			);
-
 			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &inputBufferBarrier, 0u, DE_NULL);
 		}
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferDstBarrier = makeImageMemoryBarrier
-			(
-				0u,
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_IMAGE_LAYOUT_UNDEFINED,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				*imageSparse,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
-				);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferDstBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferDstBarriers.push_back( makeImageMemoryBarrier (
+					0u,
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					*imageSparse,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
+				));
+			}
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferDstBarriers.size()), imageSparseTransferDstBarriers.data());
 		}
 
-		deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+		deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferSrcBarrier = makeImageMemoryBarrier
-			(
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_ACCESS_TRANSFER_READ_BIT,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-				*imageSparse,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
-			);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferSrcBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferSrcBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferSrcBarriers.push_back( makeImageMemoryBarrier (
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_ACCESS_TRANSFER_READ_BIT,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+					*imageSparse,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
+				));
+			}
+
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferSrcBarriers.size()), imageSparseTransferSrcBarriers.data());
 		}
 
 		const VkBufferCreateInfo		outputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
 		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
 
-		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
 			const VkBufferMemoryBarrier outputBufferBarrier = makeBufferMemoryBarrier
@@ -378,18 +409,21 @@
 		// Retrieve data from buffer to host memory
 		invalidateAlloc(deviceInterface, getDevice(), *outputBufferAlloc);
 
-		const deUint8* outputData = static_cast<const deUint8*>(outputBufferAlloc->getHostPtr());
-
 		// Wait for sparse queue to become idle
 		deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
-		{
-			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
-			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[mipmapNdx].bufferOffset);
+		const deUint8* outputData = static_cast<const deUint8*>(outputBufferAlloc->getHostPtr());
 
-			if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
-				return tcu::TestStatus::fail("Failed");
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx);
+				const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[ planeNdx * imageSparseInfo.mipLevels + mipmapNdx].bufferOffset);
+
+				if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+					return tcu::TestStatus::fail("Failed");
+			}
 		}
 	}
 
@@ -405,49 +439,38 @@
 
 tcu::TestCaseGroup* createImageSparseBindingTestsCommon(tcu::TestContext& testCtx, de::MovePtr<tcu::TestCaseGroup> testGroup, const bool useDeviceGroup = false)
 {
-	static const deUint32 sizeCountPerImageType = 3u;
-
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSizes[sizeCountPerImageType];
+		{ IMAGE_TYPE_1D,			{ tcu::UVec3(512u, 1u,   1u ),	tcu::UVec3(1024u, 1u,   1u),	tcu::UVec3(11u,  1u,   1u) },	getTestFormats(IMAGE_TYPE_1D) },
+		{ IMAGE_TYPE_1D_ARRAY,		{ tcu::UVec3(512u, 1u,   64u),	tcu::UVec3(1024u, 1u,   8u),	tcu::UVec3(11u,  1u,   3u) },	getTestFormats(IMAGE_TYPE_1D_ARRAY) },
+		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u, 1u ),	tcu::UVec3(1024u, 128u, 1u),	tcu::UVec3(11u,  137u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u, 6u ),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_3D,			{ tcu::UVec3(512u, 256u, 6u ),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_3D) },
+		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u, 1u ),	tcu::UVec3(128u,  128u, 1u),	tcu::UVec3(137u, 137u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u, 6u ),	tcu::UVec3(128u,  128u, 8u),	tcu::UVec3(137u, 137u, 3u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) }
 	};
 
-	static const ImageParameters imageParametersArray[] =
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		{ IMAGE_TYPE_1D,		{ tcu::UVec3(512u, 1u,   1u ), tcu::UVec3(1024u, 1u,   1u), tcu::UVec3(11u,  1u,   1u) } },
-		{ IMAGE_TYPE_1D_ARRAY,  { tcu::UVec3(512u, 1u,   64u), tcu::UVec3(1024u, 1u,   8u), tcu::UVec3(11u,  1u,   3u) } },
-		{ IMAGE_TYPE_2D,		{ tcu::UVec3(512u, 256u, 1u ), tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u,  137u, 1u) } },
-		{ IMAGE_TYPE_2D_ARRAY,	{ tcu::UVec3(512u, 256u, 6u ), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } },
-		{ IMAGE_TYPE_3D,		{ tcu::UVec3(512u, 256u, 6u ), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } },
-		{ IMAGE_TYPE_CUBE,		{ tcu::UVec3(256u, 256u, 1u ), tcu::UVec3(128u,  128u, 1u), tcu::UVec3(137u, 137u, 1u) } },
-		{ IMAGE_TYPE_CUBE_ARRAY,{ tcu::UVec3(256u, 256u, 6u ), tcu::UVec3(128u,  128u, 8u), tcu::UVec3(137u, 137u, 3u) } }
-	};
+		const ImageType					imageType		= imageParameters[imageTypeNdx].imageType;
+		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup	(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT8)
-	};
-
-
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
-	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
-		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
-
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&		format = formats[formatNdx];
-			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+			VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
-			for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
+			for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
 			{
-				const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
+				const tcu::UVec3 imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
+
+				// skip test for images with odd sizes for some YCbCr formats
+				if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+					continue;
+				if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+					continue;
+
 				std::ostringstream	stream;
 				stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseResidency.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseResidency.cpp
index be9b01c..cafb299 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseResidency.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseResidency.cpp
@@ -39,12 +39,18 @@
 #include "vkTypeUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkObjUtil.hpp"
+#include "tcuTestLog.hpp"
 
+#include "deMath.h"
 #include "deUniquePtr.hpp"
 #include "deStringUtil.hpp"
 
+#include "tcuTextureUtil.hpp"
+#include "tcuTexVerifierUtil.hpp"
+
 #include <string>
 #include <vector>
+#include <sstream>
 
 using namespace vk;
 
@@ -55,10 +61,31 @@
 namespace
 {
 
-const std::string getCoordStr  (const ImageType		imageType,
-								const std::string&	x,
-								const std::string&	y,
-								const std::string&	z)
+std::string getFormatValueString	(const std::vector<std::pair<deUint32, deUint32>>& channelsOnPlane,
+									 const std::vector<std::string>& formatValueStrings)
+{
+	std::string result = "( ";
+	deUint32 i;
+	for (i=0; i<channelsOnPlane.size(); ++i)
+	{
+		result += formatValueStrings[channelsOnPlane[i].first];
+		if (i < 3)
+			result += ", ";
+	}
+	for (; i < 4; ++i)
+	{
+		result += "0";
+		if (i < 3)
+			result += ", ";
+	}
+	result += " )";
+	return result;
+}
+
+const std::string getCoordStr	(const ImageType	imageType,
+								 const std::string&	x,
+								 const std::string&	y,
+								 const std::string&	z)
 {
 	switch (imageType)
 	{
@@ -82,14 +109,14 @@
 	}
 }
 
-tcu::UVec3 computeWorkGroupSize (const tcu::UVec3& gridSize)
+tcu::UVec3 computeWorkGroupSize (const VkExtent3D& planeExtent)
 {
 	const deUint32		maxComputeWorkGroupInvocations	= 128u;
 	const tcu::UVec3	maxComputeWorkGroupSize			= tcu::UVec3(128u, 128u, 64u);
 
-	const deUint32 xWorkGroupSize = std::min(std::min(gridSize.x(), maxComputeWorkGroupSize.x()), maxComputeWorkGroupInvocations);
-	const deUint32 yWorkGroupSize = std::min(std::min(gridSize.y(), maxComputeWorkGroupSize.y()), maxComputeWorkGroupInvocations /  xWorkGroupSize);
-	const deUint32 zWorkGroupSize = std::min(std::min(gridSize.z(), maxComputeWorkGroupSize.z()), maxComputeWorkGroupInvocations / (xWorkGroupSize*yWorkGroupSize));
+	const deUint32 xWorkGroupSize = std::min(std::min(planeExtent.width,	maxComputeWorkGroupSize.x()), maxComputeWorkGroupInvocations);
+	const deUint32 yWorkGroupSize = std::min(std::min(planeExtent.height,	maxComputeWorkGroupSize.y()), maxComputeWorkGroupInvocations /  xWorkGroupSize);
+	const deUint32 zWorkGroupSize = std::min(std::min(planeExtent.depth,	maxComputeWorkGroupSize.z()), maxComputeWorkGroupInvocations / (xWorkGroupSize*yWorkGroupSize));
 
 	return tcu::UVec3(xWorkGroupSize, yWorkGroupSize, zWorkGroupSize);
 }
@@ -97,95 +124,164 @@
 class ImageSparseResidencyCase : public TestCase
 {
 public:
-					ImageSparseResidencyCase	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const std::string&			description,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format,
-												 const glu::GLSLVersion		glslVersion,
-												 const bool					useDeviceGroups);
+	ImageSparseResidencyCase		(tcu::TestContext&		testCtx,
+									 const std::string&		name,
+									 const std::string&		description,
+									 const ImageType		imageType,
+									 const tcu::UVec3&		imageSize,
+									 const VkFormat			format,
+									 const glu::GLSLVersion	glslVersion,
+									 const bool				useDeviceGroups);
 
-	void			initPrograms				(SourceCollections&			sourceCollections) const;
-	TestInstance*	createInstance				(Context&					context) const;
+	void			initPrograms	(SourceCollections&		sourceCollections) const;
+	virtual void	checkSupport	(Context&				context) const;
+	TestInstance*	createInstance	(Context&				context) const;
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
-	const glu::GLSLVersion		m_glslVersion;
+	const bool				m_useDeviceGroups;
+	const ImageType			m_imageType;
+	const tcu::UVec3		m_imageSize;
+	const VkFormat			m_format;
+	const glu::GLSLVersion	m_glslVersion;
 };
 
-ImageSparseResidencyCase::ImageSparseResidencyCase (tcu::TestContext&			testCtx,
-													const std::string&			name,
-													const std::string&			description,
-													const ImageType				imageType,
-													const tcu::UVec3&			imageSize,
-													const tcu::TextureFormat&	format,
-													const glu::GLSLVersion		glslVersion,
-													const bool					useDeviceGroups)
-	: TestCase				(testCtx, name, description)
-	, m_useDeviceGroups		(useDeviceGroups)
-	, m_imageType			(imageType)
-	, m_imageSize			(imageSize)
-	, m_format				(format)
-	, m_glslVersion			(glslVersion)
+ImageSparseResidencyCase::ImageSparseResidencyCase	(tcu::TestContext&		testCtx,
+													 const std::string&		name,
+													 const std::string&		description,
+													 const ImageType		imageType,
+													 const tcu::UVec3&		imageSize,
+													 const VkFormat			format,
+													 const glu::GLSLVersion	glslVersion,
+													 const bool				useDeviceGroups)
+	: TestCase			(testCtx, name, description)
+	, m_useDeviceGroups	(useDeviceGroups)
+	, m_imageType		(imageType)
+	, m_imageSize		(imageSize)
+	, m_format			(format)
+	, m_glslVersion		(glslVersion)
 {
 }
 
 void ImageSparseResidencyCase::initPrograms (SourceCollections&	sourceCollections) const
 {
 	// Create compute program
-	const char* const versionDecl			= glu::getGLSLVersionDeclaration(m_glslVersion);
-	const std::string imageTypeStr			= getShaderImageType(m_format, m_imageType);
-	const std::string formatQualifierStr	= getShaderImageFormatQualifier(m_format);
-	const std::string formatDataStr			= getShaderImageDataType(m_format);
-	const tcu::UVec3  gridSize				= getShaderGridSize(m_imageType, m_imageSize);
-	const tcu::UVec3  workGroupSize			= computeWorkGroupSize(gridSize);
+	const char* const				versionDecl			= glu::getGLSLVersionDeclaration(m_glslVersion);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
+	const std::string				imageTypeStr		= getShaderImageType(formatDescription, m_imageType);
+	const std::string				formatDataStr		= getShaderImageDataType(formatDescription);
+	const tcu::UVec3				shaderGridSize		= getShaderGridSize(m_imageType, m_imageSize);
 
-	std::ostringstream src;
-	src << versionDecl << "\n"
-		<< "layout (local_size_x = " << workGroupSize.x() << ", local_size_y = " << workGroupSize.y() << ", local_size_z = " << workGroupSize.z() << ") in; \n"
-		<< "layout (binding = 0, " << formatQualifierStr << ") writeonly uniform highp " << imageTypeStr << " u_image;\n"
-		<< "void main (void)\n"
-		<< "{\n"
-		<< "	if( gl_GlobalInvocationID.x < " << gridSize.x() << " ) \n"
-		<< "	if( gl_GlobalInvocationID.y < " << gridSize.y() << " ) \n"
-		<< "	if( gl_GlobalInvocationID.z < " << gridSize.z() << " ) \n"
-		<< "	{\n"
-		<< "		imageStore(u_image, " << getCoordStr(m_imageType, "gl_GlobalInvocationID.x", "gl_GlobalInvocationID.y", "gl_GlobalInvocationID.z") << ","
-		<< formatDataStr << "( int(gl_GlobalInvocationID.x) % 127, int(gl_GlobalInvocationID.y) % 127, int(gl_GlobalInvocationID.z) % 127, 1));\n"
-		<< "	}\n"
-		<< "}\n";
+	std::vector<std::string>		formatValueStrings;
+	switch (formatDescription.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			formatValueStrings = {
+				"int(gl_GlobalInvocationID.x) % 127",
+				"int(gl_GlobalInvocationID.y) % 127",
+				"int(gl_GlobalInvocationID.z) % 127",
+				"1"
+			};
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			formatValueStrings = {
+				"float(int(gl_GlobalInvocationID.x) % 127) / 127.0" ,
+				"float(int(gl_GlobalInvocationID.y) % 127) / 127.0",
+				"float(int(gl_GlobalInvocationID.z) % 127) / 127.0",
+				"1.0"
+			};
+			break;
+		default:	DE_ASSERT(false);	break;
+	}
 
-	sourceCollections.glslSources.add("comp") << glu::ComputeSource(src.str());
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+	{
+		VkFormat						planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+		vk::PlanarFormatDescription		compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+		VkExtent3D						compatibleShaderGridSize	{ shaderGridSize.x() / formatDescription.blockWidth, shaderGridSize.y() / formatDescription.blockHeight, shaderGridSize.z() / 1u };
+
+		std::vector<std::pair<deUint32, deUint32>> channelsOnPlane;
+		for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
+		{
+			if (!formatDescription.hasChannelNdx(channelNdx))
+				continue;
+			if (formatDescription.channels[channelNdx].planeNdx != planeNdx)
+				continue;
+			channelsOnPlane.push_back({ channelNdx,formatDescription.channels[channelNdx].offsetBits });
+		}
+		// reorder channels for multi-planar images
+		if(formatDescription.numPlanes>1)
+			std::sort(begin(channelsOnPlane), end(channelsOnPlane), [](const std::pair<deUint32, deUint32>& lhs, const std::pair<deUint32, deUint32>& rhs) { return lhs.second < rhs.second; });
+		std::string			formatValueStr		= getFormatValueString(channelsOnPlane, formatValueStrings);
+		VkExtent3D			shaderExtent		= getPlaneExtent(compatibleFormatDescription, compatibleShaderGridSize, planeNdx, 0);
+		const std::string	formatQualifierStr	= getShaderImageFormatQualifier(planeCompatibleFormat);
+		const tcu::UVec3	workGroupSize		= computeWorkGroupSize(shaderExtent);
+
+		std::ostringstream src;
+		src << versionDecl << "\n"
+			<< "layout (local_size_x = " << workGroupSize.x() << ", local_size_y = " << workGroupSize.y() << ", local_size_z = " << workGroupSize.z() << ") in; \n"
+			<< "layout (binding = 0, " << formatQualifierStr << ") writeonly uniform highp " << imageTypeStr << " u_image;\n"
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "	if( gl_GlobalInvocationID.x < " << shaderExtent.width << " ) \n"
+			<< "	if( gl_GlobalInvocationID.y < " << shaderExtent.height << " ) \n"
+			<< "	if( gl_GlobalInvocationID.z < " << shaderExtent.depth << " ) \n"
+			<< "	{\n"
+			<< "		imageStore(u_image, " << getCoordStr(m_imageType, "gl_GlobalInvocationID.x", "gl_GlobalInvocationID.y", "gl_GlobalInvocationID.z") << ","
+			<< formatDataStr << formatValueStr << ");\n"
+			<< "	}\n"
+			<< "}\n";
+		std::ostringstream shaderName;
+		shaderName << "comp" << planeNdx;
+		sourceCollections.glslSources.add(shaderName.str()) << glu::ComputeSource(src.str());
+	}
+}
+
+void ImageSparseResidencyCase::checkSupport(Context& context) const
+{
+	const InstanceInterface&	instance = context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice = context.getPhysicalDevice();
+
+	// Check if image size does not exceed device limits
+	if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+		TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+	// Check if device supports sparse operations for image type
+	if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+		TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+
+	 //Check if image format supports storage images
+	const VkFormatProperties	formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, m_format);
+	if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
+		TCU_THROW(NotSupportedError, "Storage images are not supported for this format");
 }
 
 class ImageSparseResidencyInstance : public SparseResourcesBaseInstance
 {
 public:
-					ImageSparseResidencyInstance(Context&									 context,
-												 const ImageType							 imageType,
-												 const tcu::UVec3&							 imageSize,
-												 const tcu::TextureFormat&					 format,
-												 const bool									 useDeviceGroups);
+	ImageSparseResidencyInstance	(Context&			context,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format,
+									 const bool			useDeviceGroups);
 
 
-	tcu::TestStatus	iterate						(void);
+	tcu::TestStatus	iterate			(void);
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-ImageSparseResidencyInstance::ImageSparseResidencyInstance (Context&					context,
-															const ImageType				imageType,
-															const tcu::UVec3&			imageSize,
-															const tcu::TextureFormat&	format,
-															const bool					useDeviceGroups)
+ImageSparseResidencyInstance::ImageSparseResidencyInstance	(Context&			context,
+															 const ImageType	imageType,
+															 const tcu::UVec3&	imageSize,
+															 const VkFormat		format,
+															 const bool			useDeviceGroups)
 	: SparseResourcesBaseInstance	(context, useDeviceGroups)
 	, m_useDeviceGroups				(useDeviceGroups)
 	, m_imageType					(imageType)
@@ -196,7 +292,8 @@
 
 tcu::TestStatus ImageSparseResidencyInstance::iterate (void)
 {
-	const InstanceInterface&			instance = m_context.getInstanceInterface();
+	const float					epsilon				= 1e-5f;
+	const InstanceInterface&	instance			= m_context.getInstanceInterface();
 
 	{
 		// Create logical device supporting both sparse and compute queues
@@ -207,14 +304,13 @@
 		createDeviceSupportingQueues(queueRequirements);
 	}
 
-	VkImageCreateInfo					imageCreateInfo;
-	VkSparseImageMemoryRequirements		aspectRequirements;
-	VkExtent3D							imageGranularity;
-	std::vector<DeviceMemorySp>			deviceMemUniquePtrVec;
+	VkImageCreateInfo			imageCreateInfo;
+	std::vector<DeviceMemorySp>	deviceMemUniquePtrVec;
 
-	const DeviceInterface&	deviceInterface	= getDeviceInterface();
-	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-	const Queue&			computeQueue	= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const DeviceInterface&			deviceInterface		= getDeviceInterface();
+	const Queue&					sparseQueue			= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+	const Queue&					computeQueue		= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
 
 	// Go through all physical devices
 	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
@@ -225,19 +321,11 @@
 		const VkPhysicalDevice				physicalDevice				= getPhysicalDevice(firstDeviceID);
 		const VkPhysicalDeviceProperties	physicalDeviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
 
-		// Check if image size does not exceed device limits
-		if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-			TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-		// Check if device supports sparse operations for image type
-		if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-			TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
 		imageCreateInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
 		imageCreateInfo.pNext					= DE_NULL;
 		imageCreateInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 		imageCreateInfo.imageType				= mapImageType(m_imageType);
-		imageCreateInfo.format					= mapTextureFormat(m_format);
+		imageCreateInfo.format					= m_format;
 		imageCreateInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 		imageCreateInfo.mipLevels				= 1u;
 		imageCreateInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
@@ -255,46 +343,34 @@
 			imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 		}
 
+		// check if we need to create VkImageView with different VkFormat than VkImage format
+		VkFormat planeCompatibleFormat0 = getPlaneCompatibleFormatForWriting(formatDescription, 0);
+		if (planeCompatibleFormat0 != getPlaneCompatibleFormat(formatDescription, 0))
+		{
+			imageCreateInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+		}
+
 		// Check if device supports sparse operations for image format
 		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageCreateInfo))
 			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
 
 		// Create sparse image
-		const Unique<VkImage> sparseImage(createImage(deviceInterface, getDevice(), &imageCreateInfo));
+		const Unique<VkImage> imageSparse(createImage(deviceInterface, getDevice(), &imageCreateInfo));
 
 		// Create sparse image memory bind semaphore
 		const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
 
+		std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements;
+
 		{
 			// Get image general memory requirements
-			const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
+			const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
 			if (imageMemoryRequirements.size > physicalDeviceProperties.limits.sparseAddressSpaceSize)
 				TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits");
 
 			DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
 
-			// Get sparse image sparse memory requirements
-			const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
-
-			DE_ASSERT(sparseMemoryRequirements.size() != 0);
-
-			const deUint32 colorAspectIndex		= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
-			const deUint32 metadataAspectIndex	= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
-
-			if (colorAspectIndex == NO_MATCH_FOUND)
-				TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
-
-			aspectRequirements	= sparseMemoryRequirements[colorAspectIndex];
-			imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
-
-			const VkImageAspectFlags aspectMask = aspectRequirements.formatProperties.aspectMask;
-
-			DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
-
-			std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
-			std::vector<VkSparseMemoryBind>		 imageMipTailMemoryBinds;
-
 			const deUint32						 memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
 			if (memoryType == NO_MATCH_FOUND)
@@ -313,84 +389,104 @@
 				}
 			}
 
+			// Get sparse image sparse memory requirements
+			sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
+			DE_ASSERT(sparseMemoryRequirements.size() != 0);
+
+			const deUint32 metadataAspectIndex = getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
+
+			std::vector<VkSparseImageMemoryBind>	imageResidencyMemoryBinds;
+			std::vector<VkSparseMemoryBind>			imageMipTailMemoryBinds;
+
 			// Bind device memory for each aspect
-			for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 			{
-				for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+				const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+				const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
+
+				if (aspectIndex == NO_MATCH_FOUND)
+					TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+				VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+				VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
+
+				for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
 				{
-					const VkImageSubresource subresource		= { aspectMask, mipLevelNdx, layerNdx };
-					const VkExtent3D		 mipExtent			= mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
-					const tcu::UVec3		 numSparseBinds		= alignedDivide(mipExtent, imageGranularity);
-					const tcu::UVec3		 lastBlockExtent	= tcu::UVec3(mipExtent.width  % imageGranularity.width  ? mipExtent.width   % imageGranularity.width  : imageGranularity.width,
-																			 mipExtent.height % imageGranularity.height ? mipExtent.height  % imageGranularity.height : imageGranularity.height,
-																			 mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth   % imageGranularity.depth  : imageGranularity.depth);
-					for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
-					for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
-					for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
+					for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
 					{
-						const deUint32 linearIndex = x + y*numSparseBinds.x() + z*numSparseBinds.x()*numSparseBinds.y() + layerNdx*numSparseBinds.x()*numSparseBinds.y()*numSparseBinds.z();
+						const VkImageSubresource subresource		= { aspect, mipLevelNdx, layerNdx };
+						const VkExtent3D		 planeExtent		= getPlaneExtent(formatDescription, imageCreateInfo.extent, planeNdx, mipLevelNdx);
+						const tcu::UVec3		 numSparseBinds		= alignedDivide(planeExtent, imageGranularity);
+						const tcu::UVec3		 lastBlockExtent	= tcu::UVec3(planeExtent.width  % imageGranularity.width  ? planeExtent.width  % imageGranularity.width  : imageGranularity.width,
+																				 planeExtent.height % imageGranularity.height ? planeExtent.height % imageGranularity.height : imageGranularity.height,
+																				 planeExtent.depth  % imageGranularity.depth  ? planeExtent.depth  % imageGranularity.depth  : imageGranularity.depth);
 
-						if (linearIndex % 2u == 1u)
+						for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
+						for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
+						for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
 						{
-							continue;
+							const deUint32 linearIndex = x + y * numSparseBinds.x() + z * numSparseBinds.x() * numSparseBinds.y() + layerNdx * numSparseBinds.x() * numSparseBinds.y() * numSparseBinds.z();
+
+							if (linearIndex % 2u == 0u)
+							{
+								VkOffset3D offset;
+								offset.x		= x * imageGranularity.width;
+								offset.y		= y * imageGranularity.height;
+								offset.z		= z * imageGranularity.depth;
+
+								VkExtent3D extent;
+								extent.width	= (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
+								extent.height	= (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
+								extent.depth	= (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
+
+								const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
+									imageMemoryRequirements.alignment, memoryType, subresource, offset, extent);
+
+								deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+								imageResidencyMemoryBinds.push_back(imageMemoryBind);
+							}
 						}
-
-						VkOffset3D offset;
-						offset.x = x*imageGranularity.width;
-						offset.y = y*imageGranularity.height;
-						offset.z = z*imageGranularity.depth;
-
-						VkExtent3D extent;
-						extent.width  = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
-						extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
-						extent.depth  = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
-
-						const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
-							imageMemoryRequirements.alignment, memoryType, subresource, offset, extent);
-
-						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-						imageResidencyMemoryBinds.push_back(imageMemoryBind);
 					}
-				}
 
-				if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
-				{
-					const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
-
-					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-					imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
-				}
-
-				// Metadata
-				if (metadataAspectIndex != NO_MATCH_FOUND)
-				{
-					const VkSparseImageMemoryRequirements metadataAspectRequirements = sparseMemoryRequirements[metadataAspectIndex];
-
-					if (!(metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT))
+					if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
 					{
 						const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-							metadataAspectRequirements.imageMipTailSize, memoryType,
-							metadataAspectRequirements.imageMipTailOffset + layerNdx * metadataAspectRequirements.imageMipTailStride,
-							VK_SPARSE_MEMORY_BIND_METADATA_BIT);
+							aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
 
 						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
 						imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
 					}
+
+					// Metadata
+					if (metadataAspectIndex != NO_MATCH_FOUND)
+					{
+						const VkSparseImageMemoryRequirements metadataAspectRequirements = sparseMemoryRequirements[metadataAspectIndex];
+
+						if (!(metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT))
+						{
+							const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+								metadataAspectRequirements.imageMipTailSize, memoryType,
+								metadataAspectRequirements.imageMipTailOffset + layerNdx * metadataAspectRequirements.imageMipTailStride,
+								VK_SPARSE_MEMORY_BIND_METADATA_BIT);
+
+							deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+							imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+						}
+					}
 				}
-			}
 
-			if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
-			{
-				const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
+				if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
+				{
+					const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
 
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
-				imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+					imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+				}
 			}
 
 			// Metadata
@@ -434,14 +530,14 @@
 				&imageMemoryBindSemaphore.get()							//const VkSemaphore*						pSignalSemaphores;
 			};
 
-			VkSparseImageMemoryBindInfo		  imageResidencyBindInfo;
-			VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo;
+			VkSparseImageMemoryBindInfo			imageResidencyBindInfo;
+			VkSparseImageOpaqueMemoryBindInfo	imageMipTailBindInfo;
 
 			if (imageResidencyMemoryBinds.size() > 0)
 			{
-				imageResidencyBindInfo.image		= *sparseImage;
+				imageResidencyBindInfo.image		= *imageSparse;
 				imageResidencyBindInfo.bindCount	= static_cast<deUint32>(imageResidencyMemoryBinds.size());
-				imageResidencyBindInfo.pBinds		= &imageResidencyMemoryBinds[0];
+				imageResidencyBindInfo.pBinds		= imageResidencyMemoryBinds.data();
 
 				bindSparseInfo.imageBindCount		= 1u;
 				bindSparseInfo.pImageBinds			= &imageResidencyBindInfo;
@@ -449,9 +545,9 @@
 
 			if (imageMipTailMemoryBinds.size() > 0)
 			{
-				imageMipTailBindInfo.image			= *sparseImage;
+				imageMipTailBindInfo.image			= *imageSparse;
 				imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailMemoryBinds.size());
-				imageMipTailBindInfo.pBinds			= &imageMipTailMemoryBinds[0];
+				imageMipTailBindInfo.pBinds			= imageMipTailMemoryBinds.data();
 
 				bindSparseInfo.imageOpaqueBindCount = 1u;
 				bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
@@ -461,9 +557,9 @@
 			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
 		}
 
-		// Create command buffer for compute and transfer oparations
-		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
-		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+		// Create command buffer for compute and transfer operations
+		const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
+		const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
 		// Start recording commands
 		beginCommandBuffer(deviceInterface, *commandBuffer);
@@ -474,92 +570,134 @@
 			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
 			.build(deviceInterface, getDevice()));
 
-		// Create and bind compute pipeline
-		const Unique<VkShaderModule>	shaderModule(createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("comp"), DE_NULL));
-		const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, getDevice(), *descriptorSetLayout));
-		const Unique<VkPipeline>		computePipeline(makeComputePipeline(deviceInterface, getDevice(), *pipelineLayout, *shaderModule));
-
-		deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
-
 		// Create and bind descriptor set
 		const Unique<VkDescriptorPool> descriptorPool(
 			DescriptorPoolBuilder()
 			.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u)
-			.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
+			.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, vk::PlanarFormatDescription::MAX_PLANES));
 
-		const Unique<VkDescriptorSet>	descriptorSet(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
+		const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, getDevice(), *descriptorSetLayout));
+		std::vector<de::SharedPtr<vk::Unique<vk::VkShaderModule>>>	shaderModules;
+		std::vector<de::SharedPtr<vk::Unique<vk::VkPipeline>>>		computePipelines;
+		std::vector<de::SharedPtr<vk::Unique<vk::VkDescriptorSet>>>	descriptorSets;
+		std::vector<de::SharedPtr<vk::Unique<vk::VkImageView>>>		imageViews;
 
-		const VkImageSubresourceRange	subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));
-		const Unique<VkImageView>		imageView(makeImageView(deviceInterface, getDevice(), *sparseImage, mapImageViewType(m_imageType), mapTextureFormat(m_format), subresourceRange));
-		const VkDescriptorImageInfo		sparseImageInfo  = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
+		const tcu::UVec3 shaderGridSize = getShaderGridSize(m_imageType, m_imageSize);
 
-		DescriptorSetUpdateBuilder()
-			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &sparseImageInfo)
-			.update(deviceInterface, getDevice());
-
-		deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
-
+		// Run compute shader for each image plane
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			const VkImageMemoryBarrier sparseImageLayoutChangeBarrier = makeImageMemoryBarrier
-			(
-				0u,
-				VK_ACCESS_SHADER_WRITE_BIT,
-				VK_IMAGE_LAYOUT_UNDEFINED,
-				VK_IMAGE_LAYOUT_GENERAL,
-				*sparseImage,
-				subresourceRange,
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
-				);
+			const VkImageAspectFlags		aspect						= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+			const VkImageSubresourceRange	subresourceRange			= makeImageSubresourceRange(aspect, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));
+			VkFormat						planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+			vk::PlanarFormatDescription		compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+			const tcu::UVec3				compatibleShaderGridSize	( shaderGridSize.x() / formatDescription.blockWidth, shaderGridSize.y() / formatDescription.blockHeight, shaderGridSize.z() / 1u);
+			VkExtent3D						shaderExtent				= getPlaneExtent(compatibleFormatDescription, VkExtent3D{ compatibleShaderGridSize.x(), compatibleShaderGridSize.y(), compatibleShaderGridSize.z() }, planeNdx, 0u);
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &sparseImageLayoutChangeBarrier);
-		}
+			// Create and bind compute pipeline
+			std::ostringstream shaderName;
+			shaderName << "comp" << planeNdx;
+			auto shaderModule		= makeVkSharedPtr(createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get(shaderName.str()), DE_NULL));
+			shaderModules.push_back(shaderModule);
+			auto computePipeline	= makeVkSharedPtr(makeComputePipeline(deviceInterface, getDevice(), *pipelineLayout, shaderModule->get()));
+			computePipelines.push_back(computePipeline);
+			deviceInterface.cmdBindPipeline	(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->get());
 
-		const tcu::UVec3  gridSize = getShaderGridSize(m_imageType, m_imageSize);
+			auto descriptorSet		= makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
+			descriptorSets.push_back(descriptorSet);
 
-		{
-			const tcu::UVec3  workGroupSize = computeWorkGroupSize(gridSize);
+			auto imageView			= makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), *imageSparse, mapImageViewType(m_imageType), planeCompatibleFormat, subresourceRange));
+			imageViews.push_back(imageView);
+			const VkDescriptorImageInfo		imageSparseInfo			= makeDescriptorImageInfo(DE_NULL, imageView->get(), VK_IMAGE_LAYOUT_GENERAL);
 
-			const deUint32 xWorkGroupCount = gridSize.x() / workGroupSize.x() + (gridSize.x() % workGroupSize.x() ? 1u : 0u);
-			const deUint32 yWorkGroupCount = gridSize.y() / workGroupSize.y() + (gridSize.y() % workGroupSize.y() ? 1u : 0u);
-			const deUint32 zWorkGroupCount = gridSize.z() / workGroupSize.z() + (gridSize.z() % workGroupSize.z() ? 1u : 0u);
+			DescriptorSetUpdateBuilder()
+				.writeSingle(descriptorSet->get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageSparseInfo)
+				.update(deviceInterface, getDevice());
 
-			const tcu::UVec3 maxComputeWorkGroupCount = tcu::UVec3(65535u, 65535u, 65535u);
+			deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet->get(), 0u, DE_NULL);
 
-			if (maxComputeWorkGroupCount.x() < xWorkGroupCount ||
-				maxComputeWorkGroupCount.y() < yWorkGroupCount ||
-				maxComputeWorkGroupCount.z() < zWorkGroupCount)
 			{
-				TCU_THROW(NotSupportedError, "Image size is not supported");
+				const VkImageMemoryBarrier imageSparseLayoutChangeBarrier = makeImageMemoryBarrier
+				(
+					0u,
+					VK_ACCESS_SHADER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED,
+					VK_IMAGE_LAYOUT_GENERAL,
+					*imageSparse,
+					subresourceRange,
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
+					);
+
+				deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseLayoutChangeBarrier);
 			}
 
-			deviceInterface.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
+			{
+				const tcu::UVec3 workGroupSize = computeWorkGroupSize(shaderExtent);
+
+				const deUint32 xWorkGroupCount = shaderExtent.width  / workGroupSize.x() + (shaderExtent.width  % workGroupSize.x() ? 1u : 0u);
+				const deUint32 yWorkGroupCount = shaderExtent.height / workGroupSize.y() + (shaderExtent.height % workGroupSize.y() ? 1u : 0u);
+				const deUint32 zWorkGroupCount = shaderExtent.depth  / workGroupSize.z() + (shaderExtent.depth  % workGroupSize.z() ? 1u : 0u);
+
+				const tcu::UVec3 maxComputeWorkGroupCount = tcu::UVec3(65535u, 65535u, 65535u);
+
+				if (maxComputeWorkGroupCount.x() < xWorkGroupCount ||
+					maxComputeWorkGroupCount.y() < yWorkGroupCount ||
+					maxComputeWorkGroupCount.z() < zWorkGroupCount)
+				{
+					TCU_THROW(NotSupportedError, "Image size is not supported");
+				}
+
+				deviceInterface.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
+			}
+
+			{
+				const VkImageMemoryBarrier imageSparseTransferBarrier = makeImageMemoryBarrier
+				(
+					VK_ACCESS_SHADER_WRITE_BIT,
+					VK_ACCESS_TRANSFER_READ_BIT,
+					VK_IMAGE_LAYOUT_GENERAL,
+					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+					*imageSparse,
+					subresourceRange
+				);
+
+				deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferBarrier);
+			}
 		}
 
+		deUint32	imageSizeInBytes = 0;
+		deUint32	planeOffsets[PlanarFormatDescription::MAX_PLANES];
+		deUint32	planeRowPitches[PlanarFormatDescription::MAX_PLANES];
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			const VkImageMemoryBarrier sparseImageTrasferBarrier = makeImageMemoryBarrier
-			(
-				VK_ACCESS_SHADER_WRITE_BIT,
-				VK_ACCESS_TRANSFER_READ_BIT,
-				VK_IMAGE_LAYOUT_GENERAL,
-				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-				*sparseImage,
-				subresourceRange
-			);
-
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &sparseImageTrasferBarrier);
+			planeOffsets[planeNdx]		= imageSizeInBytes;
+			const deUint32	planeW		= imageCreateInfo.extent.width / (formatDescription.blockWidth * formatDescription.planes[planeNdx].widthDivisor);
+			planeRowPitches[planeNdx]	= formatDescription.planes[planeNdx].elementSizeBytes * planeW;
+			imageSizeInBytes			+= getImageMipLevelSizeInBytes(imageCreateInfo.extent, imageCreateInfo.arrayLayers, formatDescription, planeNdx, 0, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 		}
 
-		const deUint32					imageSizeInBytes		= getNumPixels(m_imageType, m_imageSize) * tcu::getPixelSize(m_format);
 		const VkBufferCreateInfo		outputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
 		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
+		std::vector<VkBufferImageCopy>	bufferImageCopy			(formatDescription.numPlanes);
 
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			const VkBufferImageCopy bufferImageCopy = makeBufferImageCopy(imageCreateInfo.extent, imageCreateInfo.arrayLayers);
+			const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
 
-			deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *sparseImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, 1u, &bufferImageCopy);
+			bufferImageCopy[planeNdx] =
+			{
+				planeOffsets[planeNdx],														//	VkDeviceSize				bufferOffset;
+				0u,																			//	deUint32					bufferRowLength;
+				0u,																			//	deUint32					bufferImageHeight;
+				makeImageSubresourceLayers(aspect, 0u, 0u, imageCreateInfo.arrayLayers),	//	VkImageSubresourceLayers	imageSubresource;
+				makeOffset3D(0, 0, 0),														//	VkOffset3D					imageOffset;
+				vk::getPlaneExtent(formatDescription, imageCreateInfo.extent, planeNdx, 0)	//	VkExtent3D					imageExtent;
+			};
 		}
+		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
 			const VkBufferMemoryBarrier outputBufferHostReadBarrier = makeBufferMemoryBarrier
@@ -586,83 +724,263 @@
 
 		// Retrieve data from buffer to host memory
 		invalidateAlloc(deviceInterface, getDevice(), *outputBufferAlloc);
+		deUint8*	outputData	= static_cast<deUint8*>(outputBufferAlloc->getHostPtr());
+		void*		planePointers[PlanarFormatDescription::MAX_PLANES];
 
-		const deUint8* outputData = static_cast<const deUint8*>(outputBufferAlloc->getHostPtr());
-		const tcu::ConstPixelBufferAccess pixelBuffer = tcu::ConstPixelBufferAccess(m_format, gridSize.x(), gridSize.y(), gridSize.z(), outputData);
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			planePointers[planeNdx] = outputData + static_cast<size_t>(planeOffsets[planeNdx]);
 
 		// Wait for sparse queue to become idle
 		//vsk fails:
 		deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-		// Validate results
-		if( aspectRequirements.imageMipTailFirstLod > 0u )
+		// write result images to log file
+		for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
 		{
-			const VkExtent3D		 mipExtent		 = mipLevelExtents(imageCreateInfo.extent, 0u);
-			const tcu::UVec3		 numSparseBinds  = alignedDivide(mipExtent, imageGranularity);
-			const tcu::UVec3		 lastBlockExtent = tcu::UVec3(	mipExtent.width  % imageGranularity.width  ? mipExtent.width  % imageGranularity.width  : imageGranularity.width,
-																	mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height,
-																	mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth  % imageGranularity.depth  : imageGranularity.depth);
+			if (!formatDescription.hasChannelNdx(channelNdx))
+				continue;
+			deUint32					planeNdx					= formatDescription.channels[channelNdx].planeNdx;
+			vk::VkFormat				planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+			vk::PlanarFormatDescription	compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+			const tcu::UVec3			compatibleShaderGridSize	(shaderGridSize.x() / formatDescription.blockWidth, shaderGridSize.y() / formatDescription.blockHeight, shaderGridSize.z() / 1u);
+			tcu::ConstPixelBufferAccess	pixelBuffer					= vk::getChannelAccess(compatibleFormatDescription, compatibleShaderGridSize, planeRowPitches, (const void* const*)planePointers, channelNdx);
+			std::ostringstream str;
+			str << "image" << channelNdx;
+			m_context.getTestContext().getLog() << tcu::LogImage(str.str(), str.str(), pixelBuffer);;
+		}
 
-			for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
+		// Validate results
+		for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
+		{
+			if (!formatDescription.hasChannelNdx(channelNdx))
+				continue;
+
+			deUint32						planeNdx					= formatDescription.channels[channelNdx].planeNdx;
+			const VkImageAspectFlags		aspect						= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+			const deUint32					aspectIndex					= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
+
+			if (aspectIndex == NO_MATCH_FOUND)
+				TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+			VkSparseImageMemoryRequirements	aspectRequirements			= sparseMemoryRequirements[aspectIndex];
+
+			vk::VkFormat					planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+			vk::PlanarFormatDescription		compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+			const tcu::UVec3				compatibleShaderGridSize	( shaderGridSize.x() / formatDescription.blockWidth, shaderGridSize.y() / formatDescription.blockHeight, shaderGridSize.z() / 1u );
+			VkExtent3D						compatibleImageSize			{ imageCreateInfo.extent.width / formatDescription.blockWidth, imageCreateInfo.extent.height / formatDescription.blockHeight, imageCreateInfo.extent.depth / 1u };
+			VkExtent3D						compatibleImageGranularity	{ aspectRequirements.formatProperties.imageGranularity.width / formatDescription.blockWidth,
+																		  aspectRequirements.formatProperties.imageGranularity.height / formatDescription.blockHeight,
+																		  aspectRequirements.formatProperties.imageGranularity.depth / 1u };
+			tcu::ConstPixelBufferAccess		pixelBuffer					= vk::getChannelAccess(compatibleFormatDescription, compatibleShaderGridSize, planeRowPitches, (const void* const*)planePointers, channelNdx);
+			VkExtent3D						planeExtent					= getPlaneExtent(compatibleFormatDescription, compatibleImageSize, planeNdx, 0u);
+			tcu::IVec3						pixelDivider				= pixelBuffer.getDivider();
+			float							fixedPointError				= tcu::TexVerifierUtil::computeFixedPointError(formatDescription.channels[channelNdx].sizeBits);
+
+			if( aspectRequirements.imageMipTailFirstLod > 0u )
 			{
-				for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
-				for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
-				for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
+				const tcu::UVec3					numSparseBinds	= alignedDivide(planeExtent, compatibleImageGranularity);
+				const tcu::UVec3					lastBlockExtent	= tcu::UVec3(planeExtent.width  % compatibleImageGranularity.width  ? planeExtent.width  % compatibleImageGranularity.width  : compatibleImageGranularity.width,
+																				 planeExtent.height % compatibleImageGranularity.height ? planeExtent.height % compatibleImageGranularity.height : compatibleImageGranularity.height,
+																				 planeExtent.depth  % compatibleImageGranularity.depth  ? planeExtent.depth  % compatibleImageGranularity.depth  : compatibleImageGranularity.depth);
+
+				for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
 				{
-					VkExtent3D offset;
-					offset.width  = x*imageGranularity.width;
-					offset.height = y*imageGranularity.height;
-					offset.depth  = z*imageGranularity.depth + layerNdx*numSparseBinds.z()*imageGranularity.depth;
-
-					VkExtent3D extent;
-					extent.width  = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
-					extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
-					extent.depth  = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
-
-					const deUint32 linearIndex = x + y*numSparseBinds.x() + z*numSparseBinds.x()*numSparseBinds.y() + layerNdx*numSparseBinds.x()*numSparseBinds.y()*numSparseBinds.z();
-
-					if (linearIndex % 2u == 0u)
+					for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
+					for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
+					for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
 					{
-						for (deUint32 offsetZ = offset.depth;  offsetZ < offset.depth  + extent.depth;  ++offsetZ)
-						for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
-						for (deUint32 offsetX = offset.width;  offsetX < offset.width  + extent.width;  ++offsetX)
-						{
-							const tcu::UVec4 referenceValue = tcu::UVec4(offsetX % 127u, offsetY % 127u, offsetZ % 127u, 1u);
-							const tcu::UVec4 outputValue	= pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
+						VkExtent3D offset;
+						offset.width	= x * compatibleImageGranularity.width;
+						offset.height	= y * compatibleImageGranularity.height;
+						offset.depth	= z * compatibleImageGranularity.depth + layerNdx * numSparseBinds.z()*compatibleImageGranularity.depth;
 
-							if (deMemCmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format.order)) != 0)
-								return tcu::TestStatus::fail("Failed");
+						VkExtent3D extent;
+						extent.width	= (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : compatibleImageGranularity.width;
+						extent.height	= (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : compatibleImageGranularity.height;
+						extent.depth	= (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : compatibleImageGranularity.depth;
+
+						const deUint32 linearIndex = x + y * numSparseBinds.x() + z * numSparseBinds.x() * numSparseBinds.y() + layerNdx * numSparseBinds.x() * numSparseBinds.y() * numSparseBinds.z();
+
+						if (linearIndex % 2u == 0u)
+						{
+							for (deUint32 offsetZ = offset.depth; offsetZ < offset.depth + extent.depth; ++offsetZ)
+							for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
+							for (deUint32 offsetX = offset.width; offsetX < offset.width + extent.width; ++offsetX)
+							{
+								deUint32	iReferenceValue;
+								float		fReferenceValue;
+
+								switch (channelNdx)
+								{
+									case 0:
+										iReferenceValue = offsetX % 127u;
+										fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+										break;
+									case 1:
+										iReferenceValue = offsetY % 127u;
+										fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+										break;
+									case 2:
+										iReferenceValue = offsetZ % 127u;
+										fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+										break;
+									case 3:
+										iReferenceValue = 1u;
+										fReferenceValue = 1.f;
+										break;
+									default:	DE_FATAL("Unexpected channel index");	break;
+								}
+
+								float acceptableError = epsilon;
+
+								switch (formatDescription.channels[channelNdx].type)
+								{
+									case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+									case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+									{
+										const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (outputValue.x() != iReferenceValue)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+									case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+									{
+										acceptableError += fixedPointError;
+										const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (deAbs(outputValue.x() - fReferenceValue) > acceptableError)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+									{
+										const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (deAbs( outputValue.x() - fReferenceValue) > acceptableError)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									default:	DE_FATAL("Unexpected channel type");	break;
+								}
+							}
 						}
-					}
-					else if (physicalDeviceProperties.sparseProperties.residencyNonResidentStrict)
-					{
-						for (deUint32 offsetZ = offset.depth;  offsetZ < offset.depth  + extent.depth;  ++offsetZ)
-						for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
-						for (deUint32 offsetX = offset.width;  offsetX < offset.width  + extent.width;  ++offsetX)
+						else if (physicalDeviceProperties.sparseProperties.residencyNonResidentStrict)
 						{
-							const tcu::UVec4 referenceValue = tcu::UVec4(0u, 0u, 0u, 0u);
-							const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
+							for (deUint32 offsetZ = offset.depth; offsetZ < offset.depth + extent.depth; ++offsetZ)
+							for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
+							for (deUint32 offsetX = offset.width; offsetX < offset.width + extent.width; ++offsetX)
+							{
+								float acceptableError = epsilon;
 
-							if (deMemCmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format.order)) != 0)
-								return tcu::TestStatus::fail("Failed");
+								switch (formatDescription.channels[channelNdx].type)
+								{
+									case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+									case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+									{
+										const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (outputValue.x() != 0u)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+									case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+									{
+										acceptableError += fixedPointError;
+										const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (deAbs(outputValue.x()) > acceptableError)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+									{
+										const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+										if (deAbs(outputValue.x()) > acceptableError)
+											return tcu::TestStatus::fail("Failed");
+
+										break;
+									}
+									default:	DE_FATAL("Unexpected channel type");	break;
+								}
+							}
 						}
 					}
 				}
 			}
-		}
-		else
-		{
-			const VkExtent3D mipExtent = mipLevelExtents(imageCreateInfo.extent, 0u);
-
-			for (deUint32 offsetZ = 0u; offsetZ < mipExtent.depth * imageCreateInfo.arrayLayers; ++offsetZ)
-			for (deUint32 offsetY = 0u; offsetY < mipExtent.height; ++offsetY)
-			for (deUint32 offsetX = 0u; offsetX < mipExtent.width;  ++offsetX)
+			else
 			{
-				const tcu::UVec4 referenceValue = tcu::UVec4(offsetX % 127u, offsetY % 127u, offsetZ % 127u, 1u);
-				const tcu::UVec4 outputValue	= pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
+				for (deUint32 offsetZ = 0u; offsetZ < planeExtent.depth * imageCreateInfo.arrayLayers; ++offsetZ)
+				for (deUint32 offsetY = 0u; offsetY < planeExtent.height; ++offsetY)
+				for (deUint32 offsetX = 0u; offsetX < planeExtent.width; ++offsetX)
+				{
+					deUint32	iReferenceValue;
+					float		fReferenceValue;
+					switch (channelNdx)
+					{
+						case 0:
+							iReferenceValue = offsetX % 127u;
+							fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+							break;
+						case 1:
+							iReferenceValue = offsetY % 127u;
+							fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+							break;
+						case 2:
+							iReferenceValue = offsetZ % 127u;
+							fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+							break;
+						case 3:
+							iReferenceValue = 1u;
+							fReferenceValue = 1.f;
+							break;
+						default:	DE_FATAL("Unexpected channel index");	break;
+					}
+					float acceptableError = epsilon;
 
-				if (deMemCmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format.order)) != 0)
-					return tcu::TestStatus::fail("Failed");
+					switch (formatDescription.channels[channelNdx].type)
+					{
+						case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+						case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+						{
+							const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (outputValue.x() != iReferenceValue)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+						case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+						{
+							acceptableError += fixedPointError;
+							const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (deAbs(outputValue.x() - fReferenceValue) > acceptableError)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+						{
+							const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), offsetZ * pixelDivider.z());
+
+							if (deAbs( outputValue.x() - fReferenceValue) > acceptableError)
+								return tcu::TestStatus::fail("Failed");
+
+							break;
+						}
+						default:	DE_FATAL("Unexpected channel type");	break;
+					}
+				}
 			}
 		}
 	}
@@ -679,49 +997,35 @@
 
 tcu::TestCaseGroup* createImageSparseResidencyTestsCommon (tcu::TestContext& testCtx, de::MovePtr<tcu::TestCaseGroup> testGroup, const bool useDeviceGroup = false)
 {
-	static const deUint32 sizeCountPerImageType = 3u;
-
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSizes[sizeCountPerImageType];
+		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u,  1u),	tcu::UVec3(1024u, 128u, 1u),	tcu::UVec3(11u,  137u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u,  6u),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u,  1u),	tcu::UVec3(128u,  128u, 1u),	tcu::UVec3(137u, 137u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u,  6u),	tcu::UVec3(128u,  128u, 8u),	tcu::UVec3(137u, 137u, 3u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,			{ tcu::UVec3(512u, 256u, 16u),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
-	static const ImageParameters imageParametersArray[] =
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		{ IMAGE_TYPE_2D,		 { tcu::UVec3(512u, 256u, 1u),  tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u,  137u, 1u) } },
-		{ IMAGE_TYPE_2D_ARRAY,	 { tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } },
-		{ IMAGE_TYPE_CUBE,		 { tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u,  128u, 1u), tcu::UVec3(137u, 137u, 1u) } },
-		{ IMAGE_TYPE_CUBE_ARRAY, { tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u,  128u, 8u), tcu::UVec3(137u, 137u, 3u) } },
-		{ IMAGE_TYPE_3D,		 { tcu::UVec3(512u, 256u, 16u), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } }
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RG,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
-	};
-
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
-	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
+		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
 		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&		format = formats[formatNdx];
-			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+			const VkFormat					format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
-			for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
+			for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
 			{
-				const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
+				const tcu::UVec3 imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
+
+				// skip test for images with odd sizes for some YCbCr formats
+				if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+					continue;
+				if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+					continue;
 
 				std::ostringstream stream;
 				stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
@@ -738,13 +1042,13 @@
 
 tcu::TestCaseGroup* createImageSparseResidencyTests (tcu::TestContext& testCtx)
 {
-	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_sparse_residency", "Buffer Sparse Residency"));
+	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_sparse_residency", "Image Sparse Residency"));
 	return createImageSparseResidencyTestsCommon(testCtx, testGroup);
 }
 
 tcu::TestCaseGroup* createDeviceGroupImageSparseResidencyTests (tcu::TestContext& testCtx)
 {
-	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "device_group_image_sparse_residency", "Buffer Sparse Residency"));
+	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "device_group_image_sparse_residency", "Image Sparse Residency"));
 	return createImageSparseResidencyTestsCommon(testCtx, testGroup, true);
 }
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
index a7d65df..49b819b 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
@@ -57,37 +57,36 @@
 class MipmapSparseResidencyCase : public TestCase
 {
 public:
-					MipmapSparseResidencyCase	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const std::string&			description,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format,
-												 const bool					useDeviceGroups);
-
+	MipmapSparseResidencyCase		(tcu::TestContext&	testCtx,
+									 const std::string&	name,
+									 const std::string&	description,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format,
+									 const bool			useDeviceGroups);
 
 	TestInstance*	createInstance				(Context&					context) const;
 	virtual void	checkSupport				(Context&					context) const;
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-MipmapSparseResidencyCase::MipmapSparseResidencyCase (tcu::TestContext&			testCtx,
-													  const std::string&		name,
-													  const std::string&		description,
-													  const ImageType			imageType,
-													  const tcu::UVec3&			imageSize,
-													  const tcu::TextureFormat&	format,
-													  const bool				useDeviceGroups)
-	: TestCase				(testCtx, name, description)
-	, m_useDeviceGroups		(useDeviceGroups)
-	, m_imageType			(imageType)
-	, m_imageSize			(imageSize)
-	, m_format				(format)
+MipmapSparseResidencyCase::MipmapSparseResidencyCase	(tcu::TestContext&	testCtx,
+														 const std::string&	name,
+														 const std::string&	description,
+														 const ImageType	imageType,
+														 const tcu::UVec3&	imageSize,
+														 const VkFormat		format,
+														 const bool			useDeviceGroups)
+	: TestCase			(testCtx, name, description)
+	, m_useDeviceGroups	(useDeviceGroups)
+	, m_imageType		(imageType)
+	, m_imageSize		(imageSize)
+	, m_format			(format)
 {
 }
 
@@ -108,27 +107,27 @@
 class MipmapSparseResidencyInstance : public SparseResourcesBaseInstance
 {
 public:
-					MipmapSparseResidencyInstance	(Context&									 context,
-													 const ImageType							 imageType,
-													 const tcu::UVec3&							 imageSize,
-													 const tcu::TextureFormat&					 format,
-													 const bool									 useDeviceGroups);
+	MipmapSparseResidencyInstance	(Context&			context,
+									 const ImageType	imageType,
+									 const tcu::UVec3&	imageSize,
+									 const VkFormat		format,
+									 const bool			useDeviceGroups);
 
 
-	tcu::TestStatus	iterate							(void);
+	tcu::TestStatus	iterate			(void);
 
 private:
-	const bool					m_useDeviceGroups;
-	const ImageType				m_imageType;
-	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const bool			m_useDeviceGroups;
+	const ImageType		m_imageType;
+	const tcu::UVec3	m_imageSize;
+	const VkFormat		m_format;
 };
 
-MipmapSparseResidencyInstance::MipmapSparseResidencyInstance (Context&					context,
-															  const ImageType			imageType,
-															  const tcu::UVec3&			imageSize,
-															  const tcu::TextureFormat&	format,
-															  const bool				useDeviceGroups)
+MipmapSparseResidencyInstance::MipmapSparseResidencyInstance	(Context&			context,
+																 const ImageType	imageType,
+																 const tcu::UVec3&	imageSize,
+																 const VkFormat		format,
+																 const bool			useDeviceGroups)
 	: SparseResourcesBaseInstance	(context, useDeviceGroups)
 	, m_useDeviceGroups				(useDeviceGroups)
 	, m_imageType					(imageType)
@@ -153,9 +152,10 @@
 	VkImageCreateInfo			imageSparseInfo;
 	std::vector<DeviceMemorySp>	deviceMemUniquePtrVec;
 
-	const DeviceInterface&	deviceInterface	= getDeviceInterface();
-	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-	const Queue&			computeQueue	= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const DeviceInterface&			deviceInterface		= getDeviceInterface();
+	const Queue&					sparseQueue			= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+	const Queue&					computeQueue		= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
 
 	// Go through all physical devices
 	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
@@ -167,7 +167,7 @@
 		imageSparseInfo.pNext					= DE_NULL;
 		imageSparseInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 		imageSparseInfo.imageType				= mapImageType(m_imageType);
-		imageSparseInfo.format					= mapTextureFormat(m_format);
+		imageSparseInfo.format					= m_format;
 		imageSparseInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 		imageSparseInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
 		imageSparseInfo.samples					= VK_SAMPLE_COUNT_1_BIT;
@@ -184,28 +184,33 @@
 			imageSparseInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 		}
 
+		// Check if device supports sparse operations for image format
+		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
+			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
+
 		{
 			VkImageFormatProperties imageFormatProperties;
-			instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+			if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
 				imageSparseInfo.format,
 				imageSparseInfo.imageType,
 				imageSparseInfo.tiling,
 				imageSparseInfo.usage,
 				imageSparseInfo.flags,
-				&imageFormatProperties);
+				&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+			{
+				TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+			}
 
-			imageSparseInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageSparseInfo.extent);
+			imageSparseInfo.mipLevels = getMipmapCount(m_format, formatDescription, imageFormatProperties, imageSparseInfo.extent);
 		}
 
-		// Check if device supports sparse operations for image format
-		if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
-			TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
-
 		// Create sparse image
-		const Unique<VkImage> imageSparse(createImage(deviceInterface, getDevice(), &imageSparseInfo));
+		const Unique<VkImage>							imageSparse(createImage(deviceInterface, getDevice(), &imageSparseInfo));
 
 		// Create sparse image memory bind semaphore
-		const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
+		const Unique<VkSemaphore>						imageMemoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
+
+		std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements;
 
 		{
 			// Get sparse image general memory requirements
@@ -217,26 +222,6 @@
 
 			DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
 
-			// Get sparse image sparse memory requirements
-			const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
-
-			DE_ASSERT(sparseMemoryRequirements.size() != 0);
-
-			const deUint32 colorAspectIndex		= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
-			const deUint32 metadataAspectIndex	= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
-
-			if (colorAspectIndex == NO_MATCH_FOUND)
-				TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
-
-			const VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[colorAspectIndex];
-			const VkImageAspectFlags				aspectMask			= aspectRequirements.formatProperties.aspectMask;
-			const VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
-
-			DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
-
-			std::vector<VkSparseImageMemoryBind>	imageResidencyMemoryBinds;
-			std::vector<VkSparseMemoryBind>			imageMipTailMemoryBinds;
-
 			const deUint32							memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
 			if (memoryType == NO_MATCH_FOUND)
@@ -255,61 +240,85 @@
 				}
 			}
 
-			// Bind memory for each layer
-			for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
+			// Get sparse image sparse memory requirements
+			sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
+			DE_ASSERT(sparseMemoryRequirements.size() != 0);
+
+			const deUint32 metadataAspectIndex	= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
+
+			std::vector<VkSparseImageMemoryBind>	imageResidencyMemoryBinds;
+			std::vector<VkSparseMemoryBind>			imageMipTailMemoryBinds;
+
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 			{
-				for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+				const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+				const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
+
+				if (aspectIndex == NO_MATCH_FOUND)
+					TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+				VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+
+				DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
+
+				VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
+
+				// Bind memory for each layer
+				for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
 				{
-					const VkExtent3D			mipExtent			= mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
-					const tcu::UVec3			sparseBlocks		= alignedDivide(mipExtent, imageGranularity);
-					const deUint32				numSparseBlocks		= sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
-					const VkImageSubresource	subresource			= { aspectMask, mipLevelNdx, layerNdx };
+					for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+					{
+						const VkExtent3D			mipExtent			= getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipLevelNdx);
+						const tcu::UVec3			sparseBlocks		= alignedDivide(mipExtent, imageGranularity);
+						const deUint32				numSparseBlocks		= sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
+						const VkImageSubresource	subresource			= { aspect, mipLevelNdx, layerNdx };
 
-					const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
-						imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
+						const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
+							imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
 
-					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
-					imageResidencyMemoryBinds.push_back(imageMemoryBind);
-				}
+						imageResidencyMemoryBinds.push_back(imageMemoryBind);
+					}
 
-				if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
-				{
-					const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
-
-					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-					imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
-				}
-
-				// Metadata
-				if (metadataAspectIndex != NO_MATCH_FOUND)
-				{
-					const VkSparseImageMemoryRequirements metadataAspectRequirements = sparseMemoryRequirements[metadataAspectIndex];
-
-					if (!(metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT))
+					if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
 					{
 						const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-							metadataAspectRequirements.imageMipTailSize, memoryType,
-							metadataAspectRequirements.imageMipTailOffset + layerNdx * metadataAspectRequirements.imageMipTailStride,
-							VK_SPARSE_MEMORY_BIND_METADATA_BIT);
+							aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
 
 						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
 						imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
 					}
+
+					// Metadata
+					if (metadataAspectIndex != NO_MATCH_FOUND)
+					{
+						const VkSparseImageMemoryRequirements metadataAspectRequirements = sparseMemoryRequirements[metadataAspectIndex];
+
+						if (!(metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT))
+						{
+							const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+								metadataAspectRequirements.imageMipTailSize, memoryType,
+								metadataAspectRequirements.imageMipTailOffset + layerNdx * metadataAspectRequirements.imageMipTailStride,
+								VK_SPARSE_MEMORY_BIND_METADATA_BIT);
+
+							deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+							imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+						}
+					}
 				}
-			}
 
-			if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
-			{
-				const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
+				if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
+				{
+					const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
 
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
-				imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+					imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+				}
 			}
 
 			// Metadata
@@ -360,7 +369,7 @@
 			{
 				imageResidencyBindInfo.image		= *imageSparse;
 				imageResidencyBindInfo.bindCount	= static_cast<deUint32>(imageResidencyMemoryBinds.size());
-				imageResidencyBindInfo.pBinds		= &imageResidencyMemoryBinds[0];
+				imageResidencyBindInfo.pBinds		= imageResidencyMemoryBinds.data();
 
 				bindSparseInfo.imageBindCount		= 1u;
 				bindSparseInfo.pImageBinds			= &imageResidencyBindInfo;
@@ -370,7 +379,7 @@
 			{
 				imageMipTailBindInfo.image			= *imageSparse;
 				imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailMemoryBinds.size());
-				imageMipTailBindInfo.pBinds			= &imageMipTailMemoryBinds[0];
+				imageMipTailBindInfo.pBinds			= imageMipTailMemoryBinds.data();
 
 				bindSparseInfo.imageOpaqueBindCount	= 1u;
 				bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
@@ -380,25 +389,43 @@
 			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
 		}
 
-		// Create command buffer for compute and transfer oparations
-		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
-		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+		deUint32 imageSizeInBytes = 0;
 
-		std::vector <VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				imageSizeInBytes += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 
+		std::vector <VkBufferImageCopy>	bufferImageCopy(formatDescription.numPlanes*imageSparseInfo.mipLevels);
 		{
 			deUint32 bufferOffset = 0;
-			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
+
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 			{
-				bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, static_cast<VkDeviceSize>(bufferOffset));
-				bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+				{
+					bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx] =
+					{
+						bufferOffset,																		//	VkDeviceSize				bufferOffset;
+						0u,																					//	deUint32					bufferRowLength;
+						0u,																					//	deUint32					bufferImageHeight;
+						makeImageSubresourceLayers(aspect, mipmapNdx, 0u, imageSparseInfo.arrayLayers),		//	VkImageSubresourceLayers	imageSubresource;
+						makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
+						vk::getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx)	//	VkExtent3D					imageExtent;
+					};
+					bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+				}
 			}
 		}
 
+		// Create command buffer for compute and transfer operations
+		const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
+		const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
 		// Start recording commands
 		beginCommandBuffer(deviceInterface, *commandBuffer);
 
-		const deUint32					imageSizeInBytes		= getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 		const VkBufferCreateInfo		inputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 		const Unique<VkBuffer>			inputBuffer				(createBuffer(deviceInterface, getDevice(), &inputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	inputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *inputBuffer, MemoryRequirement::HostVisible));
@@ -412,11 +439,10 @@
 			referenceData[valueNdx] = static_cast<deUint8>((valueNdx % imageMemoryRequirements.alignment) + 1u);
 		}
 
-		deMemcpy(inputBufferAlloc->getHostPtr(), &referenceData[0], imageSizeInBytes);
-
-		flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
-
 		{
+			deMemcpy(inputBufferAlloc->getHostPtr(), referenceData.data(), imageSizeInBytes);
+			flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
+
 			const VkBufferMemoryBarrier inputBufferBarrier = makeBufferMemoryBarrier
 			(
 				VK_ACCESS_HOST_WRITE_BIT,
@@ -430,42 +456,55 @@
 		}
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferDstBarrier = makeImageMemoryBarrier
-			(
-				0u,
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_IMAGE_LAYOUT_UNDEFINED,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				*imageSparse,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
-				sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
-				);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferDstBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferDstBarriers.emplace_back ( makeImageMemoryBarrier
+				(
+					0u,
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_IMAGE_LAYOUT_UNDEFINED,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					*imageSparse,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
+					sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex ? computeQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
+				));
+			}
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferDstBarriers.size()), imageSparseTransferDstBarriers.data());
 		}
 
 		deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
 
 		{
-			const VkImageMemoryBarrier imageSparseTransferSrcBarrier = makeImageMemoryBarrier
-			(
-				VK_ACCESS_TRANSFER_WRITE_BIT,
-				VK_ACCESS_TRANSFER_READ_BIT,
-				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-				*imageSparse,
-				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
-			);
+			std::vector<VkImageMemoryBarrier> imageSparseTransferSrcBarriers;
 
-			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferSrcBarrier);
+			for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			{
+				const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+				imageSparseTransferSrcBarriers.emplace_back(makeImageMemoryBarrier
+				(
+					VK_ACCESS_TRANSFER_WRITE_BIT,
+					VK_ACCESS_TRANSFER_READ_BIT,
+					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+					*imageSparse,
+					makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers)
+				));
+			}
+
+			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferSrcBarriers.size()), imageSparseTransferSrcBarriers.data());
 		}
 
 		const VkBufferCreateInfo		outputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
 		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
 		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
 
-		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
 
 		{
 			const VkBufferMemoryBarrier outputBufferBarrier = makeBufferMemoryBarrier
@@ -497,13 +536,16 @@
 		// Wait for sparse queue to become idle
 		deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
-			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[mipmapNdx].bufferOffset);
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx);
+				const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx].bufferOffset);
 
-			if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
-				return tcu::TestStatus::fail("Failed");
+				if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+					return tcu::TestStatus::fail("Failed");
+			}
 		}
 	}
 	return tcu::TestStatus::pass("Passed");
@@ -518,46 +560,35 @@
 
 tcu::TestCaseGroup* createMipmapSparseResidencyTestsCommon (tcu::TestContext& testCtx, de::MovePtr<tcu::TestCaseGroup> testGroup, const bool useDeviceGroup = false)
 {
-	static const deUint32 sizeCountPerImageType = 3u;
-
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSizes[sizeCountPerImageType];
+		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(1024u, 128u, 1u),	tcu::UVec3(11u,  137u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u,  128u, 1u),	tcu::UVec3(137u, 137u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u,  128u, 8u),	tcu::UVec3(137u, 137u, 3u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,			{ tcu::UVec3(256u, 256u, 16u),	tcu::UVec3(1024u, 128u, 8u),	tcu::UVec3(11u,  137u, 3u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
-	static const ImageParameters imageParametersArray[] =
+	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 	{
-		{ IMAGE_TYPE_2D,		 { tcu::UVec3(512u, 256u, 1u),  tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u,  137u, 1u) } },
-		{ IMAGE_TYPE_2D_ARRAY,	 { tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } },
-		{ IMAGE_TYPE_CUBE,		 { tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u,  128u, 1u), tcu::UVec3(137u, 137u, 1u) } },
-		{ IMAGE_TYPE_CUBE_ARRAY, { tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u,  128u, 8u), tcu::UVec3(137u, 137u, 3u) } },
-		{ IMAGE_TYPE_3D,		 { tcu::UVec3(256u, 256u, 16u), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u,  137u, 3u) } }
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
-	};
-
-	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
-	{
-		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
+		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
 		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
 
-		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 		{
-			const tcu::TextureFormat&		format = formats[formatNdx];
-			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+			VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
-			for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
+			for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
 			{
-				const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
+				const tcu::UVec3 imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
+
+				// skip test for images with odd sizes for some YCbCr formats
+				if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+					continue;
+				if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+					continue;
 
 				std::ostringstream stream;
 				stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesQueueBindSparseTests.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesQueueBindSparseTests.cpp
index 1604e64..9021ac5 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesQueueBindSparseTests.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesQueueBindSparseTests.cpp
@@ -73,24 +73,24 @@
 	InfoUnion				info;
 };
 
-QueueSubmission makeSubmissionRegular (const Queue*					queue,
-									   const deUint32				numWaitSemaphores,
-									   const VkSemaphore*			pWaitSemaphore,
-									   const VkPipelineStageFlags*	pWaitDstStageMask,
-									   const deUint32				numSignalSemaphores,
-									   const VkSemaphore*			pSignalSemaphore)
+QueueSubmission makeSubmissionRegular	(const Queue*					queue,
+										 const deUint32					numWaitSemaphores,
+										 const VkSemaphore*				pWaitSemaphore,
+										 const VkPipelineStageFlags*	pWaitDstStageMask,
+										 const deUint32					numSignalSemaphores,
+										 const VkSemaphore*				pSignalSemaphore)
 {
 	const VkSubmitInfo submitInfo =
 	{
-		VK_STRUCTURE_TYPE_SUBMIT_INFO,				// VkStructureType                sType;
-		DE_NULL,									// const void*                    pNext;
-		numWaitSemaphores,							// uint32_t                       waitSemaphoreCount;
-		pWaitSemaphore,								// const VkSemaphore*             pWaitSemaphores;
-		pWaitDstStageMask,							// const VkPipelineStageFlags*    pWaitDstStageMask;
-		0u,											// uint32_t                       commandBufferCount;
-		DE_NULL,									// const VkCommandBuffer*         pCommandBuffers;
-		numSignalSemaphores,						// uint32_t                       signalSemaphoreCount;
-		pSignalSemaphore,							// const VkSemaphore*             pSignalSemaphores;
+		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
+		DE_NULL,						// const void*					pNext;
+		numWaitSemaphores,				// uint32_t						waitSemaphoreCount;
+		pWaitSemaphore,					// const VkSemaphore*			pWaitSemaphores;
+		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
+		0u,								// uint32_t						commandBufferCount;
+		DE_NULL,						// const VkCommandBuffer*		pCommandBuffers;
+		numSignalSemaphores,			// uint32_t						signalSemaphoreCount;
+		pSignalSemaphore,				// const VkSemaphore*			pSignalSemaphores;
 	};
 
 	QueueSubmission submission;
@@ -101,26 +101,26 @@
 	return submission;
 }
 
-QueueSubmission makeSubmissionSparse (const Queue*			queue,
-									  const deUint32		numWaitSemaphores,
-									  const VkSemaphore*	pWaitSemaphore,
-									  const deUint32		numSignalSemaphores,
-									  const VkSemaphore*	pSignalSemaphore)
+QueueSubmission makeSubmissionSparse	(const Queue*		queue,
+										 const deUint32		numWaitSemaphores,
+										 const VkSemaphore*	pWaitSemaphore,
+										 const deUint32		numSignalSemaphores,
+										 const VkSemaphore*	pSignalSemaphore)
 {
 	const VkBindSparseInfo bindInfo =
 	{
-		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			// VkStructureType                             sType;
-		DE_NULL,									// const void*                                 pNext;
-		numWaitSemaphores,							// uint32_t                                    waitSemaphoreCount;
-		pWaitSemaphore,								// const VkSemaphore*                          pWaitSemaphores;
-		0u,											// uint32_t                                    bufferBindCount;
-		DE_NULL,									// const VkSparseBufferMemoryBindInfo*         pBufferBinds;
-		0u,											// uint32_t                                    imageOpaqueBindCount;
-		DE_NULL,									// const VkSparseImageOpaqueMemoryBindInfo*    pImageOpaqueBinds;
-		0u,											// uint32_t                                    imageBindCount;
-		DE_NULL,									// const VkSparseImageMemoryBindInfo*          pImageBinds;
-		numSignalSemaphores,						// uint32_t                                    signalSemaphoreCount;
-		pSignalSemaphore,							// const VkSemaphore*                          pSignalSemaphores;
+		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			// VkStructureType							sType;
+		DE_NULL,									// const void*								pNext;
+		numWaitSemaphores,							// uint32_t									waitSemaphoreCount;
+		pWaitSemaphore,								// const VkSemaphore*						pWaitSemaphores;
+		0u,											// uint32_t									bufferBindCount;
+		DE_NULL,									// const VkSparseBufferMemoryBindInfo*		pBufferBinds;
+		0u,											// uint32_t									imageOpaqueBindCount;
+		DE_NULL,									// const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
+		0u,											// uint32_t									imageBindCount;
+		DE_NULL,									// const VkSparseImageMemoryBindInfo*		pImageBinds;
+		numSignalSemaphores,						// uint32_t									signalSemaphoreCount;
+		pSignalSemaphore,							// const VkSemaphore*						pSignalSemaphores;
 	};
 
 	QueueSubmission submission;
@@ -154,7 +154,7 @@
 
 	tcu::TestStatus iterate (void)
 	{
-		const Queue*				sparseQueue		= DE_NULL;
+		const Queue*				sparseQueue	= DE_NULL;
 		std::vector<const Queue*>	otherQueues;
 
 		// Determine required queues and create a device that supports them
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsics.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsics.cpp
index a4c528e..079464e 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsics.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsics.cpp
@@ -35,31 +35,13 @@
 {
 	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "shader_intrinsics", "Sparse Resources Shader Intrinsics"));
 
-	static const deUint32 sizeCountPerImageType = 4u;
-
-	struct ImageParameters
+	const std::vector<TestImageParameters> imageParameters =
 	{
-		ImageType	imageType;
-		tcu::UVec3	imageSizes[sizeCountPerImageType];
-	};
-
-	static const ImageParameters imageParametersArray[] =
-	{
-		{ IMAGE_TYPE_2D,		{ tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u), tcu::UVec3(503u, 137u, 1u), tcu::UVec3(11u, 37u, 1u) } },
-		{ IMAGE_TYPE_2D_ARRAY,	{ tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) } },
-		{ IMAGE_TYPE_CUBE,		{ tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(137u, 137u, 1u),	tcu::UVec3(11u, 11u, 1u) } },
-		{ IMAGE_TYPE_CUBE_ARRAY,{ tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(137u, 137u, 3u),	tcu::UVec3(11u, 11u, 3u) } },
-		{ IMAGE_TYPE_3D,		{ tcu::UVec3(256u, 256u, 16u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) } }
-	};
-
-	static const tcu::TextureFormat formats[] =
-	{
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
-		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
+		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u), tcu::UVec3(503u, 137u, 1u), tcu::UVec3(11u, 37u, 1u) },	getTestFormats(IMAGE_TYPE_2D) },
+		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) },	getTestFormats(IMAGE_TYPE_2D_ARRAY) },
+		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u, 1u),	tcu::UVec3(128u, 128u, 1u),	tcu::UVec3(137u, 137u, 1u),	tcu::UVec3(11u, 11u, 1u) },	getTestFormats(IMAGE_TYPE_CUBE) },
+		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u, 6u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(137u, 137u, 3u),	tcu::UVec3(11u, 11u, 3u) },	getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
+		{ IMAGE_TYPE_3D,			{ tcu::UVec3(256u, 256u, 16u),	tcu::UVec3(128u, 128u, 8u),	tcu::UVec3(503u, 137u, 3u),	tcu::UVec3(11u, 37u, 3u) },	getTestFormats(IMAGE_TYPE_3D) }
 	};
 
 	static const std::string functions[SPARSE_SPIRV_FUNCTION_TYPE_LAST] =
@@ -75,57 +57,64 @@
 	{
 		const SpirVFunction function = static_cast<SpirVFunction>(functionNdx);
 
-		for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
+		for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
 		{
-			const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
-			de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, (getImageTypeName(imageType) + functions[functionNdx]).c_str(), ""));
+			const ImageType					imageType		= imageParameters[imageTypeNdx].imageType;
+			de::MovePtr<tcu::TestCaseGroup> imageTypeGroup	(new tcu::TestCaseGroup(testCtx, (getImageTypeName(imageType) + functions[functionNdx]).c_str(), ""));
 
-			for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+			for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
 			{
-				const tcu::TextureFormat&		format = formats[formatNdx];
-				de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
+				VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
+				tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+				de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));
 
-				for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
+				for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
 				{
-					const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
+					const tcu::UVec3 imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];
+
+					// skip test for images with odd sizes for some YCbCr formats
+					if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+						continue;
+					if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+						continue;
 
 					std::ostringstream stream;
 					stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
 
 					switch (function)
 					{
-					case SPARSE_FETCH:
-						if ((imageType == IMAGE_TYPE_CUBE) || (imageType == IMAGE_TYPE_CUBE_ARRAY)) continue;
-						break;
-					case SPARSE_SAMPLE_EXPLICIT_LOD:
-					case SPARSE_SAMPLE_IMPLICIT_LOD:
-					case SPARSE_GATHER:
-						if ((imageType == IMAGE_TYPE_CUBE) || (imageType == IMAGE_TYPE_CUBE_ARRAY) || (imageType == IMAGE_TYPE_3D)) continue;
-						break;
-					default:
-						break;
+						case SPARSE_FETCH:
+							if ((imageType == IMAGE_TYPE_CUBE) || (imageType == IMAGE_TYPE_CUBE_ARRAY)) continue;
+							break;
+						case SPARSE_SAMPLE_EXPLICIT_LOD:
+						case SPARSE_SAMPLE_IMPLICIT_LOD:
+						case SPARSE_GATHER:
+							if ((imageType == IMAGE_TYPE_CUBE) || (imageType == IMAGE_TYPE_CUBE_ARRAY) || (imageType == IMAGE_TYPE_3D)) continue;
+							break;
+						default:
+							break;
 					}
 
 					switch (function)
 					{
-					case SPARSE_FETCH:
-						formatGroup->addChild(new SparseCaseOpImageSparseFetch(testCtx, stream.str(), function, imageType, imageSize, format));
-						break;
-					case SPARSE_READ:
-						formatGroup->addChild(new SparseCaseOpImageSparseRead(testCtx, stream.str(), function, imageType, imageSize, format));
-						break;
-					case SPARSE_SAMPLE_EXPLICIT_LOD:
-						formatGroup->addChild(new SparseCaseOpImageSparseSampleExplicitLod(testCtx, stream.str(), function, imageType, imageSize, format));
-						break;
-					case SPARSE_SAMPLE_IMPLICIT_LOD:
-						formatGroup->addChild(new SparseCaseOpImageSparseSampleImplicitLod(testCtx, stream.str(), function, imageType, imageSize, format));
-						break;
-					case SPARSE_GATHER:
-						formatGroup->addChild(new SparseCaseOpImageSparseGather(testCtx, stream.str(), function, imageType, imageSize, format));
-						break;
-					default:
-						DE_ASSERT(0);
-						break;
+						case SPARSE_FETCH:
+							formatGroup->addChild(new SparseCaseOpImageSparseFetch(testCtx, stream.str(), function, imageType, imageSize, format));
+							break;
+						case SPARSE_READ:
+							formatGroup->addChild(new SparseCaseOpImageSparseRead(testCtx, stream.str(), function, imageType, imageSize, format));
+							break;
+						case SPARSE_SAMPLE_EXPLICIT_LOD:
+							formatGroup->addChild(new SparseCaseOpImageSparseSampleExplicitLod(testCtx, stream.str(), function, imageType, imageSize, format));
+							break;
+						case SPARSE_SAMPLE_IMPLICIT_LOD:
+							formatGroup->addChild(new SparseCaseOpImageSparseSampleImplicitLod(testCtx, stream.str(), function, imageType, imageSize, format));
+							break;
+						case SPARSE_GATHER:
+							formatGroup->addChild(new SparseCaseOpImageSparseGather(testCtx, stream.str(), function, imageType, imageSize, format));
+							break;
+						default:
+							DE_FATAL("Unexpected function type");
+							break;
 					}
 				}
 				imageTypeGroup->addChild(formatGroup.release());
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp
index 6768b1a..9530ea5 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp
@@ -40,8 +40,30 @@
 			return "OpTypeInt 32 0";
 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
 			return "OpTypeInt 32 1";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "OpTypeFloat 32";
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected channel type");
+			return "";
+	}
+}
+
+std::string getOpTypeImageComponent (const vk::PlanarFormatDescription& description)
+{
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return "OpTypeInt 32 0";
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return "OpTypeInt 32 1";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "OpTypeFloat 32";
+		default:
+			DE_FATAL("Unexpected channel type");
 			return "";
 	}
 }
@@ -54,8 +76,30 @@
 			return "%type_uint";
 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
 			return "%type_int";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "%type_float";
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected channel type");
+			return "";
+	}
+}
+
+std::string getImageComponentTypeName (const vk::PlanarFormatDescription& description)
+{
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return "%type_uint";
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return "%type_int";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "%type_float";
+		default:
+			DE_FATAL("Unexpected channel type");
 			return "";
 	}
 }
@@ -68,8 +112,30 @@
 			return "%type_uvec4";
 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
 			return "%type_ivec4";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "%type_vec4";
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected channel type");
+			return "";
+	}
+}
+
+std::string getImageComponentVec4TypeName (const vk::PlanarFormatDescription& description)
+{
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return "%type_uvec4";
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return "%type_ivec4";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "%type_vec4";
+		default:
+			DE_FATAL("Unexpected channel type");
 			return "";
 	}
 }
@@ -107,7 +173,7 @@
 			src << "Cube 0 1 0 ";
 		break;
 		default :
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected image type");
 		break;
 	};
 
@@ -131,7 +197,7 @@
 			src << "Rgba";
 		break;
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected channel order");
 		break;
 	}
 
@@ -155,14 +221,152 @@
 		case tcu::TextureFormat::UNSIGNED_INT32:
 			src << "32ui";
 		break;
+		case tcu::TextureFormat::SNORM_INT8:
+			src << "8Snorm";
+		break;
+		case tcu::TextureFormat::SNORM_INT16:
+			src << "16Snorm";
+		break;
+		case tcu::TextureFormat::SNORM_INT32:
+			src << "32Snorm";
+		break;
+		case tcu::TextureFormat::UNORM_INT8:
+			src << "8";
+		break;
+		case tcu::TextureFormat::UNORM_INT16:
+			src << "16";
+		break;
+		case tcu::TextureFormat::UNORM_INT32:
+			src << "32";
+		break;
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected channel type");
 		break;
 	};
 
 	return src.str();
 }
 
+std::string getOpTypeImageSparse (const ImageType		imageType,
+								  const VkFormat		format,
+								  const std::string&	componentType,
+								  const bool			requiresSampler)
+{
+	std::ostringstream	src;
+
+	src << "OpTypeImage " << componentType << " ";
+
+	switch (imageType)
+	{
+		case IMAGE_TYPE_1D :
+			src << "1D 0 0 0 ";
+		break;
+		case IMAGE_TYPE_1D_ARRAY :
+			src << "1D 0 1 0 ";
+		break;
+		case IMAGE_TYPE_2D :
+			src << "2D 0 0 0 ";
+		break;
+		case IMAGE_TYPE_2D_ARRAY :
+			src << "2D 0 1 0 ";
+		break;
+		case IMAGE_TYPE_3D :
+			src << "3D 0 0 0 ";
+		break;
+		case IMAGE_TYPE_CUBE :
+			src << "Cube 0 0 0 ";
+		break;
+		case IMAGE_TYPE_CUBE_ARRAY :
+			src << "Cube 0 1 0 ";
+		break;
+		default :
+			DE_FATAL("Unexpected image type");
+		break;
+	};
+
+	if (requiresSampler)
+		src << "1 ";
+	else
+		src << "2 ";
+
+	switch (format)
+	{
+		case VK_FORMAT_R8_SINT:										src <<	"R8i";			break;
+		case VK_FORMAT_R16_SINT:									src <<	"R16i";			break;
+		case VK_FORMAT_R32_SINT:									src <<	"R32i";			break;
+		case VK_FORMAT_R8_UINT:										src <<	"R8ui";			break;
+		case VK_FORMAT_R16_UINT:									src <<	"R16ui";		break;
+		case VK_FORMAT_R32_UINT:									src <<	"R32ui";		break;
+		case VK_FORMAT_R8_SNORM:									src <<	"R8Snorm";		break;
+		case VK_FORMAT_R16_SNORM:									src <<	"R16Snorm";		break;
+		case VK_FORMAT_R8_UNORM:									src <<	"R8";			break;
+		case VK_FORMAT_R16_UNORM:									src <<	"R16";			break;
+
+		case VK_FORMAT_R8G8_SINT:									src <<	"Rg8i";			break;
+		case VK_FORMAT_R16G16_SINT:									src <<	"Rg16i";		break;
+		case VK_FORMAT_R32G32_SINT:									src <<	"Rg32i";		break;
+		case VK_FORMAT_R8G8_UINT:									src <<	"Rg8ui";		break;
+		case VK_FORMAT_R16G16_UINT:									src <<	"Rg16ui";		break;
+		case VK_FORMAT_R32G32_UINT:									src <<	"Rg32ui";		break;
+		case VK_FORMAT_R8G8_SNORM:									src <<	"Rg8Snorm";		break;
+		case VK_FORMAT_R16G16_SNORM:								src <<	"Rg16Snorm";	break;
+		case VK_FORMAT_R8G8_UNORM:									src <<	"Rg8";			break;
+		case VK_FORMAT_R16G16_UNORM:								src <<	"Rg16";			break;
+
+		case VK_FORMAT_R8G8B8A8_SINT:								src <<	"Rgba8i";		break;
+		case VK_FORMAT_R16G16B16A16_SINT:							src <<	"Rgba16i";		break;
+		case VK_FORMAT_R32G32B32A32_SINT:							src <<	"Rgba32i";		break;
+		case VK_FORMAT_R8G8B8A8_UINT:								src <<	"Rgba8ui";		break;
+		case VK_FORMAT_R16G16B16A16_UINT:							src <<	"Rgba16ui";		break;
+		case VK_FORMAT_R32G32B32A32_UINT:							src <<	"Rgba32ui";		break;
+		case VK_FORMAT_R8G8B8A8_SNORM:								src <<	"Rgba8Snorm";	break;
+		case VK_FORMAT_R16G16B16A16_SNORM:							src <<	"Rgba16Snorm";	break;
+		case VK_FORMAT_R8G8B8A8_UNORM:								src <<	"Rgba8";		break;
+		case VK_FORMAT_R16G16B16A16_UNORM:							src <<	"Rgba16";		break;
+
+		case VK_FORMAT_G8B8G8R8_422_UNORM:							src <<	"Rgba8";		break;
+		case VK_FORMAT_B8G8R8G8_422_UNORM:							src <<	"Rgba8";		break;
+		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:					src <<	"Rgba8";		break;
+		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:					src <<	"Rgba8";		break;
+		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:					src <<	"Rgba8";		break;
+		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:					src <<	"Rgba8";		break;
+		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:					src <<	"Rgba8";		break;
+		case VK_FORMAT_R10X6_UNORM_PACK16:							src <<	"R16";			break;
+		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:					src <<	"Rg16";			break;
+		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:			src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:		src <<	"Rgba16";		break;
+		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:		src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_R12X4_UNORM_PACK16:							src <<	"R16";			break;
+		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:					src <<	"Rg16";			break;
+		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:			src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:		src <<	"Rgba16";		break;
+		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:		src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:	src <<	"Rgba16";		break;
+		case VK_FORMAT_G16B16G16R16_422_UNORM:						src <<	"Rgba16";		break;
+		case VK_FORMAT_B16G16R16G16_422_UNORM:						src <<	"Rgba16";		break;
+		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:				src <<	"Rgba16";		break;
+		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:					src <<	"Rgba16";		break;
+		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:				src <<	"Rgba16";		break;
+		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:					src <<	"Rgba16";		break;
+		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:				src <<	"Rgba16";		break;
+
+		default:
+			DE_FATAL("Unexpected texture format");
+			break;
+	}
+	return src.str();
+}
+
+
 std::string getOpTypeImageResidency (const ImageType imageType)
 {
 	std::ostringstream	src;
@@ -193,7 +397,7 @@
 			src << "Cube 0 1 0 2 R32ui";
 		break;
 		default :
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected image type");
 		break;
 	};
 
@@ -207,15 +411,15 @@
 	VkImageCreateInfo					imageSparseInfo;
 	VkImageCreateInfo					imageTexelsInfo;
 	VkImageCreateInfo					imageResidencyInfo;
-	VkSparseImageMemoryRequirements		aspectRequirements;
 	std::vector <deUint32>				residencyReferenceData;
 	std::vector<DeviceMemorySp>			deviceMemUniquePtrVec;
+	const PlanarFormatDescription		formatDescription		= getPlanarFormatDescription(m_format);
 
 	imageSparseInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
 	imageSparseInfo.pNext					= DE_NULL;
 	imageSparseInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
 	imageSparseInfo.imageType				= mapImageType(m_imageType);
-	imageSparseInfo.format					= mapTextureFormat(m_format);
+	imageSparseInfo.format					= m_format;
 	imageSparseInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
 	imageSparseInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
 	imageSparseInfo.samples					= VK_SAMPLE_COUNT_1_BIT;
@@ -231,24 +435,27 @@
 		imageSparseInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 	}
 
+	// Check if device supports sparse operations for image format
+	if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
+		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
+
 	{
 		// Assign maximum allowed mipmap levels to image
 		VkImageFormatProperties imageFormatProperties;
-		instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
+		if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
 			imageSparseInfo.format,
 			imageSparseInfo.imageType,
 			imageSparseInfo.tiling,
 			imageSparseInfo.usage,
 			imageSparseInfo.flags,
-			&imageFormatProperties);
+			&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
+		{
+			TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
+		}
 
-		imageSparseInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageSparseInfo.extent);
+		imageSparseInfo.mipLevels = getMipmapCount(m_format, formatDescription, imageFormatProperties, imageSparseInfo.extent);
 	}
 
-	// Check if device supports sparse operations for image format
-	if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageSparseInfo))
-		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
-
 	{
 		// Create logical device supporting both sparse and compute/graphics queues
 		QueueRequirementsVec queueRequirements;
@@ -258,11 +465,10 @@
 		createDeviceSupportingQueues(queueRequirements);
 	}
 
-	const DeviceInterface&	deviceInterface	= getDeviceInterface();
-
 	// Create queues supporting sparse binding operations and compute/graphics operations
-	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-	const Queue&			extractQueue	= getQueue(getQueueFlags(), 0);
+	const DeviceInterface&			deviceInterface		= getDeviceInterface();
+	const Queue&					sparseQueue			= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+	const Queue&					extractQueue		= getQueue(getQueueFlags(), 0);
 
 	// Create sparse image
 	const Unique<VkImage> imageSparse(createImage(deviceInterface, getDevice(), &imageSparseInfo));
@@ -270,14 +476,25 @@
 	// Create sparse image memory bind semaphore
 	const Unique<VkSemaphore> memoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
 
-	const deUint32			  imageSparseSizeInBytes		= getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
-	const deUint32			  imageSizeInPixels				= getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels) / tcu::getPixelSize(m_format);
+	std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements;
+
+	deUint32	imageSparseSizeInBytes	= 0;
+	deUint32	imageSizeInPixels		= 0;
+
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+	{
+		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+		{
+			imageSparseSizeInBytes	+= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+			imageSizeInPixels		+= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx) / formatDescription.planes[planeNdx].elementSizeBytes;
+		}
+	}
 
 	residencyReferenceData.assign(imageSizeInPixels, MEMORY_BLOCK_NOT_BOUND_VALUE);
 
 	{
 		// Get sparse image general memory requirements
-		const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
+		const VkMemoryRequirements				imageMemoryRequirements	= getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
 		// Check if required image memory size does not exceed device limits
 		if (imageMemoryRequirements.size > getPhysicalDeviceProperties(instance, physicalDevice).limits.sparseAddressSpaceSize)
@@ -285,94 +502,97 @@
 
 		DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
 
-		// Get sparse image sparse memory requirements
-		const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
-
-		DE_ASSERT(sparseMemoryRequirements.size() != 0);
-
-		const deUint32 colorAspectIndex		= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
-		const deUint32 metadataAspectIndex	= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
-
-		if (colorAspectIndex == NO_MATCH_FOUND)
-			TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
-
-		aspectRequirements = sparseMemoryRequirements[colorAspectIndex];
-
-		DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
-
-		const VkImageAspectFlags aspectMask			= aspectRequirements.formatProperties.aspectMask;
-		const VkExtent3D		 imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
-		const deUint32			 memoryType			= findMatchingMemoryType(instance, physicalDevice, imageMemoryRequirements, MemoryRequirement::Any);
+		const deUint32							memoryType				= findMatchingMemoryType(instance, physicalDevice, imageMemoryRequirements, MemoryRequirement::Any);
 
 		if (memoryType == NO_MATCH_FOUND)
 			return tcu::TestStatus::fail("No matching memory type found");
 
-		deUint32 pixelOffset = 0u;
+		// Get sparse image sparse memory requirements
+		sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
-		std::vector<VkSparseImageMemoryBind>  imageResidencyMemoryBinds;
-		std::vector<VkSparseMemoryBind>		  imageMipTailBinds;
+		DE_ASSERT(sparseMemoryRequirements.size() != 0);
 
-		// Bind memory for each mipmap level
-		for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
+		const deUint32							metadataAspectIndex		= getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_METADATA_BIT);
+		deUint32								pixelOffset				= 0u;
+		std::vector<VkSparseImageMemoryBind>	imageResidencyMemoryBinds;
+		std::vector<VkSparseMemoryBind>			imageMipTailBinds;
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			const deUint32 mipLevelSizeInPixels = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx) / tcu::getPixelSize(m_format);
+			const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+			const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
 
-			if (mipLevelNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_NOT_BOUND)
+			if (aspectIndex == NO_MATCH_FOUND)
+				TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+			VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+
+			DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
+
+			VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
+
+			// Bind memory for each mipmap level
+			for (deUint32 mipmapNdx = 0; mipmapNdx < aspectRequirements.imageMipTailFirstLod; ++mipmapNdx)
 			{
+				const deUint32 mipLevelSizeInPixels = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx) / formatDescription.planes[planeNdx].elementSizeBytes;
+
+				if (mipmapNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_NOT_BOUND)
+				{
+					pixelOffset += mipLevelSizeInPixels;
+					continue;
+				}
+
+				for (deUint32 pixelNdx = 0u; pixelNdx < mipLevelSizeInPixels; ++pixelNdx)
+				{
+					residencyReferenceData[pixelOffset + pixelNdx] = MEMORY_BLOCK_BOUND_VALUE;
+				}
+
 				pixelOffset += mipLevelSizeInPixels;
-				continue;
-			}
 
-			for (deUint32 pixelNdx = 0u; pixelNdx < mipLevelSizeInPixels; ++pixelNdx)
-			{
-				residencyReferenceData[pixelOffset + pixelNdx] = MEMORY_BLOCK_BOUND_VALUE;
-			}
-
-			pixelOffset += mipLevelSizeInPixels;
-
-			for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
-			{
-				const VkExtent3D		 mipExtent			= mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
-				const tcu::UVec3		 sparseBlocks		= alignedDivide(mipExtent, imageGranularity);
-				const deUint32			 numSparseBlocks	= sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
-				const VkImageSubresource subresource		= { aspectMask, mipLevelNdx, layerNdx };
-
-				const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
-					imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
-
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-				imageResidencyMemoryBinds.push_back(imageMemoryBind);
-			}
-		}
-
-		if (aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
-		{
-			if (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)
-			{
-				const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-					aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
-
-				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
-
-				imageMipTailBinds.push_back(imageMipTailMemoryBind);
-			}
-			else
-			{
 				for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
 				{
+					const VkExtent3D			mipExtent		= getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx);
+					const tcu::UVec3			sparseBlocks	= alignedDivide(mipExtent, imageGranularity);
+					const deUint32				numSparseBlocks	= sparseBlocks.x() * sparseBlocks.y() * sparseBlocks.z();
+					const VkImageSubresource	subresource		= { aspect, mipmapNdx, layerNdx };
+
+					const VkSparseImageMemoryBind imageMemoryBind = makeSparseImageMemoryBind(deviceInterface, getDevice(),
+						imageMemoryRequirements.alignment * numSparseBlocks, memoryType, subresource, makeOffset3D(0u, 0u, 0u), mipExtent);
+
+					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+					imageResidencyMemoryBinds.push_back(imageMemoryBind);
+				}
+			}
+
+			if (aspectRequirements.imageMipTailFirstLod < imageSparseInfo.mipLevels)
+			{
+				if (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)
+				{
 					const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
-						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
+						aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset);
 
 					deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
 
 					imageMipTailBinds.push_back(imageMipTailMemoryBind);
 				}
-			}
+				else
+				{
+					for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
+					{
+						const VkSparseMemoryBind imageMipTailMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
+							aspectRequirements.imageMipTailSize, memoryType, aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride);
 
-			for (deUint32 pixelNdx = pixelOffset; pixelNdx < residencyReferenceData.size(); ++pixelNdx)
-			{
-				residencyReferenceData[pixelNdx] = MEMORY_BLOCK_BOUND_VALUE;
+						deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(imageMipTailMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
+
+						imageMipTailBinds.push_back(imageMipTailMemoryBind);
+					}
+				}
+
+				for (deUint32 pixelNdx = pixelOffset; pixelNdx < residencyReferenceData.size(); ++pixelNdx)
+				{
+					residencyReferenceData[pixelNdx] = MEMORY_BLOCK_BOUND_VALUE;
+				}
 			}
 		}
 
@@ -411,14 +631,14 @@
 			&memoryBindSemaphore.get()			//const VkSemaphore*						pSignalSemaphores;
 		};
 
-		VkSparseImageMemoryBindInfo		  imageResidencyBindInfo;
-		VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo;
+		VkSparseImageMemoryBindInfo			imageResidencyBindInfo;
+		VkSparseImageOpaqueMemoryBindInfo	imageMipTailBindInfo;
 
 		if (imageResidencyMemoryBinds.size() > 0)
 		{
 			imageResidencyBindInfo.image		= *imageSparse;
 			imageResidencyBindInfo.bindCount	= static_cast<deUint32>(imageResidencyMemoryBinds.size());
-			imageResidencyBindInfo.pBinds		= &imageResidencyMemoryBinds[0];
+			imageResidencyBindInfo.pBinds		= imageResidencyMemoryBinds.data();
 
 			bindSparseInfo.imageBindCount		= 1u;
 			bindSparseInfo.pImageBinds			= &imageResidencyBindInfo;
@@ -428,7 +648,7 @@
 		{
 			imageMipTailBindInfo.image			= *imageSparse;
 			imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailBinds.size());
-			imageMipTailBindInfo.pBinds			= &imageMipTailBinds[0];
+			imageMipTailBindInfo.pBinds			= imageMipTailBinds.data();
 
 			bindSparseInfo.imageOpaqueBindCount = 1u;
 			bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
@@ -470,21 +690,34 @@
 	const Unique<VkImage>			imageResidency		(createImage(deviceInterface, getDevice(), &imageResidencyInfo));
 	const de::UniquePtr<Allocation>	imageResidencyAlloc	(bindImage(deviceInterface, getDevice(), getAllocator(), *imageResidency, MemoryRequirement::Any));
 
-	// Create command buffer for compute and transfer oparations
-	const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), extractQueue.queueFamilyIndex));
-	const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
-
-	std::vector <VkBufferImageCopy> bufferImageSparseCopy(imageSparseInfo.mipLevels);
+	std::vector <VkBufferImageCopy> bufferImageSparseCopy(formatDescription.numPlanes * imageSparseInfo.mipLevels);
 
 	{
 		deUint32 bufferOffset = 0u;
-		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			bufferImageSparseCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, static_cast<VkDeviceSize>(bufferOffset));
-			bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+			const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+			for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				bufferImageSparseCopy[planeNdx*imageSparseInfo.mipLevels + mipmapNdx] =
+				{
+					bufferOffset,																		//	VkDeviceSize				bufferOffset;
+					0u,																					//	deUint32					bufferRowLength;
+					0u,																					//	deUint32					bufferImageHeight;
+					makeImageSubresourceLayers(aspect, mipmapNdx, 0u, imageSparseInfo.arrayLayers),		//	VkImageSubresourceLayers	imageSubresource;
+					makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
+					vk::getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx)	//	VkExtent3D					imageExtent;
+				};
+				bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+			}
 		}
 	}
 
+	// Create command buffer for compute and transfer operations
+	const Unique<VkCommandPool>		commandPool(makeCommandPool(deviceInterface, getDevice(), extractQueue.queueFamilyIndex));
+	const Unique<VkCommandBuffer>	commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
 	// Start recording commands
 	beginCommandBuffer(deviceInterface, *commandBuffer);
 
@@ -496,18 +729,21 @@
 	// Fill input buffer with reference data
 	std::vector<deUint8> referenceData(imageSparseSizeInBytes);
 
-	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 	{
-		const deUint32 mipLevelSizeinBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
-		const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageSparseCopy[mipLevelNdx].bufferOffset);
-
-		for (deUint32 byteNdx = 0u; byteNdx < mipLevelSizeinBytes; ++byteNdx)
+		for (deUint32 mipmapNdx = 0u; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
 		{
-			referenceData[bufferOffset + byteNdx] = (deUint8)(mipLevelNdx + byteNdx);
+			const deUint32 mipLevelSizeinBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription, planeNdx, mipmapNdx);
+			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageSparseCopy[mipmapNdx].bufferOffset);
+
+			for (deUint32 byteNdx = 0u; byteNdx < mipLevelSizeinBytes; ++byteNdx)
+			{
+				referenceData[bufferOffset + byteNdx] = (deUint8)( (mipmapNdx + byteNdx) % 127u );
+			}
 		}
 	}
 
-	deMemcpy(inputBufferAlloc->getHostPtr(), &referenceData[0], imageSparseSizeInBytes);
+	deMemcpy(inputBufferAlloc->getHostPtr(), referenceData.data(), imageSparseSizeInBytes);
 	flushAlloc(deviceInterface, getDevice(), *inputBufferAlloc);
 
 	{
@@ -524,27 +760,30 @@
 		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &inputBufferBarrier, 0u, DE_NULL);
 	}
 
-	const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
-
 	{
 		// Prepare sparse image for data transfer operation
-		const VkImageMemoryBarrier imageSparseTransferDstBarrier = makeImageMemoryBarrier
-		(
-			0u,
-			VK_ACCESS_TRANSFER_WRITE_BIT,
-			VK_IMAGE_LAYOUT_UNDEFINED,
-			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-			*imageSparse,
-			fullImageSubresourceRange,
-			sparseQueue.queueFamilyIndex != extractQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
-			sparseQueue.queueFamilyIndex != extractQueue.queueFamilyIndex ? extractQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
-			);
+		std::vector<VkImageMemoryBarrier> imageSparseTransferDstBarriers;
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
 
-		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
+			imageSparseTransferDstBarriers.emplace_back(makeImageMemoryBarrier
+			(
+				0u,
+				VK_ACCESS_TRANSFER_WRITE_BIT,
+				VK_IMAGE_LAYOUT_UNDEFINED,
+				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+				*imageSparse,
+				makeImageSubresourceRange(aspect, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers),
+				sparseQueue.queueFamilyIndex != extractQueue.queueFamilyIndex ? sparseQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED,
+				sparseQueue.queueFamilyIndex != extractQueue.queueFamilyIndex ? extractQueue.queueFamilyIndex : VK_QUEUE_FAMILY_IGNORED
+			));
+		}
+		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, static_cast<deUint32>(imageSparseTransferDstBarriers.size()), imageSparseTransferDstBarriers.data());
 	}
 
 	// Copy reference data from input buffer to sparse image
-	deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageSparseCopy.size()), &bufferImageSparseCopy[0]);
+	deviceInterface.cmdCopyBufferToImage(*commandBuffer, *inputBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageSparseCopy.size()), bufferImageSparseCopy.data());
 
 	recordCommands(*commandBuffer, imageSparseInfo, *imageSparse, *imageTexels, *imageResidency);
 
@@ -553,7 +792,7 @@
 	const de::UniquePtr<Allocation>	bufferTexelsAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *bufferTexels, MemoryRequirement::HostVisible));
 
 	// Copy data from texels image to buffer
-	deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageTexels, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *bufferTexels, static_cast<deUint32>(bufferImageSparseCopy.size()), &bufferImageSparseCopy[0]);
+	deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageTexels, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *bufferTexels, static_cast<deUint32>(bufferImageSparseCopy.size()), bufferImageSparseCopy.data());
 
 	const deUint32				imageResidencySizeInBytes = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, imageSparseInfo.mipLevels, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
 
@@ -562,18 +801,31 @@
 	const de::UniquePtr<Allocation>	bufferResidencyAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *bufferResidency, MemoryRequirement::HostVisible));
 
 	// Copy data from residency image to buffer
-	std::vector <VkBufferImageCopy> bufferImageResidencyCopy(imageSparseInfo.mipLevels);
+	std::vector <VkBufferImageCopy> bufferImageResidencyCopy(formatDescription.numPlanes * imageSparseInfo.mipLevels);
 
 	{
 		deUint32 bufferOffset = 0u;
-		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+		for (deUint32 planeNdx = 0u; planeNdx < formatDescription.numPlanes; ++planeNdx)
 		{
-			bufferImageResidencyCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, static_cast<VkDeviceSize>(bufferOffset));
-			bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipLevelNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+			const VkImageAspectFlags aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+			for (deUint32 mipmapNdx = 0u; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+			{
+				bufferImageResidencyCopy[planeNdx * imageSparseInfo.mipLevels + mipmapNdx] =
+				{
+					bufferOffset,																		//	VkDeviceSize				bufferOffset;
+					0u,																					//	deUint32					bufferRowLength;
+					0u,																					//	deUint32					bufferImageHeight;
+					makeImageSubresourceLayers(aspect, mipmapNdx, 0u, imageSparseInfo.arrayLayers),		//	VkImageSubresourceLayers	imageSubresource;
+					makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
+					vk::getPlaneExtent(formatDescription, imageSparseInfo.extent, planeNdx, mipmapNdx)	//	VkExtent3D					imageExtent;
+				};
+				bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipmapNdx, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+			}
 		}
 	}
 
-	deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageResidency, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *bufferResidency, static_cast<deUint32>(bufferImageResidencyCopy.size()), &bufferImageResidencyCopy[0]);
+	deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageResidency, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *bufferResidency, static_cast<deUint32>(bufferImageResidencyCopy.size()), bufferImageResidencyCopy.data());
 
 	{
 		VkBufferMemoryBarrier bufferOutputHostReadBarriers[2];
@@ -616,47 +868,60 @@
 	const deUint32* bufferResidencyData = static_cast<const deUint32*>(bufferResidencyAlloc->getHostPtr());
 
 	deUint32 pixelOffsetNotAligned = 0u;
-	for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 	{
-		const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipmapNdx);
-		const deUint32 pixelOffsetAligned	= static_cast<deUint32>(bufferImageResidencyCopy[mipmapNdx].bufferOffset) / tcu::getPixelSize(m_residencyFormat);
+		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+		{
+			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipmapNdx);
+			const deUint32 pixelOffsetAligned	= static_cast<deUint32>(bufferImageResidencyCopy[planeNdx * imageSparseInfo.mipLevels + mipmapNdx].bufferOffset) / tcu::getPixelSize(m_residencyFormat);
 
-		if (deMemCmp(&bufferResidencyData[pixelOffsetAligned], &residencyReferenceData[pixelOffsetNotAligned], mipLevelSizeInBytes) != 0)
-			return tcu::TestStatus::fail("Failed");
+			if (deMemCmp(&bufferResidencyData[pixelOffsetAligned], &residencyReferenceData[pixelOffsetNotAligned], mipLevelSizeInBytes) != 0)
+				return tcu::TestStatus::fail("Failed");
 
-		pixelOffsetNotAligned += mipLevelSizeInBytes / tcu::getPixelSize(m_residencyFormat);
-	}
-
+			pixelOffsetNotAligned += mipLevelSizeInBytes / tcu::getPixelSize(m_residencyFormat);
+		}
+}
 	// Retrieve data from texels buffer to host memory
 	invalidateAlloc(deviceInterface, getDevice(), *bufferTexelsAlloc);
 
 	const deUint8* bufferTexelsData = static_cast<const deUint8*>(bufferTexelsAlloc->getHostPtr());
 
-	for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
 	{
-		const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
-		const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageSparseCopy[mipmapNdx].bufferOffset);
+		const VkImageAspectFlags	aspect		= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+		const deUint32				aspectIndex	= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);
 
-		if (mipmapNdx < aspectRequirements.imageMipTailFirstLod)
+		if (aspectIndex == NO_MATCH_FOUND)
+			TCU_THROW(NotSupportedError, "Not supported image aspect");
+
+		VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
+
+		for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
 		{
-			if (mipmapNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_BOUND)
+			const deUint32 mipLevelSizeInBytes	= getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, formatDescription,planeNdx, mipmapNdx);
+			const deUint32 bufferOffset			= static_cast<deUint32>(bufferImageSparseCopy[planeNdx * imageSparseInfo.mipLevels + mipmapNdx].bufferOffset);
+
+			if (mipmapNdx < aspectRequirements.imageMipTailFirstLod)
+			{
+				if (mipmapNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_BOUND)
+				{
+					if (deMemCmp(&bufferTexelsData[bufferOffset], &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+						return tcu::TestStatus::fail("Failed");
+				}
+				else if (getPhysicalDeviceProperties(instance, physicalDevice).sparseProperties.residencyNonResidentStrict)
+				{
+					std::vector<deUint8> zeroData;
+					zeroData.assign(mipLevelSizeInBytes, 0u);
+
+					if (deMemCmp(&bufferTexelsData[bufferOffset], zeroData.data(), mipLevelSizeInBytes) != 0)
+						return tcu::TestStatus::fail("Failed");
+				}
+			}
+			else
 			{
 				if (deMemCmp(&bufferTexelsData[bufferOffset], &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
 					return tcu::TestStatus::fail("Failed");
 			}
-			else if (getPhysicalDeviceProperties(instance, physicalDevice).sparseProperties.residencyNonResidentStrict)
-			{
-				std::vector<deUint8> zeroData;
-				zeroData.assign(mipLevelSizeInBytes, 0u);
-
-				if (deMemCmp(&bufferTexelsData[bufferOffset], &zeroData[0], mipLevelSizeInBytes) != 0)
-					return tcu::TestStatus::fail("Failed");
-			}
-		}
-		else
-		{
-			if (deMemCmp(&bufferTexelsData[bufferOffset], &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
-				return tcu::TestStatus::fail("Failed");
 		}
 	}
 
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.hpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.hpp
index 9cf4832..3d6c4ac 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.hpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.hpp
@@ -87,25 +87,30 @@
 };
 
 std::string getOpTypeImageComponent			(const tcu::TextureFormat& format);
+std::string getOpTypeImageComponent			(const vk::PlanarFormatDescription& description);
 std::string getImageComponentTypeName		(const tcu::TextureFormat& format);
+std::string getImageComponentTypeName		(const vk::PlanarFormatDescription& description);
 std::string getImageComponentVec4TypeName	(const tcu::TextureFormat& format);
-
-std::string getOpTypeImageSparse	(const ImageType			imageType,
-									 const tcu::TextureFormat&	format,
-									 const std::string&			componentType,
-									 const bool					requiresSampler);
-
-std::string getOpTypeImageResidency	(const ImageType imageType);
+std::string getImageComponentVec4TypeName	(const vk::PlanarFormatDescription& description);
+std::string getOpTypeImageSparse			(const ImageType			imageType,
+											 const tcu::TextureFormat&	format,
+											 const std::string&			componentType,
+											 const bool					requiresSampler);
+std::string getOpTypeImageSparse			(const ImageType			imageType,
+											 const vk::VkFormat			format,
+											 const std::string&			componentType,
+											 const bool					requiresSampler);
+std::string getOpTypeImageResidency			(const ImageType imageType);
 
 class SparseShaderIntrinsicsCaseBase : public TestCase
 {
 public:
-					SparseShaderIntrinsicsCaseBase	(tcu::TestContext&			testCtx,
-													 const std::string&			name,
-													 const SpirVFunction		function,
-													 const ImageType			imageType,
-													 const tcu::UVec3&			imageSize,
-													 const tcu::TextureFormat&	format)
+	SparseShaderIntrinsicsCaseBase			(tcu::TestContext&			testCtx,
+											 const std::string&			name,
+											 const SpirVFunction		function,
+											 const ImageType			imageType,
+											 const tcu::UVec3&			imageSize,
+											 const vk::VkFormat			format)
 		: TestCase(testCtx, name, "")
 		, m_function(function)
 		, m_imageType(imageType)
@@ -134,7 +139,7 @@
 	const SpirVFunction			m_function;
 	const ImageType				m_imageType;
 	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const vk::VkFormat			m_format;
 };
 
 class SparseShaderIntrinsicsInstanceBase : public SparseResourcesBaseInstance
@@ -144,7 +149,7 @@
 											 const SpirVFunction		function,
 											 const ImageType			imageType,
 											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format)
+											 const vk::VkFormat			format)
 		: SparseResourcesBaseInstance(context)
 		, m_function(function)
 		, m_imageType(imageType)
@@ -170,7 +175,7 @@
 	const SpirVFunction			m_function;
 	const ImageType				m_imageType;
 	const tcu::UVec3			m_imageSize;
-	const tcu::TextureFormat	m_format;
+	const vk::VkFormat			m_format;
 	const tcu::TextureFormat	m_residencyFormat;
 
 	typedef de::SharedPtr< vk::Unique<vk::VkPipeline> >			SharedVkPipeline;
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.cpp
index abc8ef2..d0c879d 100755
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.cpp
@@ -36,19 +36,19 @@
 namespace
 {
 
-Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&			vk,
-									   const VkDevice					device,
-									   const VkPipelineLayout			pipelineLayout,
-									   const VkRenderPass				renderPass,
-									   const VkShaderModule				vertexModule,
-									   const VkShaderModule				fragmentModule,
-									   const VkShaderModule				geometryModule)
+Move<VkPipeline> makeGraphicsPipeline	(const DeviceInterface&	vk,
+										 const VkDevice			device,
+										 const VkPipelineLayout	pipelineLayout,
+										 const VkRenderPass		renderPass,
+										 const VkShaderModule	vertexModule,
+										 const VkShaderModule	fragmentModule,
+										 const VkShaderModule	geometryModule)
 {
 	const std::vector<VkViewport>				noViewports;
 	const std::vector<VkRect2D>					noScissors;
 
-	const VkFormat								format		= VK_FORMAT_R32G32_SFLOAT;
-	const deUint32								size		= tcu::getPixelSize(mapVkFormat(format));
+	const VkFormat								format	= VK_FORMAT_R32G32_SFLOAT;
+	const deUint32								size	= tcu::getPixelSize(mapVkFormat(format));
 
 	const VkVertexInputBindingDescription		vertexBinding =
 	{
@@ -77,13 +77,13 @@
 
 	const VkPipelineVertexInputStateCreateInfo	vertexInputStateCreateInfo	=
 	{
-		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
-		DE_NULL,													// const void*                                 pNext;
-		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
-		1u,															// deUint32                                    vertexBindingDescriptionCount;
-		&vertexBinding,												// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
-		2u,															// deUint32                                    vertexAttributeDescriptionCount;
-		vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
+		DE_NULL,													// const void*								pNext;
+		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags	flags;
+		1u,															// deUint32									vertexBindingDescriptionCount;
+		&vertexBinding,												// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
+		2u,															// deUint32									vertexAttributeDescriptionCount;
+		vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
 	};
 
 	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
@@ -117,45 +117,46 @@
 		{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
 	};
 
-	return vk::makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
-									device,									// const VkDevice                                device
-									pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
-									vertexModule,							// const VkShaderModule                          vertexShaderModule
-									DE_NULL,								// const VkShaderModule                          tessellationControlModule
-									DE_NULL,								// const VkShaderModule                          tessellationEvalModule
-									geometryModule,							// const VkShaderModule                          geometryShaderModule
-									fragmentModule,							// const VkShaderModule                          fragmentShaderModule
-									renderPass,								// const VkRenderPass                            renderPass
-									noViewports,							// const std::vector<VkViewport>&                viewports
-									noScissors,								// const std::vector<VkRect2D>&                  scissors
-									VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
-									0u,										// const deUint32                                subpass
-									0u,										// const deUint32                                patchControlPoints
-									&vertexInputStateCreateInfo,			// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
-									DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
-									DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
-									DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
-									&pipelineColorBlendStateInfo);			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
+	return vk::makeGraphicsPipeline(vk,										// const DeviceInterface&							vk
+									device,									// const VkDevice									device
+									pipelineLayout,							// const VkPipelineLayout							pipelineLayout
+									vertexModule,							// const VkShaderModule								vertexShaderModule
+									DE_NULL,								// const VkShaderModule								tessellationControlModule
+									DE_NULL,								// const VkShaderModule								tessellationEvalModule
+									geometryModule,							// const VkShaderModule								geometryShaderModule
+									fragmentModule,							// const VkShaderModule								fragmentShaderModule
+									renderPass,								// const VkRenderPass								renderPass
+									noViewports,							// const std::vector<VkViewport>&					viewports
+									noScissors,								// const std::vector<VkRect2D>&						scissors
+									VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology						topology
+									0u,										// const deUint32									subpass
+									0u,										// const deUint32									patchControlPoints
+									&vertexInputStateCreateInfo,			// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
+									DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
+									DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
+									DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
+									&pipelineColorBlendStateInfo);			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
 }
 
 } // anonymous
 
 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
 {
-	const deUint32		numLayers	= getNumLayers(m_imageType, m_imageSize);
-	const std::string	coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
+	const deUint32					numLayers			= getNumLayers(m_imageType, m_imageSize);
+	const std::string				coordString			= getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
 
 	// Create vertex shader
 	std::ostringstream vs;
 
 	vs	<< "#version 440\n"
-		<< "layout(location = 0) in  highp vec2 vs_in_position;\n"
-		<< "layout(location = 1) in  highp vec2 vs_in_texCoord;\n"
+		<< "layout(location = 0) in highp vec2 vs_in_position;\n"
+		<< "layout(location = 1) in highp vec2 vs_in_texCoord;\n"
 		<< "\n"
 		<< "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
 		<< "\n"
 		<< "out gl_PerVertex {\n"
-		<< "	vec4  gl_Position;\n"
+		<< "	vec4 gl_Position;\n"
 		<< "};\n"
 		<< "void main (void)\n"
 		<< "{\n"
@@ -188,17 +189,17 @@
 			<< "\n"
 			<< "void main (void)\n"
 			<< "{\n"
-			<< "    for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
-			<< "    {\n"
+			<< "	for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
+			<< "	{\n"
 			<< "		for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
 			<< "		{\n"
 			<< "			gl_Layer		= layerNdx;\n"
 			<< "			gl_Position		= gl_in[vertexNdx].gl_Position;\n"
-			<< "			gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
+			<< "			gs_out_texCoord	= vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
 			<< "			EmitVertex();\n"
 			<< "		}\n"
 			<< "		EndPrimitive();\n"
-			<< "    }\n"
+			<< "	}\n"
 			<< "}\n";
 
 		programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
@@ -207,8 +208,8 @@
 	// Create fragment shader
 	std::ostringstream fs;
 
-	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
-	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
+	const std::string	typeImgComp		= getImageComponentTypeName(formatDescription);
+	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(formatDescription);
 
 	fs	<< "OpCapability Shader\n"
 		<< "OpCapability SampledCubeArray\n"
@@ -258,10 +259,10 @@
 		<< "%type_vec2							= OpTypeVector %type_float 2\n"
 		<< "%type_vec3							= OpTypeVector %type_float 3\n"
 		<< "%type_vec4							= OpTypeVector %type_float 4\n"
-		<< "%type_ivec4						= OpTypeVector %type_int  4\n"
-		<< "%type_uvec4						= OpTypeVector %type_uint 4\n"
+		<< "%type_ivec4							= OpTypeVector %type_int 4\n"
+		<< "%type_uvec4							= OpTypeVector %type_uint 4\n"
 		<< "%type_uniformblock					= OpTypeStruct %type_uint %type_vec2\n"
-		<< "%type_struct_int_img_comp_vec4	= OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
+		<< "%type_struct_int_img_comp_vec4		= OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
 
 		<< "%type_input_vec3					= OpTypePointer Input %type_vec3\n"
 		<< "%type_input_float					= OpTypePointer Input %type_float\n"
@@ -274,8 +275,8 @@
 		<< "%type_function_int_img_comp_vec4	= OpTypePointer Function %type_struct_int_img_comp_vec4\n"
 
 		<< "%type_pushconstant_uniformblock				= OpTypePointer PushConstant %type_uniformblock\n"
-		<< "%type_pushconstant_uniformblock_member_lod  = OpTypePointer PushConstant %type_uint\n"
-		<< "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
+		<< "%type_pushconstant_uniformblock_member_lod	= OpTypePointer PushConstant %type_uint\n"
+		<< "%type_pushconstant_uniformblock_member_size	= OpTypePointer PushConstant %type_vec2\n"
 
 		<< "%type_image_sparse				= " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
 		<< "%type_sampled_image_sparse		= OpTypeSampledImage %type_image_sparse\n"
@@ -372,11 +373,11 @@
 	return src.str();
 }
 
-std::string	SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString  (const std::string& resultVariable,
-																			const std::string& resultType,
-																			const std::string& image,
-																			const std::string& coord,
-																			const std::string& miplevel) const
+std::string	SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString (const std::string& resultVariable,
+																		   const std::string& resultType,
+																		   const std::string& image,
+																		   const std::string& coord,
+																		   const std::string& miplevel) const
 {
 	DE_UNREF(miplevel);
 
@@ -397,8 +398,9 @@
 
 	std::ostringstream	src;
 
-	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
-	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(m_format);
+	const std::string				typeImgComp			= getImageComponentTypeName(formatDescription);
+	const std::string				typeImgCompVec4		= getImageComponentVec4TypeName(formatDescription);
 
 	// Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
 
@@ -428,8 +430,7 @@
 
 		default:
 		{
-			/* This can't be happening. */
-			DE_ASSERT(DE_FALSE);
+			DE_FATAL("Unexpected image type");
 		}
 	}
 
@@ -459,12 +460,12 @@
 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
 {
 public:
-	SparseShaderIntrinsicsInstanceSampledBase	(Context&					context,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-	: SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsInstanceSampledBase		(Context&				context,
+													 const SpirVFunction	function,
+													 const ImageType		imageType,
+													 const tcu::UVec3&		imageSize,
+													 const VkFormat			format)
+		: SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
 
 	VkImageUsageFlags		imageSparseUsageFlags	(void) const;
 	VkImageUsageFlags		imageOutputUsageFlags	(void) const;
@@ -480,7 +481,7 @@
 	virtual VkImageSubresourceRange	sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
 
 private:
-	typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp;
+	typedef de::SharedPtr< vk::Unique<VkFramebuffer> > VkFramebufferSp;
 
 	Move<VkBuffer>					m_vertexBuffer;
 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
@@ -650,9 +651,27 @@
 
 	descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
 
-	// Create sampler object
-	const tcu::Sampler			samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST);
-	const VkSamplerCreateInfo	samplerCreateInfo = mapSampler(samplerObject, m_format);
+	VkSamplerCreateInfo	samplerCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+		DE_NULL,
+		(VkSamplerCreateFlags)0,
+		mapFilterMode(tcu::Sampler::NEAREST),					// magFilter
+		mapFilterMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST),	// minFilter
+		mapMipmapMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST),	// mipMode
+		mapWrapMode(tcu::Sampler::REPEAT_GL),					// addressU
+		mapWrapMode(tcu::Sampler::REPEAT_GL),					// addressV
+		mapWrapMode(tcu::Sampler::REPEAT_GL),					// addressW
+		0.0f,													// mipLodBias
+		VK_FALSE,												// anisotropyEnable
+		1.0f,													// maxAnisotropy
+		VK_FALSE,												// compareEnable
+		mapCompareMode(tcu::Sampler::COMPAREMODE_ALWAYS),		// compareOp
+		0.0f,													// minLod
+		1000.0f,												// maxLod
+		VK_BORDER_COLOR_INT_TRANSPARENT_BLACK,					// borderColor
+		VK_FALSE,												// unnormalizedCoords
+	};
 	m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
 
 	struct PushConstants
@@ -752,29 +771,29 @@
 
 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
 	{
-		const vk::VkExtent3D			mipLevelSize	= mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
-		const vk::VkRect2D				renderArea		= makeRect2D(mipLevelSize);
+		const VkExtent3D				mipLevelSize	= mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
+		const VkRect2D					renderArea		= makeRect2D(mipLevelSize);
 		const VkViewport				viewport		= makeViewport(mipLevelSize);
 		const VkImageSubresourceRange	mipLevelRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
 
 		// Create color attachments image views
-		imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
-		imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
+		imageTexelsViews[mipLevelNdx]		= makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
+		imageResidencyViews[mipLevelNdx]	= makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
 
 		const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
 
 		// Create framebuffer
 		const VkFramebufferCreateInfo framebufferInfo =
 		{
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType                             sType;
-			DE_NULL,									// const void*                                 pNext;
-			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags                    flags;
-			*m_renderPass,								// VkRenderPass                                renderPass;
-			2u,											// uint32_t                                    attachmentCount;
-			attachmentsViews,							// const VkImageView*                          pAttachments;
-			mipLevelSize.width,							// uint32_t                                    width;
-			mipLevelSize.height,						// uint32_t                                    height;
-			imageSparseInfo.arrayLayers,				// uint32_t                                    layers;
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
+			DE_NULL,									// const void*				pNext;
+			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags	flags;
+			*m_renderPass,								// VkRenderPass				renderPass;
+			2u,											// uint32_t					attachmentCount;
+			attachmentsViews,							// const VkImageView*		pAttachments;
+			mipLevelSize.width,							// uint32_t					width;
+			mipLevelSize.height,						// uint32_t					height;
+			imageSparseInfo.arrayLayers,				// uint32_t					layers;
 		};
 
 		m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
@@ -866,12 +885,12 @@
 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
 {
 public:
-	SparseShaderIntrinsicsInstanceSampledExplicit	(Context&					context,
-													 const SpirVFunction		function,
-													 const ImageType			imageType,
-													 const tcu::UVec3&			imageSize,
-													 const tcu::TextureFormat&	format)
-	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsInstanceSampledExplicit	(Context&				context,
+													 const SpirVFunction	function,
+													 const ImageType		imageType,
+													 const tcu::UVec3&		imageSize,
+													 const VkFormat			format)
+		: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
 
 	VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo&	imageSparseInfo,
 													 const deUint32				mipLevel) const
@@ -889,12 +908,12 @@
 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
 {
 public:
-	SparseShaderIntrinsicsInstanceSampledImplicit	(Context&					context,
-													 const SpirVFunction		function,
-													 const ImageType			imageType,
-													 const tcu::UVec3&			imageSize,
-													 const tcu::TextureFormat&	format)
-	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsInstanceSampledImplicit	(Context&				context,
+													 const SpirVFunction	function,
+													 const ImageType		imageType,
+													 const tcu::UVec3&		imageSize,
+													 const VkFormat			format)
+		: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
 
 	VkImageSubresourceRange	sampledImageRangeToBind	(const VkImageCreateInfo&	imageSparseInfo,
 													 const deUint32				mipLevel) const
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.hpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.hpp
index 07e1582..d395eb6 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.hpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsSampled.hpp
@@ -33,103 +33,103 @@
 class SparseShaderIntrinsicsCaseSampledBase : public SparseShaderIntrinsicsCaseBase
 {
 public:
-	SparseShaderIntrinsicsCaseSampledBase		(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseBase (testCtx, name, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsCaseSampledBase	(tcu::TestContext&		testCtx,
+											 const std::string&		name,
+											 const SpirVFunction	function,
+											 const ImageType		imageType,
+											 const tcu::UVec3&		imageSize,
+											 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseBase (testCtx, name, function, imageType, imageSize, format) {}
 
-	void				initPrograms			(vk::SourceCollections&		programCollection) const;
+	void				initPrograms		(vk::SourceCollections&	programCollection) const;
 
-	virtual std::string	sparseImageOpString		(const std::string&			resultVariable,
-												 const std::string&			resultType,
-												 const std::string&			image,
-												 const std::string&			coord,
-												 const std::string&			miplevel) const = 0;
+	virtual std::string	sparseImageOpString	(const std::string&		resultVariable,
+											 const std::string&		resultType,
+											 const std::string&		image,
+											 const std::string&		coord,
+											 const std::string&		miplevel) const = 0;
 };
 
 class SparseShaderIntrinsicsCaseSampledExplicit : public SparseShaderIntrinsicsCaseSampledBase
 {
 public:
-	SparseShaderIntrinsicsCaseSampledExplicit	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseSampledBase (testCtx, name, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsCaseSampledExplicit	(tcu::TestContext&		testCtx,
+												 const std::string&		name,
+												 const SpirVFunction	function,
+												 const ImageType		imageType,
+												 const tcu::UVec3&		imageSize,
+												 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseSampledBase (testCtx, name, function, imageType, imageSize, format) {}
 
-	TestInstance*	createInstance				(Context&					context) const;
+	TestInstance*	createInstance				(Context&				context) const;
 };
 
 class SparseCaseOpImageSparseSampleExplicitLod : public SparseShaderIntrinsicsCaseSampledExplicit
 {
 public:
-	SparseCaseOpImageSparseSampleExplicitLod	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseSampledExplicit (testCtx, name, function, imageType, imageSize, format) {}
+	SparseCaseOpImageSparseSampleExplicitLod	(tcu::TestContext&		testCtx,
+												 const std::string&		name,
+												 const SpirVFunction	function,
+												 const ImageType		imageType,
+												 const tcu::UVec3&		imageSize,
+												 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseSampledExplicit (testCtx, name, function, imageType, imageSize, format) {}
 
-	std::string	sparseImageOpString				(const std::string&			resultVariable,
-												 const std::string&			resultType,
-												 const std::string&			image,
-												 const std::string&			coord,
-												 const std::string&			miplevel) const;
+	std::string	sparseImageOpString				(const std::string&		resultVariable,
+												 const std::string&		resultType,
+												 const std::string&		image,
+												 const std::string&		coord,
+												 const std::string&		miplevel) const;
 };
 
 class SparseShaderIntrinsicsCaseSampledImplicit : public SparseShaderIntrinsicsCaseSampledBase
 {
 public:
-	SparseShaderIntrinsicsCaseSampledImplicit	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseSampledBase (testCtx, name, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsCaseSampledImplicit	(tcu::TestContext&		testCtx,
+												 const std::string&		name,
+												 const SpirVFunction	function,
+												 const ImageType		imageType,
+												 const tcu::UVec3&		imageSize,
+												 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseSampledBase (testCtx, name, function, imageType, imageSize, format) {}
 
-	TestInstance*	createInstance				(Context&					context) const;
+	TestInstance*	createInstance				(Context&				context) const;
 };
 
 class SparseCaseOpImageSparseSampleImplicitLod : public SparseShaderIntrinsicsCaseSampledImplicit
 {
 public:
-	SparseCaseOpImageSparseSampleImplicitLod	(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseSampledImplicit (testCtx, name, function, imageType, imageSize, format) {}
+	SparseCaseOpImageSparseSampleImplicitLod	(tcu::TestContext&		testCtx,
+												 const std::string&		name,
+												 const SpirVFunction	function,
+												 const ImageType		imageType,
+												 const tcu::UVec3&		imageSize,
+												 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseSampledImplicit (testCtx, name, function, imageType, imageSize, format) {}
 
-	std::string	sparseImageOpString				(const std::string&			resultVariable,
-												 const std::string&			resultType,
-												 const std::string&			image,
-												 const std::string&			coord,
-												 const std::string&			miplevel) const;
+	std::string	sparseImageOpString				(const std::string&		resultVariable,
+												 const std::string&		resultType,
+												 const std::string&		image,
+												 const std::string&		coord,
+												 const std::string&		miplevel) const;
 };
 
 class SparseCaseOpImageSparseGather : public SparseShaderIntrinsicsCaseSampledImplicit
 {
 public:
-	SparseCaseOpImageSparseGather				(tcu::TestContext&			testCtx,
-												 const std::string&			name,
-												 const SpirVFunction		function,
-												 const ImageType			imageType,
-												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-												 : SparseShaderIntrinsicsCaseSampledImplicit (testCtx, name, function, imageType, imageSize, format) {}
+	SparseCaseOpImageSparseGather		(tcu::TestContext&		testCtx,
+										 const std::string&		name,
+										 const SpirVFunction	function,
+										 const ImageType		imageType,
+										 const tcu::UVec3&		imageSize,
+										 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseSampledImplicit (testCtx, name, function, imageType, imageSize, format) {}
 
-	std::string	sparseImageOpString				(const std::string&			resultVariable,
-												 const std::string&			resultType,
-												 const std::string&			image,
-												 const std::string&			coord,
-												 const std::string&			miplevel) const;
+	std::string	sparseImageOpString		(const std::string&		resultVariable,
+										 const std::string&		resultType,
+										 const std::string&		image,
+										 const std::string&		coord,
+										 const std::string&		miplevel) const;
 };
 
 } // sparse
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.cpp
index 08d1e8d..9fd8fb7 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.cpp
@@ -46,21 +46,25 @@
 
 void SparseShaderIntrinsicsCaseStorage::initPrograms (vk::SourceCollections& programCollection) const
 {
-	const std::string	imageTypeStr	= getShaderImageType(m_format, m_imageType);
-	const std::string	formatDataStr	= getShaderImageDataType(m_format);
-	const std::string	formatQualStr	= getShaderImageFormatQualifier(m_format);
-
-	const std::string  coordString		= getShaderImageCoordinates(m_imageType,
+	const PlanarFormatDescription	formatDescription			= getPlanarFormatDescription(m_format);
+	const std::string				imageTypeStr				= getShaderImageType(formatDescription, m_imageType);
+	const std::string				formatDataStr				= getShaderImageDataType(formatDescription);
+	const std::string				formatQualStr				= getShaderImageFormatQualifier(m_format);
+	const std::string				coordString					= getShaderImageCoordinates(m_imageType,
 																	"%local_int_GlobalInvocationID_x",
 																	"%local_ivec2_GlobalInvocationID_xy",
 																	"%local_ivec3_GlobalInvocationID_xyz");
 	// Create compute program
-	std::ostringstream	src;
+	std::ostringstream				src;
 
-	const std::string	typeImgComp					= getImageComponentTypeName(m_format);
-	const std::string	typeImgCompVec4				= getImageComponentVec4TypeName(m_format);
-	const std::string	typeImageSparse				= getSparseImageTypeName();
-	const std::string	typeUniformConstImageSparse	= getUniformConstSparseImageTypeName();
+	const std::string				typeImgComp					= getImageComponentTypeName(formatDescription);
+	const std::string				typeImgCompVec4				= getImageComponentVec4TypeName(formatDescription);
+	const std::string				typeImageSparse				= getSparseImageTypeName();
+	const std::string				typeUniformConstImageSparse	= getUniformConstSparseImageTypeName();
+	const std::string				opTypeImageSparse			= getOpTypeImageSparse(m_imageType, m_format, typeImgComp, false);
+	const std::string				opTypeImageResidency		= getOpTypeImageResidency(m_imageType);
+	// it's not possible to declare two OpTypeImage aliases for the same data type - we have to eliminate %type_image_residency when %type_image_sparse is the same
+	const std::string				typeImageResidencyName		= (opTypeImageSparse == opTypeImageResidency) ? "%type_image_sparse" : "%type_image_residency";
 
 	src << "OpCapability Shader\n"
 		<< "OpCapability ImageCubeArray\n"
@@ -109,11 +113,15 @@
 		<< "%type_bool						= OpTypeBool\n"
 		<< "%type_int						= OpTypeInt 32 1\n"
 		<< "%type_uint						= OpTypeInt 32 0\n"
+		<< "%type_float						= OpTypeFloat 32\n"
 		<< "%type_ivec2						= OpTypeVector %type_int  2\n"
 		<< "%type_ivec3						= OpTypeVector %type_int  3\n"
 		<< "%type_ivec4						= OpTypeVector %type_int  4\n"
 		<< "%type_uvec3						= OpTypeVector %type_uint 3\n"
 		<< "%type_uvec4						= OpTypeVector %type_uint 4\n"
+		<< "%type_vec2						= OpTypeVector %type_float 2\n"
+		<< "%type_vec3						= OpTypeVector %type_float 3\n"
+		<< "%type_vec4						= OpTypeVector %type_float 4\n"
 		<< "%type_struct_int_img_comp_vec4	= OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
 
 		<< "%type_input_uint		= OpTypePointer Input %type_uint\n"
@@ -131,11 +139,14 @@
 
 		// Sparse image with sampler type declaration
 		<< "%type_image_sparse_with_sampler = " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
-		<< "%type_uniformconst_image_sparse_with_sampler = OpTypePointer UniformConstant %type_image_sparse_with_sampler\n"
+		<< "%type_uniformconst_image_sparse_with_sampler = OpTypePointer UniformConstant %type_image_sparse_with_sampler\n";
+
 
 		// Residency image type declaration
-		<< "%type_image_residency				= " << getOpTypeImageResidency(m_imageType) << "\n"
-		<< "%type_uniformconst_image_residency	= OpTypePointer UniformConstant %type_image_residency\n"
+	if ( opTypeImageSparse != opTypeImageResidency )
+		src << "%type_image_residency				= " << getOpTypeImageResidency(m_imageType) << "\n";
+
+	src << "%type_uniformconst_image_residency	= OpTypePointer UniformConstant "<< typeImageResidencyName <<"\n"
 
 		// Declare sparse image variable
 		<< "%uniform_image_sparse = OpVariable " << typeUniformConstImageSparse << " UniformConstant\n"
@@ -226,7 +237,7 @@
 		<< "OpImageWrite %local_image_texels " << coordString << " %local_img_comp_vec4\n"
 
 		// Load residency info image
-		<< "%local_image_residency	= OpLoad %type_image_residency %uniform_image_residency\n"
+		<< "%local_image_residency	= OpLoad " << typeImageResidencyName <<" %uniform_image_residency\n"
 
 		// Check if loaded texel is placed in resident memory
 		<< "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
@@ -271,11 +282,11 @@
 	return "%type_uniformconst_image_sparse_with_sampler";
 }
 
-std::string	SparseCaseOpImageSparseFetch::sparseImageOpString  (const std::string& resultVariable,
-																const std::string& resultType,
-																const std::string& image,
-																const std::string& coord,
-																const std::string& mipLevel) const
+std::string	SparseCaseOpImageSparseFetch::sparseImageOpString (const std::string& resultVariable,
+															   const std::string& resultType,
+															   const std::string& image,
+															   const std::string& coord,
+															   const std::string& mipLevel) const
 {
 	std::ostringstream	src;
 
@@ -312,24 +323,24 @@
 class SparseShaderIntrinsicsInstanceStorage : public SparseShaderIntrinsicsInstanceBase
 {
 public:
-	SparseShaderIntrinsicsInstanceStorage	(Context&					context,
-											 const SpirVFunction		function,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format)
+	SparseShaderIntrinsicsInstanceStorage			(Context&				context,
+													 const SpirVFunction	function,
+													 const ImageType		imageType,
+													 const tcu::UVec3&		imageSize,
+													 const VkFormat			format)
 		: SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
 
-	VkImageUsageFlags				imageOutputUsageFlags	(void) const;
+	VkImageUsageFlags		imageOutputUsageFlags	(void) const;
 
-	VkQueueFlags					getQueueFlags			(void) const;
+	VkQueueFlags			getQueueFlags			(void) const;
 
-	void							recordCommands			(const VkCommandBuffer		commandBuffer,
-															 const VkImageCreateInfo&	imageSparseInfo,
-															 const VkImage				imageSparse,
-															 const VkImage				imageTexels,
-															 const VkImage				imageResidency);
+	void					recordCommands			(const VkCommandBuffer		commandBuffer,
+													 const VkImageCreateInfo&	imageSparseInfo,
+													 const VkImage				imageSparse,
+													 const VkImage				imageTexels,
+													 const VkImage				imageResidency);
 
-	virtual VkDescriptorType		imageSparseDescType		(void) const = 0;
+	virtual VkDescriptorType	imageSparseDescType	(void) const = 0;
 };
 
 VkImageUsageFlags SparseShaderIntrinsicsInstanceStorage::imageOutputUsageFlags (void) const
@@ -439,8 +450,8 @@
 
 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
 	{
-		const tcu::UVec3  gridSize				= getShaderGridSize(m_imageType, m_imageSize, mipLevelNdx);
-		const tcu::UVec3  workGroupSize			= computeWorkGroupSize(gridSize);
+		const tcu::UVec3 gridSize				= getShaderGridSize(m_imageType, m_imageSize, mipLevelNdx);
+		const tcu::UVec3 workGroupSize			= computeWorkGroupSize(gridSize);
 		const tcu::UVec3 specializationData[2]	= { gridSize, workGroupSize };
 
 		const VkSpecializationInfo specializationInfo =
@@ -531,8 +542,8 @@
 												 const SpirVFunction		function,
 												 const ImageType			imageType,
 												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-	: SparseShaderIntrinsicsInstanceStorage (context, function, imageType, imageSize, format) {}
+												 const VkFormat				format)
+		: SparseShaderIntrinsicsInstanceStorage(context, function, imageType, imageSize, format) {}
 
 	VkImageUsageFlags	imageSparseUsageFlags	(void) const { return VK_IMAGE_USAGE_SAMPLED_BIT; }
 	VkDescriptorType	imageSparseDescType		(void) const { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; }
@@ -550,8 +561,8 @@
 												 const SpirVFunction		function,
 												 const ImageType			imageType,
 												 const tcu::UVec3&			imageSize,
-												 const tcu::TextureFormat&	format)
-	: SparseShaderIntrinsicsInstanceStorage (context, function, imageType, imageSize, format) {}
+												 const VkFormat				format)
+		: SparseShaderIntrinsicsInstanceStorage(context, function, imageType, imageSize, format) {}
 
 	VkImageUsageFlags	imageSparseUsageFlags	(void) const { return VK_IMAGE_USAGE_STORAGE_BIT; }
 	VkDescriptorType	imageSparseDescType		(void) const { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; }
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.hpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.hpp
index f85949d..ab9e477 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.hpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsStorage.hpp
@@ -33,70 +33,70 @@
 class SparseShaderIntrinsicsCaseStorage : public SparseShaderIntrinsicsCaseBase
 {
 public:
-	SparseShaderIntrinsicsCaseStorage		(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const SpirVFunction		function,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format)
-											 : SparseShaderIntrinsicsCaseBase (testCtx, name, function, imageType, imageSize, format) {}
+	SparseShaderIntrinsicsCaseStorage						(tcu::TestContext&		testCtx,
+															 const std::string&		name,
+															 const SpirVFunction	function,
+															 const ImageType		imageType,
+															 const tcu::UVec3&		imageSize,
+															 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseBase(testCtx, name, function, imageType, imageSize, format) {}
 
-	void				initPrograms		(vk::SourceCollections&		programCollection) const;
+	void				initPrograms						(vk::SourceCollections&	programCollection) const;
 
 	virtual std::string	getSparseImageTypeName				(void) const = 0;
 	virtual std::string	getUniformConstSparseImageTypeName	(void) const = 0;
 
-	virtual std::string	sparseImageOpString	(const std::string&			resultVariable,
-											 const std::string&			resultType,
-											 const std::string&			image,
-											 const std::string&			coord,
-											 const std::string&			mipLevel) const = 0;
+	virtual std::string	sparseImageOpString					(const std::string&		resultVariable,
+															 const std::string&		resultType,
+															 const std::string&		image,
+															 const std::string&		coord,
+															 const std::string&		mipLevel) const = 0;
 };
 
 class SparseCaseOpImageSparseFetch : public SparseShaderIntrinsicsCaseStorage
 {
 public:
-	SparseCaseOpImageSparseFetch			(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const SpirVFunction		function,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format)
-											 : SparseShaderIntrinsicsCaseStorage (testCtx, name, function, imageType, imageSize, format) {}
+	SparseCaseOpImageSparseFetch						(tcu::TestContext&		testCtx,
+														 const std::string&		name,
+														 const SpirVFunction	function,
+														 const ImageType		imageType,
+														 const tcu::UVec3&		imageSize,
+														 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseStorage (testCtx, name, function, imageType, imageSize, format) {}
 
-	TestInstance* createInstance			(Context& context) const;
+	TestInstance*	createInstance						(Context&				context) const;
 
-	std::string	getSparseImageTypeName				(void) const;
-	std::string	getUniformConstSparseImageTypeName	(void) const;
+	std::string		getSparseImageTypeName				(void) const;
+	std::string		getUniformConstSparseImageTypeName	(void) const;
 
-	std::string	sparseImageOpString			(const std::string&			resultVariable,
-											 const std::string&			resultType,
-											 const std::string&			image,
-											 const std::string&			coord,
-											 const std::string&			mipLevel) const;
+	std::string		sparseImageOpString					(const std::string&		resultVariable,
+														 const std::string&		resultType,
+														 const std::string&		image,
+														 const std::string&		coord,
+														 const std::string&		mipLevel) const;
 };
 
 class SparseCaseOpImageSparseRead : public SparseShaderIntrinsicsCaseStorage
 {
 public:
-	SparseCaseOpImageSparseRead				(tcu::TestContext&			testCtx,
-											 const std::string&			name,
-											 const SpirVFunction		function,
-											 const ImageType			imageType,
-											 const tcu::UVec3&			imageSize,
-											 const tcu::TextureFormat&	format)
-											 : SparseShaderIntrinsicsCaseStorage (testCtx, name, function, imageType, imageSize, format) {}
+	SparseCaseOpImageSparseRead							(tcu::TestContext&		testCtx,
+														 const std::string&		name,
+														 const SpirVFunction	function,
+														 const ImageType		imageType,
+														 const tcu::UVec3&		imageSize,
+														 const vk::VkFormat		format)
+		: SparseShaderIntrinsicsCaseStorage (testCtx, name, function, imageType, imageSize, format) {}
 
-	TestInstance* createInstance			(Context& context) const;
+	TestInstance*	createInstance						(Context&				context) const;
 
-	std::string	getSparseImageTypeName				(void) const;
-	std::string	getUniformConstSparseImageTypeName	(void) const;
+	std::string		getSparseImageTypeName				(void) const;
+	std::string		getUniformConstSparseImageTypeName	(void) const;
 
-	std::string	sparseImageOpString			(const std::string& resultVariable,
-											 const std::string& resultType,
-											 const std::string& image,
-											 const std::string& coord,
-											 const std::string& mipLevel) const;
+	std::string		sparseImageOpString					(const std::string&		resultVariable,
+														 const std::string&		resultType,
+														 const std::string&		image,
+														 const std::string&		coord,
+														 const std::string&		mipLevel) const;
 };
 
 } // sparse
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp
index ebb707c..815e9ae 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp
@@ -26,6 +26,7 @@
 #include "vkDeviceUtil.hpp"
 #include "vkTypeUtil.hpp"
 #include "tcuTextureUtil.hpp"
+#include "deStringUtil.hpp"
 
 #include <deMath.h>
 
@@ -36,6 +37,69 @@
 namespace sparse
 {
 
+std::vector<TestFormat> getTestFormats (const ImageType& imageType)
+{
+	std::vector<TestFormat> results =
+	{
+		{ VK_FORMAT_R32_SINT },				{ VK_FORMAT_R16_SINT },				{ VK_FORMAT_R8_SINT },
+		{ VK_FORMAT_R32_UINT },				{ VK_FORMAT_R16_UINT },				{ VK_FORMAT_R8_UINT },
+											{ VK_FORMAT_R16_UNORM },			{ VK_FORMAT_R8_UNORM },
+											{ VK_FORMAT_R16_SNORM },			{ VK_FORMAT_R8_SNORM },
+		{ VK_FORMAT_R32G32_SINT },			{ VK_FORMAT_R16G16_SINT },			{ VK_FORMAT_R8G8_SINT },
+		{ VK_FORMAT_R32G32_UINT },			{ VK_FORMAT_R16G16_UINT },			{ VK_FORMAT_R8G8_UINT },
+											{ VK_FORMAT_R16G16_UNORM },			{ VK_FORMAT_R8G8_UNORM },
+											{ VK_FORMAT_R16G16_SNORM },			{ VK_FORMAT_R8G8_SNORM },
+		{ VK_FORMAT_R32G32B32A32_SINT },	{ VK_FORMAT_R16G16B16A16_SINT },	{ VK_FORMAT_R8G8B8A8_SINT },
+		{ VK_FORMAT_R32G32B32A32_UINT },	{ VK_FORMAT_R16G16B16A16_UINT },	{ VK_FORMAT_R8G8B8A8_UINT },
+											{ VK_FORMAT_R16G16B16A16_UNORM },	{ VK_FORMAT_R8G8B8A8_UNORM },
+											{ VK_FORMAT_R16G16B16A16_SNORM },	{ VK_FORMAT_R8G8B8A8_SNORM }
+	};
+
+	if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
+	{
+		std::vector<TestFormat> ycbcrFormats =
+		{
+			{ VK_FORMAT_G8B8G8R8_422_UNORM },
+			{ VK_FORMAT_B8G8R8G8_422_UNORM },
+			{ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM },
+			{ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM },
+			{ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM },
+			{ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM },
+			{ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM },
+			{ VK_FORMAT_R10X6_UNORM_PACK16 },
+			{ VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
+			{ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 },
+			{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 },
+			{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 },
+			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 },
+			{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 },
+			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 },
+			{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 },
+			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 },
+			{ VK_FORMAT_R12X4_UNORM_PACK16 },
+			{ VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
+			{ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 },
+			{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 },
+			{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 },
+			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 },
+			{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 },
+			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 },
+			{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 },
+			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 },
+			{ VK_FORMAT_G16B16G16R16_422_UNORM },
+			{ VK_FORMAT_B16G16R16G16_422_UNORM },
+			{ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM },
+			{ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM },
+			{ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM },
+			{ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM },
+			{ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM }
+		};
+		std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results));
+	}
+
+	return results;
+}
+
 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
 {
 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
@@ -44,33 +108,33 @@
 
 	switch (imageType)
 	{
-	case IMAGE_TYPE_1D:
-		return tcu::UVec3(mipLevelX, 1u, 1u);
+		case IMAGE_TYPE_1D:
+			return tcu::UVec3(mipLevelX, 1u, 1u);
 
-	case IMAGE_TYPE_BUFFER:
-		return tcu::UVec3(imageSize.x(), 1u, 1u);
+		case IMAGE_TYPE_BUFFER:
+			return tcu::UVec3(imageSize.x(), 1u, 1u);
 
-	case IMAGE_TYPE_1D_ARRAY:
-		return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
+		case IMAGE_TYPE_1D_ARRAY:
+			return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
 
-	case IMAGE_TYPE_2D:
-		return tcu::UVec3(mipLevelX, mipLevelY, 1u);
+		case IMAGE_TYPE_2D:
+			return tcu::UVec3(mipLevelX, mipLevelY, 1u);
 
-	case IMAGE_TYPE_2D_ARRAY:
-		return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
+		case IMAGE_TYPE_2D_ARRAY:
+			return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
 
-	case IMAGE_TYPE_3D:
-		return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
+		case IMAGE_TYPE_3D:
+			return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
 
-	case IMAGE_TYPE_CUBE:
-		return tcu::UVec3(mipLevelX, mipLevelY, 6u);
+		case IMAGE_TYPE_CUBE:
+			return tcu::UVec3(mipLevelX, mipLevelY, 6u);
 
-	case IMAGE_TYPE_CUBE_ARRAY:
-		return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
+		case IMAGE_TYPE_CUBE_ARRAY:
+			return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
 
-	default:
-		DE_FATAL("Unknown image type");
-		return tcu::UVec3(1u, 1u, 1u);
+		default:
+			DE_FATAL("Unknown image type");
+			return tcu::UVec3(1u, 1u, 1u);
 	}
 }
 
@@ -78,23 +142,23 @@
 {
 	switch (imageType)
 	{
-	case IMAGE_TYPE_1D:
-	case IMAGE_TYPE_1D_ARRAY:
-	case IMAGE_TYPE_BUFFER:
-		return tcu::UVec3(imageSize.x(), 1u, 1u);
+		case IMAGE_TYPE_1D:
+		case IMAGE_TYPE_1D_ARRAY:
+		case IMAGE_TYPE_BUFFER:
+			return tcu::UVec3(imageSize.x(), 1u, 1u);
 
-	case IMAGE_TYPE_2D:
-	case IMAGE_TYPE_2D_ARRAY:
-	case IMAGE_TYPE_CUBE:
-	case IMAGE_TYPE_CUBE_ARRAY:
-		return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
+		case IMAGE_TYPE_2D:
+		case IMAGE_TYPE_2D_ARRAY:
+		case IMAGE_TYPE_CUBE:
+		case IMAGE_TYPE_CUBE_ARRAY:
+			return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
 
-	case IMAGE_TYPE_3D:
-		return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
+		case IMAGE_TYPE_3D:
+			return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
 
-	default:
-		DE_FATAL("Unknown image type");
-		return tcu::UVec3(1u, 1u, 1u);
+		default:
+			DE_FATAL("Unknown image type");
+			return tcu::UVec3(1u, 1u, 1u);
 	}
 }
 
@@ -102,25 +166,25 @@
 {
 	switch (imageType)
 	{
-	case IMAGE_TYPE_1D:
-	case IMAGE_TYPE_2D:
-	case IMAGE_TYPE_3D:
-	case IMAGE_TYPE_BUFFER:
-		return 1u;
+		case IMAGE_TYPE_1D:
+		case IMAGE_TYPE_2D:
+		case IMAGE_TYPE_3D:
+		case IMAGE_TYPE_BUFFER:
+			return 1u;
 
-	case IMAGE_TYPE_1D_ARRAY:
-	case IMAGE_TYPE_2D_ARRAY:
-		return imageSize.z();
+		case IMAGE_TYPE_1D_ARRAY:
+		case IMAGE_TYPE_2D_ARRAY:
+			return imageSize.z();
 
-	case IMAGE_TYPE_CUBE:
-		return 6u;
+		case IMAGE_TYPE_CUBE:
+			return 6u;
 
-	case IMAGE_TYPE_CUBE_ARRAY:
-		return imageSize.z() * 6u;
+		case IMAGE_TYPE_CUBE_ARRAY:
+			return imageSize.z() * 6u;
 
-	default:
-		DE_FATAL("Unknown image type");
-		return 0u;
+		default:
+			DE_FATAL("Unknown image type");
+			return 0u;
 	}
 }
 
@@ -135,23 +199,23 @@
 {
 	switch (imageType)
 	{
-	case IMAGE_TYPE_1D:
-	case IMAGE_TYPE_BUFFER:
-		return 1u;
+		case IMAGE_TYPE_1D:
+		case IMAGE_TYPE_BUFFER:
+			return 1u;
 
-	case IMAGE_TYPE_1D_ARRAY:
-	case IMAGE_TYPE_2D:
-		return 2u;
+		case IMAGE_TYPE_1D_ARRAY:
+		case IMAGE_TYPE_2D:
+			return 2u;
 
-	case IMAGE_TYPE_2D_ARRAY:
-	case IMAGE_TYPE_CUBE:
-	case IMAGE_TYPE_CUBE_ARRAY:
-	case IMAGE_TYPE_3D:
-		return 3u;
+		case IMAGE_TYPE_2D_ARRAY:
+		case IMAGE_TYPE_CUBE:
+		case IMAGE_TYPE_CUBE_ARRAY:
+		case IMAGE_TYPE_3D:
+			return 3u;
 
-	default:
-		DE_FATAL("Unknown image type");
-		return 0u;
+		default:
+			DE_FATAL("Unknown image type");
+			return 0u;
 	}
 }
 
@@ -159,23 +223,23 @@
 {
 	switch (imageType)
 	{
-	case IMAGE_TYPE_1D:
-	case IMAGE_TYPE_BUFFER:
-	case IMAGE_TYPE_1D_ARRAY:
-		return 1u;
+		case IMAGE_TYPE_1D:
+		case IMAGE_TYPE_BUFFER:
+		case IMAGE_TYPE_1D_ARRAY:
+			return 1u;
 
-	case IMAGE_TYPE_2D:
-	case IMAGE_TYPE_2D_ARRAY:
-	case IMAGE_TYPE_CUBE:
-	case IMAGE_TYPE_CUBE_ARRAY:
-		return 2u;
+		case IMAGE_TYPE_2D:
+		case IMAGE_TYPE_2D_ARRAY:
+		case IMAGE_TYPE_CUBE:
+		case IMAGE_TYPE_CUBE_ARRAY:
+			return 2u;
 
-	case IMAGE_TYPE_3D:
-		return 3u;
+		case IMAGE_TYPE_3D:
+			return 3u;
 
-	default:
-		DE_FATAL("Unknown image type");
-		return 0u;
+		default:
+			DE_FATAL("Unknown image type");
+			return 0u;
 	}
 }
 
@@ -356,7 +420,7 @@
 			return VK_IMAGE_TYPE_3D;
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected image type");
 			return VK_IMAGE_TYPE_LAST;
 	}
 }
@@ -374,7 +438,7 @@
 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected image type");
 			return VK_IMAGE_VIEW_TYPE_LAST;
 	}
 }
@@ -393,7 +457,7 @@
 		case IMAGE_TYPE_BUFFER:		return "buffer";
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected image type");
 			return "";
 	}
 }
@@ -416,12 +480,52 @@
 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected image type");
 	}
 
 	return formatPart + "image" + imageTypePart;
 }
 
+std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
+{
+	std::string	formatPart;
+	std::string	imageTypePart;
+
+	// all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			formatPart = "i";
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			formatPart = "u";
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			break;
+
+		default:
+			DE_FATAL("Unexpected channel type");
+	}
+
+	switch (imageType)
+	{
+		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
+		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
+		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
+		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
+		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
+		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
+		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
+		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
+
+		default:
+			DE_FATAL("Unexpected image type");
+	}
+
+	return formatPart + "image" + imageTypePart;
+}
 
 std::string getShaderImageDataType(const tcu::TextureFormat& format)
 {
@@ -431,14 +535,33 @@
 			return "uvec4";
 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
 			return "ivec4";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
 			return "vec4";
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected channel type");
 			return "";
 	}
 }
 
+std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
+{
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return "uvec4";
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return "ivec4";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return "vec4";
+		default:
+			DE_FATAL("Unexpected channel type");
+			return "";
+	}
+}
 
 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
 {
@@ -453,7 +576,7 @@
 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected channel order");
 			orderPart = DE_NULL;
 	}
 
@@ -477,13 +600,170 @@
 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
 
 		default:
-			DE_ASSERT(false);
+			DE_FATAL("Unexpected channel type");
 			typePart = DE_NULL;
 	}
 
 	return std::string() + orderPart + typePart;
 }
 
+std::string getShaderImageFormatQualifier (VkFormat format)
+{
+	switch (format)
+	{
+		case VK_FORMAT_R8_SINT:										return "r8i";
+		case VK_FORMAT_R16_SINT:									return "r16i";
+		case VK_FORMAT_R32_SINT:									return "r32i";
+		case VK_FORMAT_R8_UINT:										return "r8ui";
+		case VK_FORMAT_R16_UINT:									return "r16ui";
+		case VK_FORMAT_R32_UINT:									return "r32ui";
+		case VK_FORMAT_R8_SNORM:									return "r8_snorm";
+		case VK_FORMAT_R16_SNORM:									return "r16_snorm";
+		case VK_FORMAT_R8_UNORM:									return "r8";
+		case VK_FORMAT_R16_UNORM:									return "r16";
+
+		case VK_FORMAT_R8G8_SINT:									return "rg8i";
+		case VK_FORMAT_R16G16_SINT:									return "rg16i";
+		case VK_FORMAT_R32G32_SINT:									return "rg32i";
+		case VK_FORMAT_R8G8_UINT:									return "rg8ui";
+		case VK_FORMAT_R16G16_UINT:									return "rg16ui";
+		case VK_FORMAT_R32G32_UINT:									return "rg32ui";
+		case VK_FORMAT_R8G8_SNORM:									return "rg8_snorm";
+		case VK_FORMAT_R16G16_SNORM:								return "rg16_snorm";
+		case VK_FORMAT_R8G8_UNORM:									return "rg8";
+		case VK_FORMAT_R16G16_UNORM:								return "rg16";
+
+		case VK_FORMAT_R8G8B8A8_SINT:								return "rgba8i";
+		case VK_FORMAT_R16G16B16A16_SINT:							return "rgba16i";
+		case VK_FORMAT_R32G32B32A32_SINT:							return "rgba32i";
+		case VK_FORMAT_R8G8B8A8_UINT:								return "rgba8ui";
+		case VK_FORMAT_R16G16B16A16_UINT:							return "rgba16ui";
+		case VK_FORMAT_R32G32B32A32_UINT:							return "rgba32ui";
+		case VK_FORMAT_R8G8B8A8_SNORM:								return "rgba8_snorm";
+		case VK_FORMAT_R16G16B16A16_SNORM:							return "rgba16_snorm";
+		case VK_FORMAT_R8G8B8A8_UNORM:								return "rgba8";
+		case VK_FORMAT_R16G16B16A16_UNORM:							return "rgba16";
+
+		case VK_FORMAT_G8B8G8R8_422_UNORM:							return "rgba8";
+		case VK_FORMAT_B8G8R8G8_422_UNORM:							return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:					return "rgba8";
+		case VK_FORMAT_R10X6_UNORM_PACK16:							return "r16";
+		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:					return "rg16";
+		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:			return "rgba16";
+		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_R12X4_UNORM_PACK16:							return "r16";
+		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:					return "rg16";
+		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:			return "rgba16";
+		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G16B16G16R16_422_UNORM:						return "rgba16";
+		case VK_FORMAT_B16G16R16G16_422_UNORM:						return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:				return "rgba16";
+		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:					return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:				return "rgba16";
+		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:					return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:				return "rgba16";
+
+		default:
+			DE_FATAL("Unexpected texture format");
+			return "error";
+	}
+}
+
+std::string getImageFormatID (VkFormat format)
+{
+	switch (format)
+	{
+		case VK_FORMAT_R8_SINT:				return "r8i";
+		case VK_FORMAT_R16_SINT:			return "r16i";
+		case VK_FORMAT_R32_SINT:			return "r32i";
+		case VK_FORMAT_R8_UINT:				return "r8ui";
+		case VK_FORMAT_R16_UINT:			return "r16ui";
+		case VK_FORMAT_R32_UINT:			return "r32ui";
+		case VK_FORMAT_R8_SNORM:			return "r8_snorm";
+		case VK_FORMAT_R16_SNORM:			return "r16_snorm";
+		case VK_FORMAT_R8_UNORM:			return "r8";
+		case VK_FORMAT_R16_UNORM:			return "r16";
+
+		case VK_FORMAT_R8G8_SINT:			return "rg8i";
+		case VK_FORMAT_R16G16_SINT:			return "rg16i";
+		case VK_FORMAT_R32G32_SINT:			return "rg32i";
+		case VK_FORMAT_R8G8_UINT:			return "rg8ui";
+		case VK_FORMAT_R16G16_UINT:			return "rg16ui";
+		case VK_FORMAT_R32G32_UINT:			return "rg32ui";
+		case VK_FORMAT_R8G8_SNORM:			return "rg8_snorm";
+		case VK_FORMAT_R16G16_SNORM:		return "rg16_snorm";
+		case VK_FORMAT_R8G8_UNORM:			return "rg8";
+		case VK_FORMAT_R16G16_UNORM:		return "rg16";
+
+		case VK_FORMAT_R8G8B8A8_SINT:		return "rgba8i";
+		case VK_FORMAT_R16G16B16A16_SINT:	return "rgba16i";
+		case VK_FORMAT_R32G32B32A32_SINT:	return "rgba32i";
+		case VK_FORMAT_R8G8B8A8_UINT:		return "rgba8ui";
+		case VK_FORMAT_R16G16B16A16_UINT:	return "rgba16ui";
+		case VK_FORMAT_R32G32B32A32_UINT:	return "rgba32ui";
+		case VK_FORMAT_R8G8B8A8_SNORM:		return "rgba8_snorm";
+		case VK_FORMAT_R16G16B16A16_SNORM:	return "rgba16_snorm";
+		case VK_FORMAT_R8G8B8A8_UNORM:		return "rgba8";
+		case VK_FORMAT_R16G16B16A16_UNORM:	return "rgba16";
+
+		case VK_FORMAT_G8B8G8R8_422_UNORM:
+		case VK_FORMAT_B8G8R8G8_422_UNORM:
+		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
+		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
+		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
+		case VK_FORMAT_R10X6_UNORM_PACK16:
+		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
+		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
+		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
+		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
+		case VK_FORMAT_R12X4_UNORM_PACK16:
+		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
+		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
+		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
+		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
+		case VK_FORMAT_G16B16G16R16_422_UNORM:
+		case VK_FORMAT_B16G16R16G16_422_UNORM:
+		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
+		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
+		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
+		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
+		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
+			return de::toLower(std::string(getFormatName(format)).substr(10));
+
+		default:
+			DE_FATAL("Unexpected texture format");
+			return "error";
+	}
+}
+
 std::string getShaderImageCoordinates	(const ImageType	imageType,
 										 const std::string&	x,
 										 const std::string&	xy,
@@ -506,18 +786,11 @@
 			return xyz;
 
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected image type");
 			return "";
 	}
 }
 
-deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
-{
-	const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
-
-	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
-}
-
 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
 {
 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
@@ -534,6 +807,21 @@
 	return imageSizeInBytes;
 }
 
+deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
+{
+	return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
+}
+
+deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
+{
+	deUint32 imageSizeInBytes = 0;
+
+	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
+		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
+
+	return imageSizeInBytes;
+}
+
 VkSparseImageMemoryBind	makeSparseImageMemoryBind  (const DeviceInterface&			vk,
 													const VkDevice					device,
 													const VkDeviceSize				allocationSize,
@@ -661,7 +949,7 @@
 		case VK_IMAGE_TYPE_3D:
 			return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
 		default:
-			DE_ASSERT(0);
+			DE_FATAL("Unexpected image type");
 			return false;
 	};
 }
@@ -698,5 +986,28 @@
 	return NO_MATCH_FOUND;
 }
 
+vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
+{
+	DE_ASSERT(planeNdx < formatInfo.numPlanes);
+	vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
+
+	// redirect result for some of the YCbCr image formats
+	static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
+	{
+		{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
+		{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_G16B16G16R16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B8G8R8G8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
+		{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B16G16R16G16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	}
+	};
+	auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
+	if (it != std::end(ycbcrFormats))
+		result = it->second;
+	return result;
+}
+
 } // sparse
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp
index dce403c..0cf8572 100644
--- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp
+++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp
@@ -67,10 +67,23 @@
 
 enum
 {
-	BUFFER_IMAGE_COPY_OFFSET_GRANULARITY	= 4u,
 	NO_MATCH_FOUND							= ~((deUint32)0),	//!< no matching index
 };
 
+struct TestFormat
+{
+	vk::VkFormat	format;
+};
+
+struct TestImageParameters
+{
+	ImageType				imageType;
+	std::vector<tcu::UVec3>	imageSizes;
+	std::vector<TestFormat>	formats;
+};
+
+std::vector<TestFormat>			getTestFormats						(const ImageType& imageType);
+
 vk::VkImageType					mapImageType						(const ImageType					imageType);
 
 vk::VkImageViewType				mapImageViewType					(const ImageType					imageType);
@@ -80,10 +93,19 @@
 std::string						getShaderImageType					(const tcu::TextureFormat&			format,
 																	 const ImageType					imageType);
 
+std::string						getShaderImageType					(const vk::PlanarFormatDescription& description,
+																	 const ImageType imageType);
+
 std::string						getShaderImageDataType				(const tcu::TextureFormat&			format);
 
+std::string						getShaderImageDataType				(const vk::PlanarFormatDescription& description);
+
 std::string						getShaderImageFormatQualifier		(const tcu::TextureFormat&			format);
 
+std::string						getShaderImageFormatQualifier		(vk::VkFormat						format);
+
+std::string						getImageFormatID					(vk::VkFormat						format);
+
 std::string						getShaderImageCoordinates			(const ImageType					imageType,
 																	 const std::string&					x,
 																	 const std::string&					xy,
@@ -118,9 +140,6 @@
 																	 const ImageType					imageType,
 																	 const tcu::UVec3&					imageSize);
 
-deUint32						getImageMaxMipLevels				(const vk::VkImageFormatProperties& imageFormatProperties,
-																	 const vk::VkExtent3D&				extent);
-
 deUint32						getImageMipLevelSizeInBytes			(const vk::VkExtent3D&				baseExtents,
 																	 const deUint32						layersCount,
 																	 const tcu::TextureFormat&			format,
@@ -133,6 +152,20 @@
 																	 const deUint32						mipmapLevelsCount		= 1u,
 																	 const deUint32						mipmapMemoryAlignment	= 1u);
 
+deUint32						getImageMipLevelSizeInBytes			(const vk::VkExtent3D&				baseExtents,
+																	 const deUint32						layersCount,
+																	 const vk::PlanarFormatDescription&	formatDescription,
+																	 const deUint32						planeNdx,
+																	 const deUint32						mipmapLevel,
+																	 const deUint32						mipmapMemoryAlignment	= 1u);
+
+deUint32						getImageSizeInBytes					(const vk::VkExtent3D&				baseExtents,
+																	 const deUint32						layersCount,
+																	 const vk::PlanarFormatDescription&	formatDescription,
+																	 const deUint32						planeNdx,
+																	 const deUint32						mipmapLevelsCount		=1u,
+																	 const deUint32						mipmapMemoryAlignment	=1u);
+
 vk::Move<vk::VkPipeline>		makeComputePipeline					(const vk::DeviceInterface&			vk,
 																	 const vk::VkDevice					device,
 																	 const vk::VkPipelineLayout			pipelineLayout,
@@ -209,6 +242,9 @@
 deUint32						getSparseAspectRequirementsIndex	(const std::vector<vk::VkSparseImageMemoryRequirements>&	requirements,
 																	 const vk::VkImageAspectFlags								aspectFlags);
 
+vk::VkFormat					getPlaneCompatibleFormatForWriting	(const vk::PlanarFormatDescription&	formatInfo,
+																	 deUint32							planeNdx);
+
 template<typename T>
 inline de::SharedPtr<vk::Unique<T> > makeVkSharedPtr (vk::Move<T> vkMove)
 {
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt b/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
index 1b77886..78d039d 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
@@ -61,6 +61,8 @@
 	vktSpvAsmWorkgroupMemoryTests.hpp
 	vktSpvAsmPtrAccessChainTests.cpp
 	vktSpvAsmPtrAccessChainTests.hpp
+	vktSpvAsmFloatControlsExtensionlessTests.cpp
+	vktSpvAsmFloatControlsExtensionlessTests.hpp
 	)
 
 set(DEQP_VK_SPIRV_ASSEMBLY_LIBS
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm64bitCompareTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm64bitCompareTests.cpp
index 512f68b..ec073bd 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm64bitCompareTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm64bitCompareTests.cpp
@@ -24,6 +24,7 @@
 
 #include "vktSpvAsm64bitCompareTests.hpp"
 #include "vktTestGroupUtil.hpp"
+#include "vktSpvAsmUtils.hpp"
 #include "vkDefs.hpp"
 #include "vktTestCase.hpp"
 #include "vkQueryUtil.hpp"
@@ -203,6 +204,7 @@
 	const CompareOperation<T>&	operation;
 	vk::VkShaderStageFlagBits	stage;
 	const OperandsVector<T>&	operands;
+	bool						requireNanPreserve;
 };
 
 // Shader template for the compute stage using single scalars.
@@ -225,9 +227,12 @@
 const tcu::StringTemplate CompShaderSingle(R"(
                         OpCapability Shader
                         ${OPCAPABILITY}
+                        ${NANCAP}
+                        ${NANEXT}
                    %1 = OpExtInstImport "GLSL.std.450"
                         OpMemoryModel Logical GLSL450
                         OpEntryPoint GLCompute %main "main"
+                        ${NANMODE}
                         OpExecutionMode %main LocalSize 1 1 1
                         OpName %main "main"
                         OpName %i "i"
@@ -334,9 +339,12 @@
 const tcu::StringTemplate CompShaderVector(R"(
                           OpCapability Shader
                           ${OPCAPABILITY}
+                          ${NANCAP}
+                          ${NANEXT}
                      %1 = OpExtInstImport "GLSL.std.450"
                           OpMemoryModel Logical GLSL450
                           OpEntryPoint GLCompute %main "main"
+                          ${NANMODE}
                           OpExecutionMode %main LocalSize 1 1 1
                           OpName %main "main"
                           OpName %i "i"
@@ -450,9 +458,12 @@
 const tcu::StringTemplate VertShaderSingle(R"(
                             OpCapability Shader
                             ${OPCAPABILITY}
+                            ${NANCAP}
+                            ${NANEXT}
                        %1 = OpExtInstImport "GLSL.std.450"
                             OpMemoryModel Logical GLSL450
                             OpEntryPoint Vertex %main "main" %_
+                            ${NANMODE}
                             OpName %main "main"
                             OpName %gl_PerVertex "gl_PerVertex"
                             OpMemberName %gl_PerVertex 0 "gl_Position"
@@ -587,9 +598,12 @@
 const tcu::StringTemplate VertShaderVector(R"(
                             OpCapability Shader
                             ${OPCAPABILITY}
+                            ${NANCAP}
+                            ${NANEXT}
                        %1 = OpExtInstImport "GLSL.std.450"
                             OpMemoryModel Logical GLSL450
                             OpEntryPoint Vertex %main "main" %_
+                            ${NANMODE}
                             OpName %main "main"
                             OpName %gl_PerVertex "gl_PerVertex"
                             OpMemberName %gl_PerVertex 0 "gl_Position"
@@ -739,9 +753,12 @@
 const tcu::StringTemplate FragShaderSingle(R"(
                         OpCapability Shader
                         ${OPCAPABILITY}
+                        ${NANCAP}
+                        ${NANEXT}
                    %1 = OpExtInstImport "GLSL.std.450"
                         OpMemoryModel Logical GLSL450
                         OpEntryPoint Fragment %main "main"
+                        ${NANMODE}
                         OpExecutionMode %main OriginUpperLeft
                         OpSource GLSL 430
                         OpName %main "main"
@@ -849,9 +866,12 @@
 const tcu::StringTemplate FragShaderVector(R"(
                           OpCapability Shader
                           ${OPCAPABILITY}
+                          ${NANCAP}
+                          ${NANEXT}
                      %1 = OpExtInstImport "GLSL.std.450"
                           OpMemoryModel Logical GLSL450
                           OpEntryPoint Fragment %main "main"
+                          ${NANMODE}
                           OpExecutionMode %main OriginUpperLeft
                           OpName %main "main"
                           OpName %i "i"
@@ -972,6 +992,11 @@
 	// Same.
 	template <class T>
 	static std::string getOpType();
+
+	// Return the capabilities, extensions and execution modes for NaN preservation.
+	static std::string getNanCapability	(bool preserve);
+	static std::string getNanExtension	(bool preserve);
+	static std::string getNanExeMode	(bool preserve);
 };
 
 template <> std::string SpirvTemplateManager::getOpCapability<double>()		{ return "OpCapability Float64";	}
@@ -982,6 +1007,21 @@
 template <> std::string SpirvTemplateManager::getOpType<deInt64>()	{ return "OpTypeInt 64 1";	}
 template <> std::string SpirvTemplateManager::getOpType<deUint64>()	{ return "OpTypeInt 64 0";	}
 
+std::string SpirvTemplateManager::getNanCapability (bool preserve)
+{
+	return (preserve ? "OpCapability SignedZeroInfNanPreserve" : "");
+}
+
+std::string SpirvTemplateManager::getNanExtension (bool preserve)
+{
+	return (preserve ? "OpExtension \"SPV_KHR_float_controls\"" : "");
+}
+
+std::string SpirvTemplateManager::getNanExeMode (bool preserve)
+{
+	return (preserve ? "OpExecutionMode %main SignedZeroInfNanPreserve 64" : "");
+}
+
 struct BufferWithMemory
 {
 	vk::Move<vk::VkBuffer>		buffer;
@@ -1069,12 +1109,10 @@
 	{	-6.0,	-5.0	},
 	{	 6.0,	 5.0	},
 	{	 0.0,	 1.0	},
-#if 0
 	{	 1.0,	 0.0	},
 	{	 0.0,	 NAN	},
 	{	 NAN,	 0.0	},
 	{	 NAN,	 NAN	},
-#endif
 };
 
 const OperandsVector<deInt64>	INT64_OPERANDS	=
@@ -1138,6 +1176,18 @@
 {
 }
 
+template<class T>
+bool genericIsNan (T)
+{
+	return false;
+}
+
+template<>
+bool genericIsNan<double> (double value)
+{
+	return std::isnan(value);
+}
+
 template <class T>
 tcu::TestStatus T64bitCompareTestInstance<T>::iterate (void)
 {
@@ -1584,7 +1634,7 @@
 	for (size_t i = 0; i < m_numOperations; ++i)
 	{
 		int expected = static_cast<int>(m_params.operation.run(m_params.operands[i].first, m_params.operands[i].second));
-		if (results[i] != expected)
+		if (results[i] != expected && (m_params.requireNanPreserve || (!genericIsNan<T>(m_params.operands[i].first) && !genericIsNan<T>(m_params.operands[i].second))))
 		{
 			std::ostringstream msg;
 			msg << "Invalid result found in position " << i << ": expected " << expected << " and found " << results[i];
@@ -1670,6 +1720,13 @@
 	default:
 		DE_ASSERT(DE_NULL == "Invalid shader stage specified");
 	}
+
+	ExtensionFloatControlsFeatures fcFeatures;
+	deMemset(&fcFeatures, 0, sizeof(fcFeatures));
+	fcFeatures.shaderSignedZeroInfNanPreserveFloat64 = VK_TRUE;
+
+	if (m_params.requireNanPreserve && !isFloatControlsFeaturesSupported(context, fcFeatures))
+		TCU_THROW(NotSupportedError, "NaN preservation not supported");
 }
 
 template <class T>
@@ -1684,6 +1741,9 @@
 	replacements["OPNAME"]			= m_params.operation.spirvName();
 	replacements["OPCAPABILITY"]	= SpirvTemplateManager::getOpCapability<T>();
 	replacements["OPTYPE"]			= SpirvTemplateManager::getOpType<T>();
+	replacements["NANCAP"]			= SpirvTemplateManager::getNanCapability(m_params.requireNanPreserve);
+	replacements["NANEXT"]			= SpirvTemplateManager::getNanExtension(m_params.requireNanPreserve);
+	replacements["NANMODE"]			= SpirvTemplateManager::getNanExeMode(m_params.requireNanPreserve);
 
 	static const std::map<vk::VkShaderStageFlagBits, std::string>	sourceNames			=
 	{
@@ -1706,7 +1766,13 @@
 	return new T64bitCompareTestInstance<T>(ctx, m_params);
 }
 
-const std::map<DataType, std::string> dataTypeName =
+const std::map<bool, std::string>		requireNanName =
+{
+	std::make_pair( false,	"nonan"		),
+	std::make_pair( true,	"withnan"	),
+};
+
+const std::map<DataType, std::string>	dataTypeName =
 {
 	std::make_pair(DATA_TYPE_SINGLE, "single"),
 	std::make_pair(DATA_TYPE_VECTOR, "vector"),
@@ -1736,10 +1802,11 @@
 
 	for (const auto&	stageNamePair	: *stageNames)
 	for (const auto&	typeNamePair	: dataTypeName)
+	for (const auto&	requireNanPair	: requireNanName)
 	for (const auto		opPtr			: operationList)
 	{
-		TestParameters<double>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, DOUBLE_OPERANDS };
-		std::string				testName	= stageNamePair.second + "_" + de::toLower(opPtr->spirvName()) + "_" + typeNamePair.second;
+		TestParameters<double>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, DOUBLE_OPERANDS, requireNanPair.first };
+		std::string				testName	= stageNamePair.second + "_" + de::toLower(opPtr->spirvName()) + "_" + requireNanPair.second + "_" + typeNamePair.second;
 		tests->addChild(new T64bitCompareTest<double>(tests->getTestContext(), testName, "", params));
 	}
 }
@@ -1760,7 +1827,7 @@
 	for (const auto&	typeNamePair	: dataTypeName)
 	for (const auto		opPtr			: operationList)
 	{
-		TestParameters<deInt64>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, INT64_OPERANDS };
+		TestParameters<deInt64>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, INT64_OPERANDS, false };
 		std::string				testName	= stageNamePair.second + "_" + de::toLower(opPtr->spirvName()) + "_" + typeNamePair.second;
 		tests->addChild(new T64bitCompareTest<deInt64>(tests->getTestContext(), testName, "", params));
 	}
@@ -1782,7 +1849,7 @@
 	for (const auto&	typeNamePair	: dataTypeName)
 	for (const auto		opPtr			: operationList)
 	{
-		TestParameters<deUint64>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, UINT64_OPERANDS };
+		TestParameters<deUint64>	params		= { typeNamePair.first, *opPtr, stageNamePair.first, UINT64_OPERANDS, false };
 		std::string					testName	= stageNamePair.second + "_" + de::toLower(opPtr->spirvName()) + "_" + typeNamePair.second;
 		tests->addChild(new T64bitCompareTest<deUint64>(tests->getTestContext(), testName, "", params));
 	}
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
index 74e0a5b..bfe5d71 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
@@ -73,7 +73,7 @@
 	VkBufferUsageFlags			usageFlags			= (VkBufferUsageFlags)0u;
 
 	if (physStorageBuffer)
-		usageFlags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
+		usageFlags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
 
 	switch (dtype)
 	{
@@ -423,11 +423,8 @@
 	vector<VkDescriptorType>			descriptorTypes;
 
 	// Check all required extensions are supported
-	for (std::vector<std::string>::const_iterator i = m_shaderSpec.extensions.begin(); i != m_shaderSpec.extensions.end(); ++i)
-	{
-		if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), *i))
-			TCU_THROW(NotSupportedError, (std::string("Extension not supported: ") + *i).c_str());
-	}
+	for (const auto& ext : m_shaderSpec.extensions)
+		m_context.requireDeviceFunctionality(ext);
 
 	// Core features
 	{
@@ -769,9 +766,9 @@
 	{
 		const bool useKHR = m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address");
 
-		VkBufferDeviceAddressInfoKHR info =
+		VkBufferDeviceAddressInfo info =
 		{
-			VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType	sType;
+			VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,		// VkStructureType	sType;
 			DE_NULL,											// const void*		pNext;
 			0,													// VkBuffer			buffer
 		};
@@ -781,7 +778,7 @@
 			info.buffer = **inputBuffers[inputNdx];
 			VkDeviceAddress addr;
 			if (useKHR)
-				addr = vkdi.getBufferDeviceAddressKHR(device, &info);
+				addr = vkdi.getBufferDeviceAddress(device, &info);
 			else
 				addr = vkdi.getBufferDeviceAddressEXT(device, &info);
 			gpuAddrs.push_back(addr);
@@ -791,7 +788,7 @@
 			info.buffer = **outputBuffers[outputNdx];
 			VkDeviceAddress addr;
 			if (useKHR)
-				addr = vkdi.getBufferDeviceAddressKHR(device, &info);
+				addr = vkdi.getBufferDeviceAddress(device, &info);
 			else
 				addr = vkdi.getBufferDeviceAddressEXT(device, &info);
 			gpuAddrs.push_back(addr);
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.cpp
index 2d06d96..794b15f 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.cpp
@@ -60,14 +60,18 @@
 }
 }
 
-std::string getComputeAsmShaderPreamble (const std::string& capabilities, const std::string& extensions, const std::string& exeModes, const std::string& extraEntryPoints)
+std::string getComputeAsmShaderPreamble (const std::string& capabilities,
+										 const std::string& extensions,
+										 const std::string& exeModes,
+										 const std::string& extraEntryPoints,
+										 const std::string& extraEntryPointsArguments)
 {
 	return
 		std::string("OpCapability Shader\n") +
 		capabilities +
 		extensions +
 		"OpMemoryModel Logical GLSL450\n"
-		"OpEntryPoint GLCompute %main \"main\" %id\n" +
+		"OpEntryPoint GLCompute %main \"main\" %id " + extraEntryPointsArguments + "\n" +
 		extraEntryPoints +
 		"OpExecutionMode %main LocalSize 1 1 1\n" +
 		exeModes;
@@ -107,19 +111,19 @@
 		"%i64arr    = OpTypeRuntimeArray %i64\n";
 }
 
-const char* getComputeAsmInputOutputBuffer (void)
-{
-	return
+std::string getComputeAsmInputOutputBuffer (std::string blockStorageClass)
+{	// Uniform | StorageBuffer
+	return std::string() +
 		"%buf     = OpTypeStruct %f32arr\n"
-		"%bufptr  = OpTypePointer Uniform %buf\n"
-		"%indata    = OpVariable %bufptr Uniform\n"
-		"%outdata   = OpVariable %bufptr Uniform\n";
+		"%bufptr  = OpTypePointer " + blockStorageClass + " %buf\n"
+		"%indata    = OpVariable %bufptr " + blockStorageClass + "\n"
+		"%outdata   = OpVariable %bufptr " + blockStorageClass + "\n";
 }
 
-const char* getComputeAsmInputOutputBufferTraits (void)
-{
-	return
-		"OpDecorate %buf BufferBlock\n"
+std::string getComputeAsmInputOutputBufferTraits (std::string blockStorageClass)
+{	// BufferBlock | Block
+	return std::string() +
+		"OpDecorate %buf " + blockStorageClass + "\n"
 		"OpDecorate %indata DescriptorSet 0\n"
 		"OpDecorate %indata Binding 0\n"
 		"OpDecorate %outdata DescriptorSet 0\n"
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
index 229413e..18f2b63 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderTestUtil.hpp
@@ -353,6 +353,7 @@
 	SpirvVersion							spirvVersion;
 	bool									coherentMemory;
 	bool									usesPhysStorageBuffer;
+	bool									spirvVersion14;
 
 											ComputeShaderSpec (void)
 												: entryPoint					("main")
@@ -365,6 +366,7 @@
 												, spirvVersion					(SPIRV_VERSION_1_0)
 												, coherentMemory				(false)
 												, usesPhysStorageBuffer			(false)
+												, spirvVersion14				(false)
 											{}
 };
 
@@ -372,7 +374,11 @@
  * \brief Helper functions for SPIR-V assembly shared by various tests
  *//*--------------------------------------------------------------------*/
 
-std::string getComputeAsmShaderPreamble				(const std::string& capabilities = "", const std::string& extensions = "", const std::string& exeModes = "", const std::string& extraEntryPoints = "");
+std::string getComputeAsmShaderPreamble				(const std::string& capabilities				= "",
+													 const std::string& extensions					= "",
+													 const std::string& exeModes					= "",
+													 const std::string& extraEntryPoints			= "",
+													 const std::string& extraEntryPointsArguments	= "");
 const char* getComputeAsmShaderPreambleWithoutLocalSize         (void);
 std::string getComputeAsmCommonTypes				(std::string blockStorageClass = "Uniform");
 const char*	getComputeAsmCommonInt64Types			(void);
@@ -381,13 +387,13 @@
  * Declares two uniform variables (indata, outdata) of type
  * "struct { float[] }". Depends on type "f32arr" (for "float[]").
  *//*--------------------------------------------------------------------*/
-const char* getComputeAsmInputOutputBuffer			(void);
+std::string getComputeAsmInputOutputBuffer			(std::string blockStorageClass = "Uniform");
 /*--------------------------------------------------------------------*//*!
  * Declares buffer type and layout for uniform variables indata and
  * outdata. Both of them are SSBO bounded to descriptor set 0.
  * indata is at binding point 0, while outdata is at 1.
  *//*--------------------------------------------------------------------*/
-const char* getComputeAsmInputOutputBufferTraits	(void);
+std::string getComputeAsmInputOutputBufferTraits	(std::string blockStorageClass = "BufferBlock");
 
 bool verifyOutput									(const std::vector<Resource>&,
 													const std::vector<AllocationSp>&	outputAllocs,
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.cpp
new file mode 100644
index 0000000..7551ede
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.cpp
@@ -0,0 +1,262 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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 Float Control SPIR-V tokens test
+ *//*--------------------------------------------------------------------*/
+
+#include "vkApiVersion.hpp"
+
+#include "vktSpvAsmFloatControlsExtensionlessTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktSpvAsmComputeShaderCase.hpp"
+
+#include "deRandom.hpp"
+#include "deStringUtil.hpp"
+#include "tcuCommandLine.hpp"
+#include "vkQueryUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+static const char* TEST_FEATURE_DENORM_PRESERVE					= "DenormPreserve";
+static const char* TEST_FEATURE_DENORM_FLUSH_TO_ZERO			= "DenormFlushToZero";
+static const char* TEST_FEATURE_SIGNED_ZERO_INF_NAN_PRESERVE	= "SignedZeroInfNanPreserve";
+static const char* TEST_FEATURE_ROUNDING_MODE_RTE				= "RoundingModeRTE";
+static const char* TEST_FEATURE_ROUNDING_MODE_RTZ				= "RoundingModeRTZ";
+
+using namespace vk;
+using std::map;
+using std::string;
+using std::vector;
+
+static void getComputeSourceCode (std::string& computeSourceCode, const std::string& featureName, const int fpWideness)
+{
+	const std::string capability	= "OpCapability " + featureName + "\n";
+	const std::string exeModes		= "OpExecutionMode %main " + featureName + " " + de::toString(fpWideness) + "\n";
+
+	computeSourceCode =
+		string(getComputeAsmShaderPreamble(capability, "", exeModes, "", "%indata %outdata")) +
+
+		"OpSource GLSL 430\n"
+		"OpName %main \"main\"\n"
+		"OpName %id \"gl_GlobalInvocationID\"\n"
+
+		"OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+		+ getComputeAsmInputOutputBufferTraits("Block") + getComputeAsmCommonTypes("StorageBuffer") + getComputeAsmInputOutputBuffer("StorageBuffer") +
+
+		"%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 (Context& ctx, const std::string& testCaseName)
+{
+	const deUint32		baseSeed		= deStringHash(testCaseName.c_str()) + static_cast<deUint32>(ctx.getTestContext().getCommandLine().getBaseSeed());
+	de::Random			rnd				(baseSeed);
+	const int			numElements		= 64;
+	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)
+		outputFloats[ndx] = -inputFloats[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(inputFloats)));
+	spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+
+	spec.numWorkGroups	= tcu::IVec3(numElements, 1, 1);
+	spec.verifyIO		= &verifyOutput;
+
+	return spec;
+}
+
+VkBool32 getFloatControlsProperty(Context& context, const int fpWideness, const std::string& featureName)
+{
+	VkPhysicalDeviceFloatControlsProperties floatControlsProperties;
+	deMemset(&floatControlsProperties, 0, sizeof(floatControlsProperties));
+	floatControlsProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
+
+	VkPhysicalDeviceProperties2 properties;
+	deMemset(&properties, 0, sizeof(properties));
+	properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+	properties.pNext = &floatControlsProperties;
+
+	context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
+
+	if (fpWideness == 16)
+	{
+		if (featureName == TEST_FEATURE_DENORM_PRESERVE				) return floatControlsProperties.shaderDenormPreserveFloat16;
+		if (featureName == TEST_FEATURE_DENORM_FLUSH_TO_ZERO		) return floatControlsProperties.shaderDenormFlushToZeroFloat16;
+		if (featureName == TEST_FEATURE_SIGNED_ZERO_INF_NAN_PRESERVE) return floatControlsProperties.shaderSignedZeroInfNanPreserveFloat16;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTE			) return floatControlsProperties.shaderRoundingModeRTEFloat16;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTZ			) return floatControlsProperties.shaderRoundingModeRTZFloat16;
+	}
+
+	if (fpWideness == 32)
+	{
+		if (featureName == TEST_FEATURE_DENORM_PRESERVE				) return floatControlsProperties.shaderDenormPreserveFloat32;
+		if (featureName == TEST_FEATURE_DENORM_FLUSH_TO_ZERO		) return floatControlsProperties.shaderDenormFlushToZeroFloat32;
+		if (featureName == TEST_FEATURE_SIGNED_ZERO_INF_NAN_PRESERVE) return floatControlsProperties.shaderSignedZeroInfNanPreserveFloat32;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTE			) return floatControlsProperties.shaderRoundingModeRTEFloat32;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTZ			) return floatControlsProperties.shaderRoundingModeRTZFloat32;
+	}
+
+	if (fpWideness == 64)
+	{
+		if (featureName == TEST_FEATURE_DENORM_PRESERVE				) return floatControlsProperties.shaderDenormPreserveFloat64;
+		if (featureName == TEST_FEATURE_DENORM_FLUSH_TO_ZERO		) return floatControlsProperties.shaderDenormFlushToZeroFloat64;
+		if (featureName == TEST_FEATURE_SIGNED_ZERO_INF_NAN_PRESERVE) return floatControlsProperties.shaderSignedZeroInfNanPreserveFloat64;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTE			) return floatControlsProperties.shaderRoundingModeRTEFloat64;
+		if (featureName == TEST_FEATURE_ROUNDING_MODE_RTZ			) return floatControlsProperties.shaderRoundingModeRTZFloat64;
+	}
+
+	TCU_THROW(InternalError, "Unknown property requested");
+}
+
+class SpvAsmFloatControlsExtensionlessInstance : public ComputeShaderSpec, public SpvAsmComputeShaderInstance
+{
+public:
+	SpvAsmFloatControlsExtensionlessInstance	(Context& ctx, const std::string& testCaseName);
+};
+
+SpvAsmFloatControlsExtensionlessInstance::SpvAsmFloatControlsExtensionlessInstance (Context& ctx, const std::string& testCaseName)
+	: ComputeShaderSpec(getComputeShaderSpec(ctx, testCaseName))
+	, SpvAsmComputeShaderInstance(ctx, *this)
+{
+}
+
+SpvAsmFloatControlsExtensionlessCase::SpvAsmFloatControlsExtensionlessCase (tcu::TestContext& testCtx, const char* name, const char* description, const char* featureName, const int fpWideness, const bool spirv14)
+	: TestCase		(testCtx, name, description)
+	, m_featureName	(featureName)
+	, m_fpWideness	(fpWideness)
+	, m_spirv14		(spirv14)
+{
+}
+
+void SpvAsmFloatControlsExtensionlessCase::initPrograms (SourceCollections& programCollection) const
+{
+	const bool	allowSpirv14	= true;
+	std::string	comp;
+
+	getComputeSourceCode(comp, m_featureName, m_fpWideness);
+
+	programCollection.spirvAsmSources.add("compute") << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_4, allowSpirv14) << comp;
+}
+
+void SpvAsmFloatControlsExtensionlessCase::checkSupport (Context& context) const
+{
+	if (m_spirv14)
+	{
+		context.requireDeviceFunctionality("VK_KHR_spirv_1_4");
+	}
+	else
+	{
+		if (!context.contextSupports(vk::ApiVersion(1, 2, 0)))
+			TCU_THROW(NotSupportedError, "Test requires Vulkan 1.2");
+	}
+
+	if (m_fpWideness == 16)
+	{
+		context.requireDeviceFunctionality("VK_KHR_shader_float16_int8");
+		if (!isFloat16Int8FeaturesSupported(context, EXTFLOAT16INT8FEATURES_FLOAT16))
+			TCU_THROW(NotSupportedError, "Floating point number of width 16 bit are not supported");
+	}
+
+	if (m_fpWideness == 64)
+	{
+		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_FLOAT64);
+	}
+
+	if (!getFloatControlsProperty(context, m_fpWideness, m_featureName))
+		TCU_THROW(NotSupportedError, "Property is not supported");
+}
+
+TestInstance* SpvAsmFloatControlsExtensionlessCase::createInstance (Context& context) const
+{
+	return new SpvAsmFloatControlsExtensionlessInstance(context, getName());
+}
+
+tcu::TestCaseGroup* createFloatControlsExtensionlessGroup (tcu::TestContext& testCtx)
+{
+	const char*						spirVersions[]			= { "spirv1p4", "vulkan1_2" };
+	const int						floatingPointWideness[]	= { 16, 32, 64 };
+	const struct FpFeatures
+	{
+		const char* testName;
+		const char* featureName;
+	}
+	fpFeatures[] =
+	{
+		{ "denorm_preserve",				TEST_FEATURE_DENORM_PRESERVE				},
+		{ "denorm_flush_to_zero",			TEST_FEATURE_DENORM_FLUSH_TO_ZERO			},
+		{ "signed_zero_inf_nan_preserve",	TEST_FEATURE_SIGNED_ZERO_INF_NAN_PRESERVE	},
+		{ "rounding_mode_rte",				TEST_FEATURE_ROUNDING_MODE_RTE				},
+		{ "rounding_mode_rtz",				TEST_FEATURE_ROUNDING_MODE_RTZ				},
+	};
+	de::MovePtr<tcu::TestCaseGroup>	group					(new tcu::TestCaseGroup(testCtx, "float_controls_extensionless", "Tests float controls without extension"));
+
+	for (int spirVersionsNdx = 0; spirVersionsNdx < DE_LENGTH_OF_ARRAY(spirVersions); ++spirVersionsNdx)
+	{
+		const bool						spirv14				= (spirVersionsNdx == 0);
+		de::MovePtr<tcu::TestCaseGroup>	spirVersionGroup	(new tcu::TestCaseGroup(testCtx, spirVersions[spirVersionsNdx], ""));
+
+		for (int fpWidenessNdx = 0; fpWidenessNdx < DE_LENGTH_OF_ARRAY(floatingPointWideness); ++fpWidenessNdx)
+		for (int execModeNdx = 0; execModeNdx < DE_LENGTH_OF_ARRAY(fpFeatures); ++execModeNdx)
+		{
+			const int			fpWideness		= floatingPointWideness[fpWidenessNdx];
+			const std::string	testName		= fpFeatures[execModeNdx].testName;
+			const char*			featureName		= fpFeatures[execModeNdx].featureName;
+			const std::string	fullTestName	= "fp" + de::toString(fpWideness) + "_" + testName;
+
+			spirVersionGroup->addChild(new SpvAsmFloatControlsExtensionlessCase(testCtx, fullTestName.c_str(), "", featureName, fpWideness, spirv14));
+		}
+
+		group->addChild(spirVersionGroup.release());
+	}
+
+	return group.release();
+}
+
+
+} // SpirVAssembly
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.hpp
new file mode 100644
index 0000000..1cc7ea8
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsExtensionlessTests.hpp
@@ -0,0 +1,55 @@
+#ifndef _VKTSPVASMFLOATCONTROLSEXTENSIONLESSTESTS_HPP
+#define _VKTSPVASMFLOATCONTROLSEXTENSIONLESSTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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 Float Control SPIR-V tokens test
+ *//*--------------------------------------------------------------------*/
+
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+class SpvAsmFloatControlsExtensionlessCase : public TestCase
+{
+public:
+					SpvAsmFloatControlsExtensionlessCase	(tcu::TestContext& testCtx, const char* name, const char* description, const char* featureName, const int fpWideness, const bool spirv14);
+	void			initPrograms							(vk::SourceCollections& programCollection) const;
+	TestInstance*	createInstance							(Context& context) const;
+	virtual void	checkSupport							(Context& context) const;
+
+protected:
+	const char*		m_featureName;
+	const int		m_fpWideness;
+	const bool		m_spirv14;
+};
+
+tcu::TestCaseGroup* createFloatControlsExtensionlessGroup (tcu::TestContext& testCtx);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMFLOATCONTROLSEXTENSIONLESSTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp
index 2c0a3e8..c054d1d 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp
@@ -2541,7 +2541,7 @@
 	{
 		const char*								name;
 		SettingsMode							testedMode;
-		VkShaderFloatControlsIndependenceKHR	independenceSetting;
+		VkShaderFloatControlsIndependence		independenceSetting;
 
 		SettingsOption							fp16Option;
 		SettingsOption							fp32Option;
@@ -3036,7 +3036,7 @@
 	TestCaseGroup*	group	= new TestCaseGroup(testCtx, "independence_settings", "");
 	parentGroup->addChild(group);
 
-	using SFCI = VkShaderFloatControlsIndependenceKHR;
+	using SFCI = VkShaderFloatControlsIndependence;
 	const SFCI independence32	= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
 	const SFCI independenceAll	= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
index 9361ff5..6e18155 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
@@ -832,7 +832,7 @@
 		"${capability:opt}\n"
 		"${extension:opt}\n"
 		"OpMemoryModel Logical GLSL450\n"
-		"OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
+		"OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} ${GL_entrypoint:opt} \n"
 		"OpExecutionMode %BP_main Triangles\n"
 		"OpExecutionMode %BP_main Invocations 1\n"
 		"OpExecutionMode %BP_main OutputTriangleStrip\n"
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
index 57f5bc1..d165387 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp
@@ -99,12 +99,14 @@
 	VerifyIOFunc				verifyIO;
 	GraphicsVerifyBinaryFunc	verifyBinary;
 	SpirvVersion				spirvVersion;
+	bool						spirvVersion14;
 
 							GraphicsResources()
-								: inputFormat	(VK_FORMAT_R32G32B32A32_SFLOAT)
-								, verifyIO		(DE_NULL)
-								, verifyBinary	(DE_NULL)
-								, spirvVersion	(SPIRV_VERSION_1_0)
+								: inputFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
+								, verifyIO			(DE_NULL)
+								, verifyBinary		(DE_NULL)
+								, spirvVersion		(SPIRV_VERSION_1_0)
+								, spirvVersion14	(false)
 							{}
 };
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
index f48012d..c614b21 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
@@ -76,6 +76,7 @@
 #include "vktSpvAsmWorkgroupMemoryTests.hpp"
 #include "vktSpvAsmSignedIntCompareTests.hpp"
 #include "vktSpvAsmPtrAccessChainTests.hpp"
+#include "vktSpvAsmFloatControlsExtensionlessTests.hpp"
 #include "vktSpvAsm64bitCompareTests.hpp"
 
 #include <cmath>
@@ -9893,7 +9894,7 @@
 	return getTypeName(from) + "_to_" + getTypeName(to) + fullSuffix;
 }
 
-const string getAsmTypeName (ConversionDataType type)
+const string getAsmTypeName (ConversionDataType type, deUint32 elements = 1)
 {
 	string prefix;
 
@@ -9902,33 +9903,37 @@
 	else if (type == DATA_TYPE_VEC2_SIGNED_16)	return "i16vec2";
 	else if (type == DATA_TYPE_VEC2_SIGNED_32)	return "v2i32";
 	else										DE_ASSERT(false);
+	if ((isInt(type) || isFloat(type)) && elements == 2)
+	{
+		prefix = "v2" + prefix;
+	}
 
 	return prefix + getBitWidthStr(type);
 }
 
 template<typename T>
-BufferSp getSpecializedBuffer (deInt64 number)
+BufferSp getSpecializedBuffer (deInt64 number, deUint32 elements = 1)
 {
-	return BufferSp(new Buffer<T>(vector<T>(1, (T)number)));
+	return BufferSp(new Buffer<T>(vector<T>(elements, (T)number)));
 }
 
-BufferSp getBuffer (ConversionDataType type, deInt64 number)
+BufferSp getBuffer (ConversionDataType type, deInt64 number, deUint32 elements = 1)
 {
 	switch (type)
 	{
-		case DATA_TYPE_SIGNED_8:		return getSpecializedBuffer<deInt8>(number);
-		case DATA_TYPE_SIGNED_16:		return getSpecializedBuffer<deInt16>(number);
-		case DATA_TYPE_SIGNED_32:		return getSpecializedBuffer<deInt32>(number);
-		case DATA_TYPE_SIGNED_64:		return getSpecializedBuffer<deInt64>(number);
-		case DATA_TYPE_UNSIGNED_8:		return getSpecializedBuffer<deUint8>(number);
-		case DATA_TYPE_UNSIGNED_16:		return getSpecializedBuffer<deUint16>(number);
-		case DATA_TYPE_UNSIGNED_32:		return getSpecializedBuffer<deUint32>(number);
-		case DATA_TYPE_UNSIGNED_64:		return getSpecializedBuffer<deUint64>(number);
-		case DATA_TYPE_FLOAT_16:		return getSpecializedBuffer<deUint16>(number);
-		case DATA_TYPE_FLOAT_32:		return getSpecializedBuffer<deUint32>(number);
-		case DATA_TYPE_FLOAT_64:		return getSpecializedBuffer<deUint64>(number);
-		case DATA_TYPE_VEC2_SIGNED_16:	return getSpecializedBuffer<deUint32>(number);
-		case DATA_TYPE_VEC2_SIGNED_32:	return getSpecializedBuffer<deUint64>(number);
+		case DATA_TYPE_SIGNED_8:		return getSpecializedBuffer<deInt8>(number, elements);
+		case DATA_TYPE_SIGNED_16:		return getSpecializedBuffer<deInt16>(number, elements);
+		case DATA_TYPE_SIGNED_32:		return getSpecializedBuffer<deInt32>(number, elements);
+		case DATA_TYPE_SIGNED_64:		return getSpecializedBuffer<deInt64>(number, elements);
+		case DATA_TYPE_UNSIGNED_8:		return getSpecializedBuffer<deUint8>(number, elements);
+		case DATA_TYPE_UNSIGNED_16:		return getSpecializedBuffer<deUint16>(number, elements);
+		case DATA_TYPE_UNSIGNED_32:		return getSpecializedBuffer<deUint32>(number, elements);
+		case DATA_TYPE_UNSIGNED_64:		return getSpecializedBuffer<deUint64>(number, elements);
+		case DATA_TYPE_FLOAT_16:		return getSpecializedBuffer<deUint16>(number, elements);
+		case DATA_TYPE_FLOAT_32:		return getSpecializedBuffer<deUint32>(number, elements);
+		case DATA_TYPE_FLOAT_64:		return getSpecializedBuffer<deUint64>(number, elements);
+		case DATA_TYPE_VEC2_SIGNED_16:	return getSpecializedBuffer<deUint32>(number, elements);
+		case DATA_TYPE_VEC2_SIGNED_32:	return getSpecializedBuffer<deUint64>(number, elements);
 
 		default:						TCU_THROW(InternalError, "Unimplemented type passed");
 	}
@@ -9975,7 +9980,7 @@
 	return (from == DATA_TYPE_FLOAT_64 || to == DATA_TYPE_FLOAT_64);
 }
 
-void getVulkanFeaturesAndExtensions (ConversionDataType from, ConversionDataType to, VulkanFeatures& vulkanFeatures, vector<string>& extensions)
+void getVulkanFeaturesAndExtensions (ConversionDataType from, ConversionDataType to, bool useStorageExt, VulkanFeatures& vulkanFeatures, vector<string>& extensions)
 {
 	if (usesInt16(from, to) && !usesInt32(from, to))
 		vulkanFeatures.coreFeatures.shaderInt16 = DE_TRUE;
@@ -9986,7 +9991,7 @@
 	if (usesFloat64(from, to))
 		vulkanFeatures.coreFeatures.shaderFloat64 = DE_TRUE;
 
-	if (usesInt16(from, to) || usesFloat16(from, to))
+	if ((usesInt16(from, to) || usesFloat16(from, to)) && useStorageExt)
 	{
 		extensions.push_back("VK_KHR_16bit_storage");
 		vulkanFeatures.ext16BitStorage |= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
@@ -10013,23 +10018,67 @@
 
 struct ConvertCase
 {
-	ConvertCase (const string& instruction, ConversionDataType from, ConversionDataType to, deInt64 number, bool separateOutput = false, deInt64 outputNumber = 0, const char* suffix = DE_NULL)
+	ConvertCase (const string& instruction, ConversionDataType from, ConversionDataType to, deInt64 number, bool separateOutput = false, deInt64 outputNumber = 0, const char* suffix = DE_NULL, bool useStorageExt = true)
 	: m_fromType		(from)
 	, m_toType			(to)
+	, m_elements		(1)
+	, m_useStorageExt	(useStorageExt)
 	, m_name			(getTestName(from, to, suffix))
-	, m_inputBuffer		(getBuffer(from, number))
 	{
 		string caps;
 		string decl;
 		string exts;
 
-		m_asmTypes["inputType"]		= getAsmTypeName(from);
-		m_asmTypes["outputType"]	= getAsmTypeName(to);
+		m_asmTypes["inStorageType"]	= getAsmTypeName(from);
+		m_asmTypes["outStorageType"] = getAsmTypeName(to);
+		m_asmTypes["inCast"] = "OpCopyObject";
+		m_asmTypes["outCast"] = "OpCopyObject";
+		// If the storage extensions are being avoided, tests instead uses
+		// vectors so that they are easily convertible to 32-bit integers.
+		// |m_elements| indicates the size of the vector. It modifies how many
+		// items added to the buffers and converted in the tests.
+		//
+		// Currently only supports 1 (default) or 2 elements.
+		if (!m_useStorageExt)
+		{
+			bool in_change = false;
+			bool out_change = false;
+			if (usesFloat16(from, from) || usesInt16(from, from))
+			{
+				m_asmTypes["inStorageType"] = "u32";
+				m_asmTypes["inCast"] = "OpBitcast";
+				m_elements = 2;
+				in_change = true;
+			}
+			if (usesFloat16(to, to) || usesInt16(to, to))
+			{
+				m_asmTypes["outStorageType"] = "u32";
+				m_asmTypes["outCast"] = "OpBitcast";
+				m_elements = 2;
+				out_change = true;
+			}
+			if (in_change && !out_change)
+			{
+				m_asmTypes["outStorageType"] = getAsmTypeName(to, m_elements);
+			}
+			if (!in_change && out_change)
+			{
+				m_asmTypes["inStorageType"] = getAsmTypeName(from, m_elements);
+			}
+		}
 
+		// Safety check for implementation.
+		if (m_elements < 1 || m_elements > 2)
+			TCU_THROW(InternalError, "Unsupported number of elements");
+
+		m_asmTypes["inputType"]		= getAsmTypeName(from, m_elements);
+		m_asmTypes["outputType"]	= getAsmTypeName(to, m_elements);
+
+		m_inputBuffer = getBuffer(from, number, m_elements);
 		if (separateOutput)
-			m_outputBuffer = getBuffer(to, outputNumber);
+			m_outputBuffer = getBuffer(to, outputNumber, m_elements);
 		else
-			m_outputBuffer = getBuffer(to, number);
+			m_outputBuffer = getBuffer(to, number, m_elements);
 
 		if (usesInt8(from, to))
 		{
@@ -10047,6 +10096,12 @@
 
 			decl += "%i8         = OpTypeInt 8 1\n"
 					"%u8         = OpTypeInt 8 0\n";
+
+			if (m_elements == 2)
+			{
+				decl += "%v2i8       = OpTypeVector %i8 2\n"
+						"%v2u8       = OpTypeVector %u8 2\n";
+			}
 			exts += "OpExtension \"SPV_KHR_8bit_storage\"\n";
 		}
 
@@ -10062,24 +10117,36 @@
 			}
 
 			decl += "%i16        = OpTypeInt 16 1\n"
-					"%u16        = OpTypeInt 16 0\n"
-					"%i16vec2    = OpTypeVector %i16 2\n";
+					"%u16        = OpTypeInt 16 0\n";
+			if (m_elements == 2)
+			{
+				decl += "%v2i16      = OpTypeVector %i16 2\n"
+						"%v2u16      = OpTypeVector %u16 2\n";
+			}
+			else
+			{
+				decl += "%i16vec2    = OpTypeVector %i16 2\n";
+			}
 
 			// Conversions between 16 and 32 bit are provided by SPV_KHR_16bit_storage. The rest requires explicit Int16
-			if (requiresInt16Capability)
+			if (requiresInt16Capability || !m_useStorageExt)
 				caps += "OpCapability Int16\n";
 		}
 
 		if (usesFloat16(from, to))
 		{
 			decl += "%f16        = OpTypeFloat 16\n";
+			if (m_elements == 2)
+			{
+				decl += "%v2f16      = OpTypeVector %f16 2\n";
+			}
 
 			// Width-only conversions between 16 and 32 bit are provided by SPV_KHR_16bit_storage. The rest requires explicit Float16
-			if (!usesFloat32(from, to))
+			if (!usesFloat32(from, to) || !m_useStorageExt)
 				caps += "OpCapability Float16\n";
 		}
 
-		if (usesInt16(from, to) || usesFloat16(from, to))
+		if ((usesInt16(from, to) || usesFloat16(from, to)) && m_useStorageExt)
 		{
 			caps += "OpCapability StorageUniformBufferBlock16\n";
 			exts += "OpExtension \"SPV_KHR_16bit_storage\"\n";
@@ -10090,12 +10157,21 @@
 			caps += "OpCapability Int64\n";
 			decl += "%i64        = OpTypeInt 64 1\n"
 					"%u64        = OpTypeInt 64 0\n";
+			if (m_elements == 2)
+			{
+				decl += "%v2i64      = OpTypeVector %i64 2\n"
+						"%v2u64      = OpTypeVector %u64 2\n";
+			}
 		}
 
 		if (usesFloat64(from, to))
 		{
 			caps += "OpCapability Float64\n";
 			decl += "%f64        = OpTypeFloat 64\n";
+			if (m_elements == 2)
+			{
+				decl += "%v2f64        = OpTypeVector %f64 2\n";
+			}
 		}
 
 		m_asmTypes["datatype_capabilities"]		= caps;
@@ -10105,13 +10181,15 @@
 
 	ConversionDataType		m_fromType;
 	ConversionDataType		m_toType;
+	deUint32				m_elements;
+	bool					m_useStorageExt;
 	string					m_name;
 	map<string, string>		m_asmTypes;
 	BufferSp				m_inputBuffer;
 	BufferSp				m_outputBuffer;
 };
 
-const string getConvertCaseShaderStr (const string& instruction, const ConvertCase& convertCase)
+const string getConvertCaseShaderStr (const string& instruction, const ConvertCase& convertCase, bool addVectors = false)
 {
 	map<string, string> params = convertCase.m_asmTypes;
 
@@ -10119,7 +10197,7 @@
 	params["inDecorator"]	= getByteWidthStr(convertCase.m_fromType);
 	params["outDecorator"]	= getByteWidthStr(convertCase.m_toType);
 
-	const StringTemplate shader (
+	std::string shader (
 		"OpCapability Shader\n"
 		"${datatype_capabilities}"
 		"${datatype_extensions:opt}"
@@ -10145,12 +10223,19 @@
 		"%f32        = OpTypeFloat 32\n"
 		"%v2i32      = OpTypeVector %i32 2\n"
 		"${datatype_additional_decl}"
+	);
+	if (addVectors)
+	{
+		shader += "%v2u32 = OpTypeVector %u32 2\n"
+					"%v2f32 = OpTypeVector %f32 2\n";
+	}
+	shader +=
 		"%uvec3      = OpTypeVector %u32 3\n"
 		// Derived types
-		"%in_ptr     = OpTypePointer Uniform %${inputType}\n"
-		"%out_ptr    = OpTypePointer Uniform %${outputType}\n"
-		"%in_buf     = OpTypeStruct %${inputType}\n"
-		"%out_buf    = OpTypeStruct %${outputType}\n"
+		"%in_ptr     = OpTypePointer Uniform %${inStorageType}\n"
+		"%out_ptr    = OpTypePointer Uniform %${outStorageType}\n"
+		"%in_buf     = OpTypeStruct %${inStorageType}\n"
+		"%out_buf    = OpTypeStruct %${outStorageType}\n"
 		"%in_bufptr  = OpTypePointer Uniform %in_buf\n"
 		"%out_bufptr = OpTypePointer Uniform %out_buf\n"
 		"%indata     = OpVariable %in_bufptr Uniform\n"
@@ -10162,14 +10247,16 @@
 		"%label      = OpLabel\n"
 		"%inloc      = OpAccessChain %in_ptr %indata %zero\n"
 		"%outloc     = OpAccessChain %out_ptr %outdata %zero\n"
-		"%inval      = OpLoad %${inputType} %inloc\n"
-		"%conv       = ${instruction} %${outputType} %inval\n"
-		"              OpStore %outloc %conv\n"
+		"%inval      = OpLoad %${inStorageType} %inloc\n"
+		"%in_cast    = ${inCast} %${inputType} %inval\n"
+		"%conv       = ${instruction} %${outputType} %in_cast\n"
+		"%out_cast   = ${outCast} %${outStorageType} %conv\n"
+		"              OpStore %outloc %out_cast\n"
 		"              OpReturn\n"
 		"              OpFunctionEnd\n"
-	);
+	;
 
-	return shader.specialize(params);
+	return StringTemplate(shader).specialize(params);
 }
 
 void createConvertCases (vector<ConvertCase>& testCases, const string& instruction)
@@ -10271,8 +10358,13 @@
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_FLOAT_64,			0x449a4000,							true,	0x4093480000000000));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_FLOAT_32,			0x4093480000000000,					true,	0x449a4000));
 
+		// Conversion to/from 32-bit floats are supported by both 16-bit
+		// storage and Float16. The tests are duplicated to exercise both
+		// cases.
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_FLOAT_16,			0x449a4000,							true,	0x64D2));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_FLOAT_32,			0x64D2,								true,	0x449a4000));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_FLOAT_16,			0x449a4000,							true,	0x64D2,					"no_storage",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_FLOAT_32,			0x64D2,								true,	0x449a4000,				"no_storage",	false));
 
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_FLOAT_64,			0x64D2,								true,	0x4093480000000000));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_FLOAT_16,			0x4093480000000000,					true,	0x64D2));
@@ -10280,44 +10372,44 @@
 	else if (instruction == "OpConvertFToU")
 	{
 		// Normal numbers from uint8 range
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x5020,								true,	33,									"33"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x5020,								true,	33,									"33",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_8,		0x42280000,							true,	42,									"42"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_UNSIGNED_8,		0x4067800000000000ull,				true,	188,								"188"));
 
 		// Maximum uint8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x5BF8,								true,	255,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x5BF8,								true,	255,								"max",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_8,		0x437F0000,							true,	255,								"max"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_UNSIGNED_8,		0x406FE00000000000ull,				true,	255,								"max"));
 
 		// +0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x0000,								true,	0,									"p0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x0000,								true,	0,									"p0",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_8,		0x00000000,							true,	0,									"p0"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_UNSIGNED_8,		0x0000000000000000ull,				true,	0,									"p0"));
 
 		// -0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x8000,								true,	0,									"m0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_8,		0x8000,								true,	0,									"m0",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_8,		0x80000000,							true,	0,									"m0"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_UNSIGNED_8,		0x8000000000000000ull,				true,	0,									"m0"));
 
 		// All hexadecimal values below represent 1234.0 as 16/32/64-bit IEEE 754 float
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x64D2,								true,	1234,								"1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x64D2,								true,	1234,								"1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x64D2,								true,	1234,								"1234"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x64D2,								true,	1234,								"1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x64D2,								true,	1234,								"1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x64D2,								true,	1234,								"1234",	false));
 
 		// 0x7BFF = 0111 1011 1111 1111 = 0 11110 1111111111 = 65504
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x7BFF,								true,	65504,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x7BFF,								true,	65504,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x7BFF,								true,	65504,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x7BFF,								true,	65504,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x7BFF,								true,	65504,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x7BFF,								true,	65504,								"max",	false));
 
 		// +0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x0000,								true,	0,									"p0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x0000,								true,	0,									"p0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x0000,								true,	0,									"p0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x0000,								true,	0,									"p0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x0000,								true,	0,									"p0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x0000,								true,	0,									"p0",	false));
 
 		// -0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x8000,								true,	0,									"m0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x8000,								true,	0,									"m0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x8000,								true,	0,									"m0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_16,		0x8000,								true,	0,									"m0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_32,		0x8000,								true,	0,									"m0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_UNSIGNED_64,		0x8000,								true,	0,									"m0",	false));
 
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_16,		0x449a4000,							true,	1234));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_UNSIGNED_32,		0x449a4000,							true,	1234));
@@ -10329,24 +10421,24 @@
 	else if (instruction == "OpConvertUToF")
 	{
 		// Normal numbers from uint8 range
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_16,			116,								true,	0x5740,								"116"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_16,			116,								true,	0x5740,								"116",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_32,			232,								true,	0x43680000,							"232"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_64,			164,								true,	0x4064800000000000ull,				"164"));
 
 		// Maximum uint8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_16,			255,								true,	0x5BF8,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_16,			255,								true,	0x5BF8,								"max",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_32,			255,								true,	0x437F0000,							"max"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_8,		DATA_TYPE_FLOAT_64,			255,								true,	0x406FE00000000000ull,				"max"));
 
 		// All hexadecimal values below represent 1234.0 as 32/64-bit IEEE 754 float
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_32,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_64,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_32,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_64,		DATA_TYPE_FLOAT_16,			1234,								true,	0x64D2,								"1234",	false));
 
 		// 0x7BFF = 0111 1011 1111 1111 = 0 11110 1111111111 = 65504
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_32,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_64,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_32,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_64,		DATA_TYPE_FLOAT_16,			65504,								true,	0x7BFF,								"max",	false));
 
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_32,			1234,								true,	0x449a4000));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_UNSIGNED_16,		DATA_TYPE_FLOAT_64,			1234,								true,	0x4093480000000000));
@@ -10358,54 +10450,54 @@
 	else if (instruction == "OpConvertFToS")
 	{
 		// Normal numbers from int8 range
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0xC980,								true,	-11,								"m11"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0xC980,								true,	-11,								"m11",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_8,			0xC2140000,							true,	-37,								"m37"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_SIGNED_8,			0xC050800000000000ull,				true,	-66,								"m66"));
 
 		// Minimum int8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0xD800,								true,	-128,								"min"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0xD800,								true,	-128,								"min",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_8,			0xC3000000,							true,	-128,								"min"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_SIGNED_8,			0xC060000000000000ull,				true,	-128,								"min"));
 
 		// Maximum int8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x57F0,								true,	127,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x57F0,								true,	127,								"max",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_8,			0x42FE0000,							true,	127,								"max"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_SIGNED_8,			0x405FC00000000000ull,				true,	127,								"max"));
 
 		// +0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x0000,								true,	0,									"p0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x0000,								true,	0,									"p0",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_8,			0x00000000,							true,	0,									"p0"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_SIGNED_8,			0x0000000000000000ull,				true,	0,									"p0"));
 
 		// -0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x8000,								true,	0,									"m0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_8,			0x8000,								true,	0,									"m0",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_8,			0x80000000,							true,	0,									"m0"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_64,			DATA_TYPE_SIGNED_8,			0x8000000000000000ull,				true,	0,									"m0"));
 
 		// All hexadecimal values below represent -1234.0 as 32/64-bit IEEE 754 float
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0xE4D2,								true,	-1234,								"m1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0xE4D2,								true,	-1234,								"m1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0xE4D2,								true,	-1234,								"m1234"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0xE4D2,								true,	-1234,								"m1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0xE4D2,								true,	-1234,								"m1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0xE4D2,								true,	-1234,								"m1234",	false));
 
 		// 0xF800 = 1111 1000 0000 0000 = 1 11110 0000000000 = -32768
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0xF800,								true,	-32768,								"min"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0xF800,								true,	-32768,								"min"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0xF800,								true,	-32768,								"min"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0xF800,								true,	-32768,								"min",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0xF800,								true,	-32768,								"min",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0xF800,								true,	-32768,								"min",	false));
 
 		// 0x77FF = 0111 0111 1111 1111 = 0 11101 1111111111 = 32752
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x77FF,								true,	32752,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x77FF,								true,	32752,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x77FF,								true,	32752,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x77FF,								true,	32752,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x77FF,								true,	32752,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x77FF,								true,	32752,								"max",	false));
 
 		// +0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x0000,								true,	0,									"p0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x0000,								true,	0,									"p0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x0000,								true,	0,									"p0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x0000,								true,	0,									"p0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x0000,								true,	0,									"p0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x0000,								true,	0,									"p0",	false));
 
 		// -0
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x8000,								true,	0,									"m0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x8000,								true,	0,									"m0"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x8000,								true,	0,									"m0"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_16,		0x8000,								true,	0,									"m0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_32,		0x8000,								true,	0,									"m0",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_16,			DATA_TYPE_SIGNED_64,		0x8000,								true,	0,									"m0",	false));
 
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_16,		0xc49a4000,							true,	-1234));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_FLOAT_32,			DATA_TYPE_SIGNED_32,		0xc49a4000,							true,	-1234));
@@ -10419,34 +10511,34 @@
 	else if (instruction == "OpConvertSToF")
 	{
 		// Normal numbers from int8 range
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			-12,								true,	0xCA00,								"m21"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			-12,								true,	0xCA00,								"m21",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_32,			-21,								true,	0xC1A80000,							"m21"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_64,			-99,								true,	0xC058C00000000000ull,				"m99"));
 
 		// Minimum int8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			-128,								true,	0xD800,								"min"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			-128,								true,	0xD800,								"min",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_32,			-128,								true,	0xC3000000,							"min"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_64,			-128,								true,	0xC060000000000000ull,				"min"));
 
 		// Maximum int8 value
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			127,								true,	0x57F0,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_16,			127,								true,	0x57F0,								"max",	false));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_32,			127,								true,	0x42FE0000,							"max"));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_8,			DATA_TYPE_FLOAT_64,			127,								true,	0x405FC00000000000ull,				"max"));
 
 		// All hexadecimal values below represent 1234.0 as 32/64-bit IEEE 754 float
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			-1234,								true,	0xE4D2,								"m1234",	false));
 
 		// 0xF800 = 1111 1000 0000 0000 = 1 11110 0000000000 = -32768
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			-32768,								true,	0xF800,								"min",	false));
 
 		// 0x77FF = 0111 0111 1111 1111 = 0 11101 1111111111 = 32752
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max"));
-		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max"));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_32,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max",	false));
+		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_64,		DATA_TYPE_FLOAT_16,			32752,								true,	0x77FF,								"max",	false));
 
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_32,			-1234,								true,	0xc49a4000));
 		testCases.push_back(ConvertCase(instruction,	DATA_TYPE_SIGNED_16,		DATA_TYPE_FLOAT_64,			-1234,								true,	0xc093480000000000));
@@ -10523,12 +10615,12 @@
 	for (vector<ConvertCase>::const_iterator test = testCases.begin(); test != testCases.end(); ++test)
 	{
 		ComputeShaderSpec spec;
-		spec.assembly			= getConvertCaseShaderStr(instruction, *test);
+		spec.assembly			= getConvertCaseShaderStr(instruction, *test, true);
 		spec.numWorkGroups		= IVec3(1, 1, 1);
 		spec.inputs.push_back	(test->m_inputBuffer);
 		spec.outputs.push_back	(test->m_outputBuffer);
 
-		getVulkanFeaturesAndExtensions(test->m_fromType, test->m_toType, spec.requestedVulkanFeatures, spec.extensions);
+		getVulkanFeaturesAndExtensions(test->m_fromType, test->m_toType, test->m_useStorageExt, spec.requestedVulkanFeatures, spec.extensions);
 
 		group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "", spec));
 	}
@@ -10558,7 +10650,7 @@
 		resources.outputs.push_back	(Resource(test->m_outputBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		extensions.push_back		("VK_KHR_storage_buffer_storage_class");
 
-		getVulkanFeaturesAndExtensions(test->m_fromType, test->m_toType, vulkanFeatures, extensions);
+		getVulkanFeaturesAndExtensions(test->m_fromType, test->m_toType, test->m_useStorageExt, vulkanFeatures, extensions);
 
 		vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics	= true;
 		vulkanFeatures.coreFeatures.fragmentStoresAndAtomics		= true;
@@ -11363,6 +11455,9 @@
 		const size_t	typeStride;
 		const char*		typeName;
 		const char*		typeDecls;
+		const char*		typeStorage;
+		const string		loadFunction;
+		const string		storeFunction;
 	};
 
 	const TestType	testTypes[]	=
@@ -11372,41 +11467,65 @@
 			2 * sizeof(deFloat16),
 			"v2f16",
 			"      %v2f16 = OpTypeVector %f16 2\n"
+			"%v2f16_i32_fn = OpTypeFunction %v2f16 %i32\n"
+			"%void_f16_i32_fn = OpTypeFunction %void %f16 %i32\n"
+			"%c_u32_high_ones = OpConstant %u32 0xffff0000\n"
+			" %c_u32_low_ones = OpConstant %u32 0x0000ffff\n",
+			"u32",
+			loadV2F16FromUint,
+			storeScalarF16AsUint
 		},
 		{
 			3,
 			4 * sizeof(deFloat16),
 			"v3f16",
+			"      %v2f16 = OpTypeVector %f16 2\n"
 			"      %v3f16 = OpTypeVector %f16 3\n"
+			"%v3f16_i32_fn = OpTypeFunction %v3f16 %i32\n"
+			"%void_f16_i32_fn = OpTypeFunction %void %f16 %i32\n"
+			"%c_u32_high_ones = OpConstant %u32 0xffff0000\n"
+			" %c_u32_low_ones = OpConstant %u32 0x0000ffff\n",
+			"ra_u32_2",
+			loadV3F16FromUints,
+			storeScalarF16AsUint
 		},
 		{
 			4,
 			4 * sizeof(deFloat16),
 			"v4f16",
+			"      %v2f16 = OpTypeVector %f16 2\n"
 			"      %v4f16 = OpTypeVector %f16 4\n"
+			"%v4f16_i32_fn = OpTypeFunction %v4f16 %i32\n"
+			"%void_f16_i32_fn = OpTypeFunction %void %f16 %i32\n"
+			"%c_u32_high_ones = OpConstant %u32 0xffff0000\n"
+			" %c_u32_low_ones = OpConstant %u32 0x0000ffff\n",
+			"ra_u32_2",
+			loadV4F16FromUints,
+			storeScalarF16AsUint
 		},
 	};
 
 	const StringTemplate preMain
 	(
 		"  %c_i32_ndp = OpConstant %i32 ${num_data_points}\n"
+		" %c_i32_hndp = OpSpecConstantOp %i32 SDiv %c_i32_ndp %c_i32_2\n"
 		"        %f16 = OpTypeFloat 16\n"
 
 		"${type_decl}"
 
-		"   %up_${tt} = OpTypePointer Uniform %${tt}\n"
-		"   %ra_${tt} = OpTypeArray %${tt} %c_i32_ndp\n"
-		"   %SSBO_SRC = OpTypeStruct %ra_${tt}\n"
-		"%up_SSBO_SRC = OpTypePointer Uniform %SSBO_SRC\n"
-
 		"     %up_u32 = OpTypePointer Uniform %u32\n"
 		"     %ra_u32 = OpTypeArray %u32 %c_i32_ndp\n"
 		"   %SSBO_IDX = OpTypeStruct %ra_u32\n"
 		"%up_SSBO_IDX = OpTypePointer Uniform %SSBO_IDX\n"
 
-		"     %up_f16 = OpTypePointer Uniform %f16\n"
-		"     %ra_f16 = OpTypeArray %f16 %c_i32_ndp\n"
-		"   %SSBO_DST = OpTypeStruct %ra_f16\n"
+		"   %ra_u32_2 = OpTypeArray %u32 %c_u32_2\n"
+		" %ra_u32_ndp = OpTypeArray %u32 %c_i32_ndp\n"
+		"%ra_ra_u32_2 = OpTypeArray %ra_u32_2 %c_i32_ndp\n"
+		"   %SSBO_SRC = OpTypeStruct %ra_${ts}\n"
+		"%up_SSBO_SRC = OpTypePointer Uniform %SSBO_SRC\n"
+
+		" %ra_u32_hndp = OpTypeArray %u32 %c_i32_hndp\n"
+		"   %SSBO_DST = OpTypeStruct %ra_u32_hndp\n"
 		"%up_SSBO_DST = OpTypePointer Uniform %SSBO_DST\n"
 
 		"   %ssbo_src = OpVariable %up_SSBO_SRC Uniform\n"
@@ -11416,7 +11535,9 @@
 
 	const StringTemplate decoration
 	(
-		"OpDecorate %ra_${tt} ArrayStride ${tt_stride}\n"
+		"OpDecorate %ra_u32_2 ArrayStride 4\n"
+		"OpDecorate %ra_u32_hndp ArrayStride 4\n"
+		"OpDecorate %ra_ra_u32_2 ArrayStride 8\n"
 		"OpMemberDecorate %SSBO_SRC 0 Offset 0\n"
 		"OpDecorate %SSBO_SRC BufferBlock\n"
 		"OpDecorate %ssbo_src DescriptorSet 0\n"
@@ -11428,7 +11549,6 @@
 		"OpDecorate %ssbo_idx DescriptorSet 0\n"
 		"OpDecorate %ssbo_idx Binding 1\n"
 
-		"OpDecorate %ra_f16 ArrayStride 2\n"
 		"OpMemberDecorate %SSBO_DST 0 Offset 0\n"
 		"OpDecorate %SSBO_DST BufferBlock\n"
 		"OpDecorate %ssbo_dst DescriptorSet 0\n"
@@ -11460,16 +11580,14 @@
 		"    %write = OpLabel\n"
 		"      %ndx = OpLoad %i32 %i\n"
 
-		"      %src = OpAccessChain %up_${tt} %ssbo_src %c_i32_0 %ndx\n"
-		"  %val_src = OpLoad %${tt} %src\n"
+		"  %val_src = OpFunctionCall %${tt} %ld_arg_ssbo_src %ndx\n"
 
 		"  %src_idx = OpAccessChain %up_u32 %ssbo_idx %c_i32_0 %ndx\n"
 		"  %val_idx = OpLoad %u32 %src_idx\n"
 
 		"  %val_dst = OpVectorExtractDynamic %f16 %val_src %val_idx\n"
-		"      %dst = OpAccessChain %up_f16 %ssbo_dst %c_i32_0 %ndx\n"
+		"      %dst = OpFunctionCall %void %st_fn_ssbo_dst %val_dst %ndx\n"
 
-		"             OpStore %dst %val_dst\n"
 		"             OpBranch %next\n"
 
 		"     %next = OpLabel\n"
@@ -11504,25 +11622,25 @@
 
 		specs["num_data_points"]	= de::toString(iterations);
 		specs["tt"]					= testType.typeName;
+		specs["ts"]					= testType.typeStorage;
 		specs["tt_stride"]			= de::toString(testType.typeStride);
 		specs["type_decl"]			= testType.typeDecls;
 
-		fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"";
-		fragments["capability"]		= "OpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
+		fragments["capability"]		= "OpCapability Float16\n";
 		fragments["decoration"]		= decoration.specialize(specs);
 		fragments["pre_main"]		= preMain.specialize(specs);
 		fragments["testfun"]		= testFun.specialize(specs);
+		fragments["testfun"]		+= StringTemplate(testType.loadFunction).specialize({{"var", "ssbo_src"}});
+		fragments["testfun"]		+= StringTemplate(testType.storeFunction).specialize({{"var", "ssbo_dst"}});
 
 		specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16InputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.inputs.push_back(Resource(BufferSp(new Uint32Buffer(inputDataNdx)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16OutputDummy)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.verifyIO = compareFP16VectorExtractFunc;
 
-		extensions.push_back("VK_KHR_16bit_storage");
 		extensions.push_back("VK_KHR_shader_float16_int8");
 
 		features.extFloat16Int8		= EXTFLOAT16INT8FEATURES_FLOAT16;
-		features.ext16BitStorage	= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
 
 		finalizeTestsCreation(specResource, fragments, testCtx, *testGroup.get(), testName, features, extensions, IVec3(1, 1, 1));
 	}
@@ -11599,6 +11717,9 @@
 		const char*		typeName;
 		const char*		typeDecls;
 		VerifyIOFunc	verifyIOFunc;
+		const char*		typeStorage;
+		const string		loadFunction;
+		const string		storeFunction;
 	};
 
 	const TestType	testTypes[]	=
@@ -11607,22 +11728,39 @@
 			2,
 			2 * sizeof(deFloat16),
 			"v2f16",
-			"      %v2f16 = OpTypeVector %f16 2\n",
-			compareFP16VectorInsertFunc<2, replacement>
+			"      %v2f16 = OpTypeVector %f16 2\n"
+			"%v2f16_i32_fn = OpTypeFunction %v2f16 %i32\n"
+			"%void_v2f16_i32_fn = OpTypeFunction %void %v2f16 %i32\n",
+			compareFP16VectorInsertFunc<2, replacement>,
+			"u32",
+			loadV2F16FromUint,
+			storeV2F16AsUint
 		},
 		{
 			3,
 			4 * sizeof(deFloat16),
 			"v3f16",
-			"      %v3f16 = OpTypeVector %f16 3\n",
-			compareFP16VectorInsertFunc<3, replacement>
+			"      %v2f16 = OpTypeVector %f16 2\n"
+			"      %v3f16 = OpTypeVector %f16 3\n"
+			"%v3f16_i32_fn = OpTypeFunction %v3f16 %i32\n"
+			"%void_v3f16_i32_fn = OpTypeFunction %void %v3f16 %i32\n",
+			compareFP16VectorInsertFunc<3, replacement>,
+			"ra_u32_2",
+			loadV3F16FromUints,
+			storeV3F16AsUints
 		},
 		{
 			4,
 			4 * sizeof(deFloat16),
 			"v4f16",
-			"      %v4f16 = OpTypeVector %f16 4\n",
-			compareFP16VectorInsertFunc<4, replacement>
+			"      %v2f16 = OpTypeVector %f16 2\n"
+			"      %v4f16 = OpTypeVector %f16 4\n"
+			"%v4f16_i32_fn = OpTypeFunction %v4f16 %i32\n"
+			"%void_v4f16_i32_fn = OpTypeFunction %void %v4f16 %i32\n",
+			compareFP16VectorInsertFunc<4, replacement>,
+			"ra_u32_2",
+			loadV4F16FromUints,
+			storeV4F16AsUints
 		},
 	};
 
@@ -11634,17 +11772,17 @@
 
 		"${type_decl}"
 
-		"   %up_${tt} = OpTypePointer Uniform %${tt}\n"
-		"   %ra_${tt} = OpTypeArray %${tt} %c_i32_ndp\n"
-		"   %SSBO_SRC = OpTypeStruct %ra_${tt}\n"
-		"%up_SSBO_SRC = OpTypePointer Uniform %SSBO_SRC\n"
-
-		"     %up_u32 = OpTypePointer Uniform %u32\n"
 		"     %ra_u32 = OpTypeArray %u32 %c_i32_ndp\n"
+		"	  %up_u32 = OpTypePointer Uniform %u32\n"
 		"   %SSBO_IDX = OpTypeStruct %ra_u32\n"
 		"%up_SSBO_IDX = OpTypePointer Uniform %SSBO_IDX\n"
 
-		"   %SSBO_DST = OpTypeStruct %ra_${tt}\n"
+		"   %ra_u32_2 = OpTypeArray %u32 %c_u32_2\n"
+		"%ra_ra_u32_2 = OpTypeArray %ra_u32_2 %c_i32_ndp\n"
+		"   %SSBO_SRC = OpTypeStruct %ra_${ts}\n"
+		"%up_SSBO_SRC = OpTypePointer Uniform %SSBO_SRC\n"
+
+		"   %SSBO_DST = OpTypeStruct %ra_${ts}\n"
 		"%up_SSBO_DST = OpTypePointer Uniform %SSBO_DST\n"
 
 		"   %ssbo_src = OpVariable %up_SSBO_SRC Uniform\n"
@@ -11654,7 +11792,8 @@
 
 	const StringTemplate decoration
 	(
-		"OpDecorate %ra_${tt} ArrayStride ${tt_stride}\n"
+		"OpDecorate %ra_u32_2 ArrayStride 4\n"
+		"OpDecorate %ra_ra_u32_2 ArrayStride 8\n"
 		"OpMemberDecorate %SSBO_SRC 0 Offset 0\n"
 		"OpDecorate %SSBO_SRC BufferBlock\n"
 		"OpDecorate %ssbo_src DescriptorSet 0\n"
@@ -11697,16 +11836,14 @@
 		"    %write = OpLabel\n"
 		"      %ndx = OpLoad %i32 %i\n"
 
-		"      %src = OpAccessChain %up_${tt} %ssbo_src %c_i32_0 %ndx\n"
-		"  %val_src = OpLoad %${tt} %src\n"
+		"  %val_src = OpFunctionCall %${tt} %ld_arg_ssbo_src %ndx\n"
 
 		"  %src_idx = OpAccessChain %up_u32 %ssbo_idx %c_i32_0 %ndx\n"
 		"  %val_idx = OpLoad %u32 %src_idx\n"
 
 		"  %val_dst = OpVectorInsertDynamic %${tt} %val_src %c_f16_ins %val_idx\n"
-		"      %dst = OpAccessChain %up_${tt} %ssbo_dst %c_i32_0 %ndx\n"
+		"      %dst = OpFunctionCall %void %st_fn_ssbo_dst %val_dst %ndx\n"
 
-		"             OpStore %dst %val_dst\n"
 		"             OpBranch %next\n"
 
 		"     %next = OpLabel\n"
@@ -11741,26 +11878,26 @@
 
 		specs["num_data_points"]	= de::toString(iterations);
 		specs["tt"]					= testType.typeName;
+		specs["ts"]					= testType.typeStorage;
 		specs["tt_stride"]			= de::toString(testType.typeStride);
 		specs["type_decl"]			= testType.typeDecls;
 		specs["replacement"]		= de::toString(replacement);
 
-		fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"";
-		fragments["capability"]		= "OpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
+		fragments["capability"]		= "OpCapability Float16\n";
 		fragments["decoration"]		= decoration.specialize(specs);
 		fragments["pre_main"]		= preMain.specialize(specs);
 		fragments["testfun"]		= testFun.specialize(specs);
+		fragments["testfun"]		+= StringTemplate(testType.loadFunction).specialize({{"var", "ssbo_src"}});
+		fragments["testfun"]		+= StringTemplate(testType.storeFunction).specialize({{"var", "ssbo_dst"}});
 
 		specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16InputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.inputs.push_back(Resource(BufferSp(new Uint32Buffer(inputDataNdx)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16OutputDummy)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.verifyIO = testType.verifyIOFunc;
 
-		extensions.push_back("VK_KHR_16bit_storage");
 		extensions.push_back("VK_KHR_shader_float16_int8");
 
 		features.extFloat16Int8		= EXTFLOAT16INT8FEATURES_FLOAT16;
-		features.ext16BitStorage	= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
 
 		finalizeTestsCreation(specResource, fragments, testCtx, *testGroup.get(), testName, features, extensions, IVec3(1, 1, 1));
 	}
@@ -11904,6 +12041,8 @@
 	{
 		const deUint32	typeComponents;
 		const char*		typeName;
+		const string	loadFunction;
+		const string	storeFunction;
 	};
 
 	const TestType	testTypes[]	=
@@ -11911,14 +12050,20 @@
 		{
 			2,
 			"v2f16",
+			loadV2F16FromUint,
+			storeV2F16AsUint
 		},
 		{
 			3,
 			"v3f16",
+			loadV3F16FromUints,
+			storeV3F16AsUints
 		},
 		{
 			4,
 			"v4f16",
+			loadV4F16FromUints,
+			storeV4F16AsUints
 		},
 	};
 
@@ -11931,19 +12076,23 @@
 		"        %v3f16 = OpTypeVector %f16 3\n"
 		"        %v4f16 = OpTypeVector %f16 4\n"
 
-		"     %up_v2f16 = OpTypePointer Uniform %v2f16\n"
-		"     %ra_v2f16 = OpTypeArray %v2f16 %c_i32_ndp\n"
-		"   %SSBO_v2f16 = OpTypeStruct %ra_v2f16\n"
+		"     %v2f16_i32_fn = OpTypeFunction %v2f16 %i32\n"
+		"     %v3f16_i32_fn = OpTypeFunction %v3f16 %i32\n"
+		"     %v4f16_i32_fn = OpTypeFunction %v4f16 %i32\n"
+		"%void_v2f16_i32_fn = OpTypeFunction %void %v2f16 %i32\n"
+		"%void_v3f16_i32_fn = OpTypeFunction %void %v3f16 %i32\n"
+		"%void_v4f16_i32_fn = OpTypeFunction %void %v4f16 %i32\n"
+
+		"     %ra_u32_2 = OpTypeArray %u32 %c_u32_2\n"
+		"   %ra_u32_ndp = OpTypeArray %u32 %c_i32_ndp\n"
+		"  %ra_ra_u32_2 = OpTypeArray %ra_u32_2 %c_i32_ndp\n"
+		"       %up_u32 = OpTypePointer Uniform %u32\n"
+		"   %SSBO_v2f16 = OpTypeStruct %ra_u32_ndp\n"
+		"   %SSBO_v3f16 = OpTypeStruct %ra_ra_u32_2\n"
+		"   %SSBO_v4f16 = OpTypeStruct %ra_ra_u32_2\n"
+
 		"%up_SSBO_v2f16 = OpTypePointer Uniform %SSBO_v2f16\n"
-
-		"     %up_v3f16 = OpTypePointer Uniform %v3f16\n"
-		"     %ra_v3f16 = OpTypeArray %v3f16 %c_i32_ndp\n"
-		"   %SSBO_v3f16 = OpTypeStruct %ra_v3f16\n"
 		"%up_SSBO_v3f16 = OpTypePointer Uniform %SSBO_v3f16\n"
-
-		"     %up_v4f16 = OpTypePointer Uniform %v4f16\n"
-		"     %ra_v4f16 = OpTypeArray %v4f16 %c_i32_ndp\n"
-		"   %SSBO_v4f16 = OpTypeStruct %ra_v4f16\n"
 		"%up_SSBO_v4f16 = OpTypePointer Uniform %SSBO_v4f16\n"
 
 		"        %fun_t = OpTypeFunction %${tt_dst} %${tt_src0} %${tt_src1} %i32\n"
@@ -11955,9 +12104,9 @@
 
 	const StringTemplate decoration
 	(
-		"OpDecorate %ra_v2f16 ArrayStride 4\n"
-		"OpDecorate %ra_v3f16 ArrayStride 8\n"
-		"OpDecorate %ra_v4f16 ArrayStride 8\n"
+		"OpDecorate %ra_u32_2 ArrayStride 4\n"
+		"OpDecorate %ra_u32_ndp ArrayStride 4\n"
+		"OpDecorate %ra_ra_u32_2 ArrayStride 8\n"
 
 		"OpMemberDecorate %SSBO_v2f16 0 Offset 0\n"
 		"OpDecorate %SSBO_v2f16 BufferBlock\n"
@@ -12000,13 +12149,10 @@
 
 		"    %write = OpLabel\n"
 		"      %ndx = OpLoad %i32 %i\n"
-		"     %src0 = OpAccessChain %up_${tt_src0} %ssbo_src0 %c_i32_0 %ndx\n"
-		" %val_src0 = OpLoad %${tt_src0} %src0\n"
-		"     %src1 = OpAccessChain %up_${tt_src1} %ssbo_src1 %c_i32_0 %ndx\n"
-		" %val_src1 = OpLoad %${tt_src1} %src1\n"
+		" %val_src0 = OpFunctionCall %${tt_src0} %ld_arg_ssbo_src0 %ndx\n"
+		" %val_src1 = OpFunctionCall %${tt_src1} %ld_arg_ssbo_src1 %ndx\n"
 		"  %val_dst = OpFunctionCall %${tt_dst} %sw_fun %val_src0 %val_src1 %ndx\n"
-		"      %dst = OpAccessChain %up_${tt_dst} %ssbo_dst %c_i32_0 %ndx\n"
-		"             OpStore %dst %val_dst\n"
+		"      %dst = OpFunctionCall %void %st_fn_ssbo_dst %val_dst %ndx\n"
 		"             OpBranch %next\n"
 
 		"     %next = OpLabel\n"
@@ -12116,22 +12262,22 @@
 				specs["case_list"]			= caseList;
 				specs["case_count"]			= de::toString(caseCount);
 
-				fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"";
-				fragments["capability"]		= "OpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
+				fragments["capability"]		= "OpCapability Float16\n";
 				fragments["decoration"]		= decoration.specialize(specs);
 				fragments["pre_main"]		= preMain.specialize(specs);
 				fragments["testfun"]		= testFun.specialize(specs);
+				fragments["testfun"]		+= StringTemplate(src0Type.loadFunction).specialize({{"var", "ssbo_src0"}});
+				fragments["testfun"]		+= StringTemplate(src1Type.loadFunction).specialize({{"var", "ssbo_src1"}});
+				fragments["testfun"]		+= StringTemplate(dstType.storeFunction).specialize({{"var", "ssbo_dst"}});
 
 				specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Input0Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 				specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Input1Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 				specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16OutputDummy)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 				specResource.verifyIO = getFloat16VectorShuffleVerifyIOFunc(dstType.typeComponents, src0Type.typeComponents, src1Type.typeComponents);
 
-				extensions.push_back("VK_KHR_16bit_storage");
 				extensions.push_back("VK_KHR_shader_float16_int8");
 
 				features.extFloat16Int8		= EXTFLOAT16INT8FEATURES_FLOAT16;
-				features.ext16BitStorage	= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
 
 				finalizeTestsCreation(specResource, fragments, testCtx, *testGroup.get(), testName, features, extensions, IVec3(1, 1, 1));
 			}
@@ -12199,7 +12345,45 @@
 
 		"${consts}"
 
+		"     %c_f16_n1 = OpConstant %f16 -1.0\n"
+		"   %c_v2f16_n1 = OpConstantComposite %v2f16 %c_f16_n1 %c_f16_n1\n"
 		"      %c_u32_5 = OpConstant %u32 5\n"
+		"      %c_u32_6 = OpConstant %u32 6\n"
+		"      %c_u32_7 = OpConstant %u32 7\n"
+		"      %c_u32_8 = OpConstant %u32 8\n"
+		"      %c_u32_9 = OpConstant %u32 9\n"
+		"     %c_u32_10 = OpConstant %u32 10\n"
+		"     %c_u32_11 = OpConstant %u32 11\n"
+		"     %c_u32_12 = OpConstant %u32 12\n"
+		"     %c_u32_13 = OpConstant %u32 13\n"
+		"     %c_u32_14 = OpConstant %u32 14\n"
+		"     %c_u32_15 = OpConstant %u32 15\n"
+		"     %c_u32_16 = OpConstant %u32 16\n"
+		"     %c_u32_17 = OpConstant %u32 17\n"
+		"     %c_u32_18 = OpConstant %u32 18\n"
+		"     %c_u32_19 = OpConstant %u32 19\n"
+		"     %c_u32_20 = OpConstant %u32 20\n"
+		"     %c_u32_21 = OpConstant %u32 21\n"
+		"     %c_u32_22 = OpConstant %u32 22\n"
+		"     %c_u32_23 = OpConstant %u32 23\n"
+		"     %c_u32_24 = OpConstant %u32 24\n"
+		"     %c_u32_25 = OpConstant %u32 25\n"
+		"     %c_u32_26 = OpConstant %u32 26\n"
+		"     %c_u32_27 = OpConstant %u32 27\n"
+		"     %c_u32_28 = OpConstant %u32 28\n"
+		"     %c_u32_29 = OpConstant %u32 29\n"
+		"     %c_u32_30 = OpConstant %u32 30\n"
+		"     %c_u32_31 = OpConstant %u32 31\n"
+		"     %c_u32_33 = OpConstant %u32 33\n"
+		"     %c_u32_34 = OpConstant %u32 34\n"
+		"     %c_u32_35 = OpConstant %u32 35\n"
+		"     %c_u32_36 = OpConstant %u32 36\n"
+		"     %c_u32_37 = OpConstant %u32 37\n"
+		"     %c_u32_38 = OpConstant %u32 38\n"
+		"     %c_u32_39 = OpConstant %u32 39\n"
+		"     %c_u32_40 = OpConstant %u32 40\n"
+		"     %c_u32_41 = OpConstant %u32 41\n"
+		"     %c_u32_44 = OpConstant %u32 44\n"
 
 		" %f16arr3      = OpTypeArray %f16 %c_u32_3\n"
 		" %v2f16arr3    = OpTypeArray %v2f16 %c_u32_3\n"
@@ -12210,9 +12394,10 @@
 		" %struct16arr3 = OpTypeArray %struct16 %c_u32_3\n"
 		" %st_test      = OpTypeStruct %f16 %v2f16 %v3f16 %v4f16 %f16arr3 %struct16arr3 %v2f16arr5 %f16 %v3f16arr5 %v4f16arr3\n"
 
-		"        %up_st = OpTypePointer Uniform %st_test\n"
-		"        %ra_st = OpTypeArray %st_test %c_i32_ndp\n"
-		"      %SSBO_st = OpTypeStruct %ra_st\n"
+		"       %up_u32 = OpTypePointer Uniform %u32\n"
+		"    %ra_u32_44 = OpTypeArray %u32 %c_u32_44\n"
+		"    %ra_ra_u32 = OpTypeArray %ra_u32_44 %c_i32_ndp\n"
+		"      %SSBO_st = OpTypeStruct %ra_ra_u32\n"
 		"   %up_SSBO_st = OpTypePointer Uniform %SSBO_st\n"
 
 		"     %ssbo_dst = OpVariable %up_SSBO_st Uniform\n"
@@ -12221,7 +12406,8 @@
 	const StringTemplate decoration
 	(
 		"OpDecorate %SSBO_st BufferBlock\n"
-		"OpDecorate %ra_st ArrayStride ${struct_item_size}\n"
+		"OpDecorate %ra_u32_44 ArrayStride 4\n"
+		"OpDecorate %ra_ra_u32 ArrayStride ${struct_item_size}\n"
 		"OpDecorate %ssbo_dst DescriptorSet 0\n"
 		"OpDecorate %ssbo_dst Binding 1\n"
 
@@ -12325,8 +12511,218 @@
 		"      %fld9 = OpCompositeConstruct %v4f16arr3 %fld9_0 %fld9_1 %fld9_2\n"
 
 		"    %st_val = OpCompositeConstruct %st_test %c_f16_0 %fld1 %fld2 %fld3 %fld4 %fld5 %fld6 %c_f16_50 %fld8 %fld9\n"
-		"       %dst = OpAccessChain %up_st %ssbo_dst %c_i32_0 %ndx\n"
-		"              OpStore %dst %st_val\n"
+
+		// Storage section: all elements that are not directly accessed should
+		// have the value of -1.0. This means for f16 and v3f16 stores the v2f16
+		// is constructed with one element from a constant -1.0.
+		// half offset 0
+		"      %ex_0 = OpCompositeExtract %f16 %st_val 0\n"
+		"     %vec_0 = OpCompositeConstruct %v2f16 %ex_0 %c_f16_n1\n"
+		"      %bc_0 = OpBitcast %u32 %vec_0\n"
+		"     %gep_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_0\n"
+		"              OpStore %gep_0 %bc_0\n"
+
+		// <2 x half> offset 4
+		"      %ex_1 = OpCompositeExtract %v2f16 %st_val 1\n"
+		"      %bc_1 = OpBitcast %u32 %ex_1\n"
+		"     %gep_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_1\n"
+		"              OpStore %gep_1 %bc_1\n"
+
+		// <3 x half> offset 8
+		"      %ex_2 = OpCompositeExtract %v3f16 %st_val 2\n"
+		"    %ex_2_0 = OpVectorShuffle %v2f16 %ex_2 %c_v2f16_n1 0 1\n"
+		"    %ex_2_1 = OpVectorShuffle %v2f16 %ex_2 %c_v2f16_n1 2 3\n"
+		"    %bc_2_0 = OpBitcast %u32 %ex_2_0\n"
+		"    %bc_2_1 = OpBitcast %u32 %ex_2_1\n"
+		"   %gep_2_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_2\n"
+		"   %gep_2_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_3\n"
+		"              OpStore %gep_2_0 %bc_2_0\n"
+		"              OpStore %gep_2_1 %bc_2_1\n"
+
+		// <4 x half> offset 16
+		"      %ex_3 = OpCompositeExtract %v4f16 %st_val 3\n"
+		"    %ex_3_0 = OpVectorShuffle %v2f16 %ex_3 %ex_3 0 1\n"
+		"    %ex_3_1 = OpVectorShuffle %v2f16 %ex_3 %ex_3 2 3\n"
+		"    %bc_3_0 = OpBitcast %u32 %ex_3_0\n"
+		"    %bc_3_1 = OpBitcast %u32 %ex_3_1\n"
+		"   %gep_3_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_4\n"
+		"   %gep_3_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_5\n"
+		"              OpStore %gep_3_0 %bc_3_0\n"
+		"              OpStore %gep_3_1 %bc_3_1\n"
+
+		// [3 x half] offset 24
+		"    %ex_4_0 = OpCompositeExtract %f16 %st_val 4 0\n"
+		"    %ex_4_1 = OpCompositeExtract %f16 %st_val 4 1\n"
+		"    %ex_4_2 = OpCompositeExtract %f16 %st_val 4 2\n"
+		"   %vec_4_0 = OpCompositeConstruct %v2f16 %ex_4_0 %ex_4_1\n"
+		"   %vec_4_1 = OpCompositeConstruct %v2f16 %ex_4_2 %c_f16_n1\n"
+		"    %bc_4_0 = OpBitcast %u32 %vec_4_0\n"
+		"    %bc_4_1 = OpBitcast %u32 %vec_4_1\n"
+		"   %gep_4_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_6\n"
+		"   %gep_4_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_7\n"
+		"              OpStore %gep_4_0 %bc_4_0\n"
+		"              OpStore %gep_4_1 %bc_4_1\n"
+
+		// [3 x {half, [3 x <2 x half>]}] offset 32
+		"    %ex_5_0 = OpCompositeExtract %struct16 %st_val 5 0\n"
+		"    %ex_5_1 = OpCompositeExtract %struct16 %st_val 5 1\n"
+		"    %ex_5_2 = OpCompositeExtract %struct16 %st_val 5 2\n"
+		"  %ex_5_0_0 = OpCompositeExtract %f16 %ex_5_0 0\n"
+		"  %ex_5_1_0 = OpCompositeExtract %f16 %ex_5_1 0\n"
+		"  %ex_5_2_0 = OpCompositeExtract %f16 %ex_5_2 0\n"
+		"%ex_5_0_1_0 = OpCompositeExtract %v2f16 %ex_5_0 1 0\n"
+		"%ex_5_0_1_1 = OpCompositeExtract %v2f16 %ex_5_0 1 1\n"
+		"%ex_5_0_1_2 = OpCompositeExtract %v2f16 %ex_5_0 1 2\n"
+		"%ex_5_1_1_0 = OpCompositeExtract %v2f16 %ex_5_1 1 0\n"
+		"%ex_5_1_1_1 = OpCompositeExtract %v2f16 %ex_5_1 1 1\n"
+		"%ex_5_1_1_2 = OpCompositeExtract %v2f16 %ex_5_1 1 2\n"
+		"%ex_5_2_1_0 = OpCompositeExtract %v2f16 %ex_5_2 1 0\n"
+		"%ex_5_2_1_1 = OpCompositeExtract %v2f16 %ex_5_2 1 1\n"
+		"%ex_5_2_1_2 = OpCompositeExtract %v2f16 %ex_5_2 1 2\n"
+		" %vec_5_0_0 = OpCompositeConstruct %v2f16 %ex_5_0_0 %c_f16_n1\n"
+		" %vec_5_1_0 = OpCompositeConstruct %v2f16 %ex_5_1_0 %c_f16_n1\n"
+		" %vec_5_2_0 = OpCompositeConstruct %v2f16 %ex_5_2_0 %c_f16_n1\n"
+		"  %bc_5_0_0 = OpBitcast %u32 %vec_5_0_0\n"
+		"  %bc_5_1_0 = OpBitcast %u32 %vec_5_1_0\n"
+		"  %bc_5_2_0 = OpBitcast %u32 %vec_5_2_0\n"
+		"%bc_5_0_1_0 = OpBitcast %u32 %ex_5_0_1_0\n"
+		"%bc_5_0_1_1 = OpBitcast %u32 %ex_5_0_1_1\n"
+		"%bc_5_0_1_2 = OpBitcast %u32 %ex_5_0_1_2\n"
+		"%bc_5_1_1_0 = OpBitcast %u32 %ex_5_1_1_0\n"
+		"%bc_5_1_1_1 = OpBitcast %u32 %ex_5_1_1_1\n"
+		"%bc_5_1_1_2 = OpBitcast %u32 %ex_5_1_1_2\n"
+		"%bc_5_2_1_0 = OpBitcast %u32 %ex_5_2_1_0\n"
+		"%bc_5_2_1_1 = OpBitcast %u32 %ex_5_2_1_1\n"
+		"%bc_5_2_1_2 = OpBitcast %u32 %ex_5_2_1_2\n"
+		"  %gep_5_0_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_8\n"
+		"%gep_5_0_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_9\n"
+		"%gep_5_0_1_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_10\n"
+		"%gep_5_0_1_2 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_11\n"
+		"  %gep_5_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_12\n"
+		"%gep_5_1_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_13\n"
+		"%gep_5_1_1_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_14\n"
+		"%gep_5_1_1_2 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_15\n"
+		"  %gep_5_2_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_16\n"
+		"%gep_5_2_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_17\n"
+		"%gep_5_2_1_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_18\n"
+		"%gep_5_2_1_2 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_19\n"
+		"              OpStore %gep_5_0_0 %bc_5_0_0\n"
+		"              OpStore %gep_5_0_1_0 %bc_5_0_1_0\n"
+		"              OpStore %gep_5_0_1_1 %bc_5_0_1_1\n"
+		"              OpStore %gep_5_0_1_2 %bc_5_0_1_2\n"
+		"              OpStore %gep_5_1_0 %bc_5_1_0\n"
+		"              OpStore %gep_5_1_1_0 %bc_5_1_1_0\n"
+		"              OpStore %gep_5_1_1_1 %bc_5_1_1_1\n"
+		"              OpStore %gep_5_1_1_2 %bc_5_1_1_2\n"
+		"              OpStore %gep_5_2_0 %bc_5_2_0\n"
+		"              OpStore %gep_5_2_1_0 %bc_5_2_1_0\n"
+		"              OpStore %gep_5_2_1_1 %bc_5_2_1_1\n"
+		"              OpStore %gep_5_2_1_2 %bc_5_2_1_2\n"
+
+		// [5 x <2 x half>] offset 80
+		"    %ex_6_0 = OpCompositeExtract %v2f16 %st_val 6 0\n"
+		"    %ex_6_1 = OpCompositeExtract %v2f16 %st_val 6 1\n"
+		"    %ex_6_2 = OpCompositeExtract %v2f16 %st_val 6 2\n"
+		"    %ex_6_3 = OpCompositeExtract %v2f16 %st_val 6 3\n"
+		"    %ex_6_4 = OpCompositeExtract %v2f16 %st_val 6 4\n"
+		"    %bc_6_0 = OpBitcast %u32 %ex_6_0\n"
+		"    %bc_6_1 = OpBitcast %u32 %ex_6_1\n"
+		"    %bc_6_2 = OpBitcast %u32 %ex_6_2\n"
+		"    %bc_6_3 = OpBitcast %u32 %ex_6_3\n"
+		"    %bc_6_4 = OpBitcast %u32 %ex_6_4\n"
+		"   %gep_6_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_20\n"
+		"   %gep_6_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_21\n"
+		"   %gep_6_2 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_22\n"
+		"   %gep_6_3 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_23\n"
+		"   %gep_6_4 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_24\n"
+		"              OpStore %gep_6_0 %bc_6_0\n"
+		"              OpStore %gep_6_1 %bc_6_1\n"
+		"              OpStore %gep_6_2 %bc_6_2\n"
+		"              OpStore %gep_6_3 %bc_6_3\n"
+		"              OpStore %gep_6_4 %bc_6_4\n"
+
+		// half offset 100
+		"      %ex_7 = OpCompositeExtract %f16 %st_val 7\n"
+		"     %vec_7 = OpCompositeConstruct %v2f16 %ex_7 %c_f16_n1\n"
+		"      %bc_7 = OpBitcast %u32 %vec_7\n"
+		"     %gep_7 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_25\n"
+		"              OpStore %gep_7 %bc_7\n"
+
+		// [5 x <3 x half>] offset 104
+		"    %ex_8_0 = OpCompositeExtract %v3f16 %st_val 8 0\n"
+		"    %ex_8_1 = OpCompositeExtract %v3f16 %st_val 8 1\n"
+		"    %ex_8_2 = OpCompositeExtract %v3f16 %st_val 8 2\n"
+		"    %ex_8_3 = OpCompositeExtract %v3f16 %st_val 8 3\n"
+		"    %ex_8_4 = OpCompositeExtract %v3f16 %st_val 8 4\n"
+		" %vec_8_0_0 = OpVectorShuffle %v2f16 %ex_8_0 %c_v2f16_n1 0 1\n"
+		" %vec_8_0_1 = OpVectorShuffle %v2f16 %ex_8_0 %c_v2f16_n1 2 3\n"
+		" %vec_8_1_0 = OpVectorShuffle %v2f16 %ex_8_1 %c_v2f16_n1 0 1\n"
+		" %vec_8_1_1 = OpVectorShuffle %v2f16 %ex_8_1 %c_v2f16_n1 2 3\n"
+		" %vec_8_2_0 = OpVectorShuffle %v2f16 %ex_8_2 %c_v2f16_n1 0 1\n"
+		" %vec_8_2_1 = OpVectorShuffle %v2f16 %ex_8_2 %c_v2f16_n1 2 3\n"
+		" %vec_8_3_0 = OpVectorShuffle %v2f16 %ex_8_3 %c_v2f16_n1 0 1\n"
+		" %vec_8_3_1 = OpVectorShuffle %v2f16 %ex_8_3 %c_v2f16_n1 2 3\n"
+		" %vec_8_4_0 = OpVectorShuffle %v2f16 %ex_8_4 %c_v2f16_n1 0 1\n"
+		" %vec_8_4_1 = OpVectorShuffle %v2f16 %ex_8_4 %c_v2f16_n1 2 3\n"
+		"  %bc_8_0_0 = OpBitcast %u32 %vec_8_0_0\n"
+		"  %bc_8_0_1 = OpBitcast %u32 %vec_8_0_1\n"
+		"  %bc_8_1_0 = OpBitcast %u32 %vec_8_1_0\n"
+		"  %bc_8_1_1 = OpBitcast %u32 %vec_8_1_1\n"
+		"  %bc_8_2_0 = OpBitcast %u32 %vec_8_2_0\n"
+		"  %bc_8_2_1 = OpBitcast %u32 %vec_8_2_1\n"
+		"  %bc_8_3_0 = OpBitcast %u32 %vec_8_3_0\n"
+		"  %bc_8_3_1 = OpBitcast %u32 %vec_8_3_1\n"
+		"  %bc_8_4_0 = OpBitcast %u32 %vec_8_4_0\n"
+		"  %bc_8_4_1 = OpBitcast %u32 %vec_8_4_1\n"
+		" %gep_8_0_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_26\n"
+		" %gep_8_0_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_27\n"
+		" %gep_8_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_28\n"
+		" %gep_8_1_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_29\n"
+		" %gep_8_2_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_30\n"
+		" %gep_8_2_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_31\n"
+		" %gep_8_3_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_32\n"
+		" %gep_8_3_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_33\n"
+		" %gep_8_4_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_34\n"
+		" %gep_8_4_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_35\n"
+		"              OpStore %gep_8_0_0 %bc_8_0_0\n"
+		"              OpStore %gep_8_0_1 %bc_8_0_1\n"
+		"              OpStore %gep_8_1_0 %bc_8_1_0\n"
+		"              OpStore %gep_8_1_1 %bc_8_1_1\n"
+		"              OpStore %gep_8_2_0 %bc_8_2_0\n"
+		"              OpStore %gep_8_2_1 %bc_8_2_1\n"
+		"              OpStore %gep_8_3_0 %bc_8_3_0\n"
+		"              OpStore %gep_8_3_1 %bc_8_3_1\n"
+		"              OpStore %gep_8_4_0 %bc_8_4_0\n"
+		"              OpStore %gep_8_4_1 %bc_8_4_1\n"
+
+		// [3 x <4 x half>] offset 144
+		"    %ex_9_0 = OpCompositeExtract %v4f16 %st_val 9 0\n"
+		"    %ex_9_1 = OpCompositeExtract %v4f16 %st_val 9 1\n"
+		"    %ex_9_2 = OpCompositeExtract %v4f16 %st_val 9 2\n"
+		" %vec_9_0_0 = OpVectorShuffle %v2f16 %ex_9_0 %ex_9_0 0 1\n"
+		" %vec_9_0_1 = OpVectorShuffle %v2f16 %ex_9_0 %ex_9_0 2 3\n"
+		" %vec_9_1_0 = OpVectorShuffle %v2f16 %ex_9_1 %ex_9_1 0 1\n"
+		" %vec_9_1_1 = OpVectorShuffle %v2f16 %ex_9_1 %ex_9_1 2 3\n"
+		" %vec_9_2_0 = OpVectorShuffle %v2f16 %ex_9_2 %ex_9_2 0 1\n"
+		" %vec_9_2_1 = OpVectorShuffle %v2f16 %ex_9_2 %ex_9_2 2 3\n"
+		"  %bc_9_0_0 = OpBitcast %u32 %vec_9_0_0\n"
+		"  %bc_9_0_1 = OpBitcast %u32 %vec_9_0_1\n"
+		"  %bc_9_1_0 = OpBitcast %u32 %vec_9_1_0\n"
+		"  %bc_9_1_1 = OpBitcast %u32 %vec_9_1_1\n"
+		"  %bc_9_2_0 = OpBitcast %u32 %vec_9_2_0\n"
+		"  %bc_9_2_1 = OpBitcast %u32 %vec_9_2_1\n"
+		" %gep_9_0_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_36\n"
+		" %gep_9_0_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_37\n"
+		" %gep_9_1_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_38\n"
+		" %gep_9_1_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_39\n"
+		" %gep_9_2_0 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_40\n"
+		" %gep_9_2_1 = OpAccessChain %up_u32 %ssbo_dst %c_u32_0 %ndx %c_u32_41\n"
+		"              OpStore %gep_9_0_0 %bc_9_0_0\n"
+		"              OpStore %gep_9_0_1 %bc_9_0_1\n"
+		"              OpStore %gep_9_1_0 %bc_9_1_0\n"
+		"              OpStore %gep_9_1_1 %bc_9_1_1\n"
+		"              OpStore %gep_9_2_0 %bc_9_2_0\n"
+		"              OpStore %gep_9_2_1 %bc_9_2_1\n"
 
 		"              OpBranch %next\n"
 
@@ -12376,8 +12772,7 @@
 		specs["field_modifier"]		= de::toString(fieldModifier);
 		specs["consts"]				= consts;
 
-		fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"";
-		fragments["capability"]		= "OpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
+		fragments["capability"]		= "OpCapability Float16\n";
 		fragments["decoration"]		= decoration.specialize(specs);
 		fragments["pre_main"]		= preMain.specialize(specs);
 		fragments["testfun"]		= testFun.specialize(specs);
@@ -12386,11 +12781,9 @@
 		specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.verifyIO = compareFP16CompositeFunc;
 
-		extensions.push_back("VK_KHR_16bit_storage");
 		extensions.push_back("VK_KHR_shader_float16_int8");
 
 		features.extFloat16Int8		= EXTFLOAT16INT8FEATURES_FLOAT16;
-		features.ext16BitStorage	= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
 
 		finalizeTestsCreation(specResource, fragments, testCtx, *testGroup.get(), testName, features, extensions, IVec3(1, 1, 1));
 	}
@@ -12411,12 +12804,24 @@
 	const StringTemplate preMain
 	(
 		"   %c_i32_ndp = OpConstant %i32 ${num_elements}\n"
+		"  %c_i32_hndp = OpSpecConstantOp %i32 SDiv %c_i32_ndp %c_i32_2\n"
+		"  %c_i32_size = OpConstant %i32 ${struct_u32s}\n"
+		"%c_u32_high_ones = OpConstant %u32 0xffff0000\n"
+		" %c_u32_low_ones = OpConstant %u32 0x0000ffff\n"
 		"         %f16 = OpTypeFloat 16\n"
 		"       %v2f16 = OpTypeVector %f16 2\n"
 		"       %v3f16 = OpTypeVector %f16 3\n"
 		"       %v4f16 = OpTypeVector %f16 4\n"
 		"    %c_f16_na = OpConstant %f16 -1.0\n"
+		"  %c_v2f16_n1 = OpConstantComposite %v2f16 %c_f16_na %c_f16_na\n"
 		"     %c_u32_5 = OpConstant %u32 5\n"
+		"     %c_i32_5 = OpConstant %i32 5\n"
+		"     %c_i32_6 = OpConstant %i32 6\n"
+		"     %c_i32_7 = OpConstant %i32 7\n"
+		"     %c_i32_8 = OpConstant %i32 8\n"
+		"     %c_i32_9 = OpConstant %i32 9\n"
+		"    %c_i32_10 = OpConstant %i32 10\n"
+		"    %c_i32_11 = OpConstant %i32 11\n"
 
 		"%f16arr3      = OpTypeArray %f16 %c_u32_3\n"
 		"%v2f16arr3    = OpTypeArray %v2f16 %c_u32_3\n"
@@ -12427,10 +12832,15 @@
 		"%struct16arr3 = OpTypeArray %struct16 %c_u32_3\n"
 		"%st_test      = OpTypeStruct %${field_type}\n"
 
-		"      %up_f16 = OpTypePointer Uniform %f16\n"
-		"       %up_st = OpTypePointer Uniform %st_test\n"
-		"      %ra_f16 = OpTypeArray %f16 %c_i32_ndp\n"
-		"       %ra_st = OpTypeArray %st_test %c_i32_1\n"
+		"      %ra_f16 = OpTypeArray %u32 %c_i32_hndp\n"
+		"       %ra_st = OpTypeArray %u32 %c_i32_size\n"
+		"      %up_u32 = OpTypePointer Uniform %u32\n"
+		"     %st_test_i32_fn = OpTypeFunction %st_test %i32\n"
+		"%void_st_test_i32_fn = OpTypeFunction %void %st_test %i32\n"
+		"         %f16_i32_fn = OpTypeFunction %f16 %i32\n"
+		"    %void_f16_i32_fn = OpTypeFunction %void %f16 %i32\n"
+		"       %v2f16_i32_fn = OpTypeFunction %v2f16 %i32\n"
+		"  %void_v2f16_i32_fn = OpTypeFunction %void %v2f16 %i32\n"
 
 		"${op_premain_decls}"
 
@@ -12445,8 +12855,8 @@
 	(
 		"OpDecorate %SSBO_src BufferBlock\n"
 		"OpDecorate %SSBO_dst BufferBlock\n"
-		"OpDecorate %ra_f16 ArrayStride 2\n"
-		"OpDecorate %ra_st ArrayStride ${struct_item_size}\n"
+		"OpDecorate %ra_f16 ArrayStride 4\n"
+		"OpDecorate %ra_st ArrayStride 4\n"
 		"OpDecorate %ssbo_src DescriptorSet 0\n"
 		"OpDecorate %ssbo_src Binding 0\n"
 		"OpDecorate %ssbo_dst DescriptorSet 0\n"
@@ -12494,7 +12904,7 @@
 
 		"${op_sw_fun_call}"
 
-		"              OpStore %dst %val_dst\n"
+		"    %dst_st = OpFunctionCall %void %${st_call} %val_dst %${st_ndx}\n"
 		"              OpBranch %next\n"
 
 		"      %next = OpLabel\n"
@@ -12532,6 +12942,515 @@
 		"             OpReturnValue %val_ret_${case_ndx}\n"
 	);
 
+	const string loadF16
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"   %ld_${var}_call = OpFunctionCall %f16 %ld_arg_${var} %ld_${var}_param\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_call\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n" +
+		loadScalarF16FromUint
+	);
+
+	const string loadV2F16
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"   %ld_${var}_call = OpFunctionCall %v2f16 %ld_arg_${var} %ld_${var}_param\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_call\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n" +
+		loadV2F16FromUint
+	);
+
+	const string loadV3F16
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"  %ld_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"  %ld_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"   %ld_${var}_ld_0 = OpLoad %u32 %ld_${var}_gep_0\n"
+		"   %ld_${var}_ld_1 = OpLoad %u32 %ld_${var}_gep_1\n"
+		"   %ld_${var}_bc_0 = OpBitcast %v2f16 %ld_${var}_ld_0\n"
+		"   %ld_${var}_bc_1 = OpBitcast %v2f16 %ld_${var}_ld_1\n"
+		"    %ld_${var}_vec = OpVectorShuffle %v3f16 %ld_${var}_bc_0 %ld_${var}_bc_1 0 1 2\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_vec\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadV4F16
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"  %ld_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"  %ld_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"   %ld_${var}_ld_0 = OpLoad %u32 %ld_${var}_gep_0\n"
+		"   %ld_${var}_ld_1 = OpLoad %u32 %ld_${var}_gep_1\n"
+		"   %ld_${var}_bc_0 = OpBitcast %v2f16 %ld_${var}_ld_0\n"
+		"   %ld_${var}_bc_1 = OpBitcast %v2f16 %ld_${var}_ld_1\n"
+		"    %ld_${var}_vec = OpVectorShuffle %v4f16 %ld_${var}_bc_0 %ld_${var}_bc_1 0 1 2 3\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_vec\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadF16Arr3
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"  %ld_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_u32_0 %c_u32_0\n"
+		"  %ld_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_u32_0 %c_u32_1\n"
+		"   %ld_${var}_ld_0 = OpLoad %u32 %ld_${var}_gep_0\n"
+		"   %ld_${var}_ld_1 = OpLoad %u32 %ld_${var}_gep_1\n"
+		"   %ld_${var}_bc_0 = OpBitcast %v2f16 %ld_${var}_ld_0\n"
+		"   %ld_${var}_bc_1 = OpBitcast %v2f16 %ld_${var}_ld_1\n"
+		"   %ld_${var}_ex_0 = OpCompositeExtract %f16 %ld_${var}_bc_0 0\n"
+		"   %ld_${var}_ex_1 = OpCompositeExtract %f16 %ld_${var}_bc_0 1\n"
+		"   %ld_${var}_ex_2 = OpCompositeExtract %f16 %ld_${var}_bc_1 0\n"
+		"   %ld_${var}_cons = OpCompositeConstruct %f16arr3 %ld_${var}_ex_0 %ld_${var}_ex_1 %ld_${var}_ex_2\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_cons\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadV2F16Arr5
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_label = OpLabel\n"
+		"  %ld_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"  %ld_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"  %ld_${var}_gep_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"  %ld_${var}_gep_3 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"  %ld_${var}_gep_4 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"   %ld_${var}_ld_0 = OpLoad %u32 %ld_${var}_gep_0\n"
+		"   %ld_${var}_ld_1 = OpLoad %u32 %ld_${var}_gep_1\n"
+		"   %ld_${var}_ld_2 = OpLoad %u32 %ld_${var}_gep_2\n"
+		"   %ld_${var}_ld_3 = OpLoad %u32 %ld_${var}_gep_3\n"
+		"   %ld_${var}_ld_4 = OpLoad %u32 %ld_${var}_gep_4\n"
+		"   %ld_${var}_bc_0 = OpBitcast %v2f16 %ld_${var}_ld_0\n"
+		"   %ld_${var}_bc_1 = OpBitcast %v2f16 %ld_${var}_ld_1\n"
+		"   %ld_${var}_bc_2 = OpBitcast %v2f16 %ld_${var}_ld_2\n"
+		"   %ld_${var}_bc_3 = OpBitcast %v2f16 %ld_${var}_ld_3\n"
+		"   %ld_${var}_bc_4 = OpBitcast %v2f16 %ld_${var}_ld_4\n"
+		"   %ld_${var}_cons = OpCompositeConstruct %v2f16arr5 %ld_${var}_bc_0 %ld_${var}_bc_1 %ld_${var}_bc_2 %ld_${var}_bc_3 %ld_${var}_bc_4\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_cons\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadV3F16Arr5
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"%ld_${var}_gep_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"%ld_${var}_gep_0_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"%ld_${var}_gep_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"%ld_${var}_gep_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"%ld_${var}_gep_2_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"%ld_${var}_gep_2_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		"%ld_${var}_gep_3_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_6\n"
+		"%ld_${var}_gep_3_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_7\n"
+		"%ld_${var}_gep_4_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_8\n"
+		"%ld_${var}_gep_4_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_9\n"
+		" %ld_${var}_ld_0_0 = OpLoad %u32 %ld_${var}_gep_0_0\n"
+		" %ld_${var}_ld_0_1 = OpLoad %u32 %ld_${var}_gep_0_1\n"
+		" %ld_${var}_ld_1_0 = OpLoad %u32 %ld_${var}_gep_1_0\n"
+		" %ld_${var}_ld_1_1 = OpLoad %u32 %ld_${var}_gep_1_1\n"
+		" %ld_${var}_ld_2_0 = OpLoad %u32 %ld_${var}_gep_2_0\n"
+		" %ld_${var}_ld_2_1 = OpLoad %u32 %ld_${var}_gep_2_1\n"
+		" %ld_${var}_ld_3_0 = OpLoad %u32 %ld_${var}_gep_3_0\n"
+		" %ld_${var}_ld_3_1 = OpLoad %u32 %ld_${var}_gep_3_1\n"
+		" %ld_${var}_ld_4_0 = OpLoad %u32 %ld_${var}_gep_4_0\n"
+		" %ld_${var}_ld_4_1 = OpLoad %u32 %ld_${var}_gep_4_1\n"
+		" %ld_${var}_bc_0_0 = OpBitcast %v2f16 %ld_${var}_ld_0_0\n"
+		" %ld_${var}_bc_0_1 = OpBitcast %v2f16 %ld_${var}_ld_0_1\n"
+		" %ld_${var}_bc_1_0 = OpBitcast %v2f16 %ld_${var}_ld_1_0\n"
+		" %ld_${var}_bc_1_1 = OpBitcast %v2f16 %ld_${var}_ld_1_1\n"
+		" %ld_${var}_bc_2_0 = OpBitcast %v2f16 %ld_${var}_ld_2_0\n"
+		" %ld_${var}_bc_2_1 = OpBitcast %v2f16 %ld_${var}_ld_2_1\n"
+		" %ld_${var}_bc_3_0 = OpBitcast %v2f16 %ld_${var}_ld_3_0\n"
+		" %ld_${var}_bc_3_1 = OpBitcast %v2f16 %ld_${var}_ld_3_1\n"
+		" %ld_${var}_bc_4_0 = OpBitcast %v2f16 %ld_${var}_ld_4_0\n"
+		" %ld_${var}_bc_4_1 = OpBitcast %v2f16 %ld_${var}_ld_4_1\n"
+		"  %ld_${var}_vec_0 = OpVectorShuffle %v3f16 %ld_${var}_bc_0_0 %ld_${var}_bc_0_1 0 1 2\n"
+		"  %ld_${var}_vec_1 = OpVectorShuffle %v3f16 %ld_${var}_bc_1_0 %ld_${var}_bc_1_1 0 1 2\n"
+		"  %ld_${var}_vec_2 = OpVectorShuffle %v3f16 %ld_${var}_bc_2_0 %ld_${var}_bc_2_1 0 1 2\n"
+		"  %ld_${var}_vec_3 = OpVectorShuffle %v3f16 %ld_${var}_bc_3_0 %ld_${var}_bc_3_1 0 1 2\n"
+		"  %ld_${var}_vec_4 = OpVectorShuffle %v3f16 %ld_${var}_bc_4_0 %ld_${var}_bc_4_1 0 1 2\n"
+		"   %ld_${var}_cons = OpCompositeConstruct %v3f16arr5 %ld_${var}_vec_0 %ld_${var}_vec_1 %ld_${var}_vec_2 %ld_${var}_vec_3 %ld_${var}_vec_4\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_cons\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadV4F16Arr3
+	(
+		"        %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"  %ld_${var}_param = OpFunctionParameter %i32\n"
+		"  %ld_${var}_entry = OpLabel\n"
+		"%ld_${var}_gep_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"%ld_${var}_gep_0_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"%ld_${var}_gep_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"%ld_${var}_gep_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"%ld_${var}_gep_2_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"%ld_${var}_gep_2_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		" %ld_${var}_ld_0_0 = OpLoad %u32 %ld_${var}_gep_0_0\n"
+		" %ld_${var}_ld_0_1 = OpLoad %u32 %ld_${var}_gep_0_1\n"
+		" %ld_${var}_ld_1_0 = OpLoad %u32 %ld_${var}_gep_1_0\n"
+		" %ld_${var}_ld_1_1 = OpLoad %u32 %ld_${var}_gep_1_1\n"
+		" %ld_${var}_ld_2_0 = OpLoad %u32 %ld_${var}_gep_2_0\n"
+		" %ld_${var}_ld_2_1 = OpLoad %u32 %ld_${var}_gep_2_1\n"
+		" %ld_${var}_bc_0_0 = OpBitcast %v2f16 %ld_${var}_ld_0_0\n"
+		" %ld_${var}_bc_0_1 = OpBitcast %v2f16 %ld_${var}_ld_0_1\n"
+		" %ld_${var}_bc_1_0 = OpBitcast %v2f16 %ld_${var}_ld_1_0\n"
+		" %ld_${var}_bc_1_1 = OpBitcast %v2f16 %ld_${var}_ld_1_1\n"
+		" %ld_${var}_bc_2_0 = OpBitcast %v2f16 %ld_${var}_ld_2_0\n"
+		" %ld_${var}_bc_2_1 = OpBitcast %v2f16 %ld_${var}_ld_2_1\n"
+		"  %ld_${var}_vec_0 = OpVectorShuffle %v4f16 %ld_${var}_bc_0_0 %ld_${var}_bc_0_1 0 1 2 3\n"
+		"  %ld_${var}_vec_1 = OpVectorShuffle %v4f16 %ld_${var}_bc_1_0 %ld_${var}_bc_1_1 0 1 2 3\n"
+		"  %ld_${var}_vec_2 = OpVectorShuffle %v4f16 %ld_${var}_bc_2_0 %ld_${var}_bc_2_1 0 1 2 3\n"
+		"   %ld_${var}_cons = OpCompositeConstruct %v4f16arr3 %ld_${var}_vec_0 %ld_${var}_vec_1 %ld_${var}_vec_2\n"
+		"%ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_cons\n"
+		"                     OpReturnValue %ld_${var}_st_test\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string loadStruct16Arr3
+	(
+		"          %ld_${var} = OpFunction %st_test None %st_test_i32_fn\n"
+		"    %ld_${var}_param = OpFunctionParameter %i32\n"
+		"    %ld_${var}_entry = OpLabel\n"
+		"%ld_${var}_gep_0_0   = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"%ld_${var}_gep_0_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"%ld_${var}_gep_0_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"%ld_${var}_gep_0_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"%ld_${var}_gep_1_0   = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"%ld_${var}_gep_1_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		"%ld_${var}_gep_1_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_6\n"
+		"%ld_${var}_gep_1_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_7\n"
+		"%ld_${var}_gep_2_0   = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_8\n"
+		"%ld_${var}_gep_2_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_9\n"
+		"%ld_${var}_gep_2_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_10\n"
+		"%ld_${var}_gep_2_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_11\n"
+		" %ld_${var}_ld_0_0   = OpLoad %u32 %ld_${var}_gep_0_0\n"
+		" %ld_${var}_ld_0_1_0 = OpLoad %u32 %ld_${var}_gep_0_1_0\n"
+		" %ld_${var}_ld_0_1_1 = OpLoad %u32 %ld_${var}_gep_0_1_1\n"
+		" %ld_${var}_ld_0_1_2 = OpLoad %u32 %ld_${var}_gep_0_1_2\n"
+		" %ld_${var}_ld_1_0   = OpLoad %u32 %ld_${var}_gep_1_0\n"
+		" %ld_${var}_ld_1_1_0 = OpLoad %u32 %ld_${var}_gep_1_1_0\n"
+		" %ld_${var}_ld_1_1_1 = OpLoad %u32 %ld_${var}_gep_1_1_1\n"
+		" %ld_${var}_ld_1_1_2 = OpLoad %u32 %ld_${var}_gep_1_1_2\n"
+		" %ld_${var}_ld_2_0   = OpLoad %u32 %ld_${var}_gep_2_0\n"
+		" %ld_${var}_ld_2_1_0 = OpLoad %u32 %ld_${var}_gep_2_1_0\n"
+		" %ld_${var}_ld_2_1_1 = OpLoad %u32 %ld_${var}_gep_2_1_1\n"
+		" %ld_${var}_ld_2_1_2 = OpLoad %u32 %ld_${var}_gep_2_1_2\n"
+		" %ld_${var}_bc_0_0   = OpBitcast %v2f16 %ld_${var}_ld_0_0\n"
+		" %ld_${var}_bc_0_1_0 = OpBitcast %v2f16 %ld_${var}_ld_0_1_0\n"
+		" %ld_${var}_bc_0_1_1 = OpBitcast %v2f16 %ld_${var}_ld_0_1_1\n"
+		" %ld_${var}_bc_0_1_2 = OpBitcast %v2f16 %ld_${var}_ld_0_1_2\n"
+		" %ld_${var}_bc_1_0   = OpBitcast %v2f16 %ld_${var}_ld_1_0\n"
+		" %ld_${var}_bc_1_1_0 = OpBitcast %v2f16 %ld_${var}_ld_1_1_0\n"
+		" %ld_${var}_bc_1_1_1 = OpBitcast %v2f16 %ld_${var}_ld_1_1_1\n"
+		" %ld_${var}_bc_1_1_2 = OpBitcast %v2f16 %ld_${var}_ld_1_1_2\n"
+		" %ld_${var}_bc_2_0   = OpBitcast %v2f16 %ld_${var}_ld_2_0\n"
+		" %ld_${var}_bc_2_1_0 = OpBitcast %v2f16 %ld_${var}_ld_2_1_0\n"
+		" %ld_${var}_bc_2_1_1 = OpBitcast %v2f16 %ld_${var}_ld_2_1_1\n"
+		" %ld_${var}_bc_2_1_2 = OpBitcast %v2f16 %ld_${var}_ld_2_1_2\n"
+		"    %ld_${var}_arr_0 = OpCompositeConstruct %v2f16arr3 %ld_${var}_bc_0_1_0 %ld_${var}_bc_0_1_1 %ld_${var}_bc_0_1_2\n"
+		"    %ld_${var}_arr_1 = OpCompositeConstruct %v2f16arr3 %ld_${var}_bc_1_1_0 %ld_${var}_bc_1_1_1 %ld_${var}_bc_1_1_2\n"
+		"    %ld_${var}_arr_2 = OpCompositeConstruct %v2f16arr3 %ld_${var}_bc_2_1_0 %ld_${var}_bc_2_1_1 %ld_${var}_bc_2_1_2\n"
+		"     %ld_${var}_ex_0 = OpCompositeExtract %f16 %ld_${var}_bc_0_0 0\n"
+		"     %ld_${var}_ex_1 = OpCompositeExtract %f16 %ld_${var}_bc_1_0 0\n"
+		"     %ld_${var}_ex_2 = OpCompositeExtract %f16 %ld_${var}_bc_2_0 0\n"
+		"     %ld_${var}_st_0 = OpCompositeConstruct %struct16 %ld_${var}_ex_0 %ld_${var}_arr_0\n"
+		"     %ld_${var}_st_1 = OpCompositeConstruct %struct16 %ld_${var}_ex_1 %ld_${var}_arr_1\n"
+		"     %ld_${var}_st_2 = OpCompositeConstruct %struct16 %ld_${var}_ex_2 %ld_${var}_arr_2\n"
+		"     %ld_${var}_cons = OpCompositeConstruct %struct16arr3 %ld_${var}_st_0 %ld_${var}_st_1 %ld_${var}_st_2\n"
+		"  %ld_${var}_st_test = OpCompositeConstruct %st_test %ld_${var}_cons\n"
+		"                       OpReturnValue %ld_${var}_st_test\n"
+		"                      OpFunctionEnd\n"
+	);
+
+	const string storeF16
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"    %st_${var}_ex = OpCompositeExtract %f16 %st_${var}_param1 0\n"
+		"  %st_${var}_call = OpFunctionCall %void %st_fn_${var} %st_${var}_ex %st_${var}_param2\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n" +
+		storeScalarF16AsUint
+	);
+
+	const string storeV2F16
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"    %st_${var}_ex = OpCompositeExtract %v2f16 %st_${var}_param1 0\n"
+		"  %st_${var}_call = OpFunctionCall %void %st_fn_${var} %st_${var}_ex %st_${var}_param2\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n" +
+		storeV2F16AsUint
+	);
+
+	const string storeV3F16
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"    %st_${var}_ex = OpCompositeExtract %v3f16 %st_${var}_param1 0\n"
+		" %st_${var}_vec_0 = OpVectorShuffle %v2f16 %st_${var}_ex %c_v2f16_n1 0 1\n"
+		" %st_${var}_vec_1 = OpVectorShuffle %v2f16 %st_${var}_ex %c_v2f16_n1 2 3\n"
+		"  %st_${var}_bc_0 = OpBitcast %u32 %st_${var}_vec_0\n"
+		"  %st_${var}_bc_1 = OpBitcast %u32 %st_${var}_vec_1\n"
+		" %st_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		" %st_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"                    OpStore %st_${var}_gep_0 %st_${var}_bc_0\n"
+		"                    OpStore %st_${var}_gep_1 %st_${var}_bc_1\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n"
+	);
+
+	const string storeV4F16
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"    %st_${var}_ex = OpCompositeExtract %v4f16 %st_${var}_param1 0\n"
+		" %st_${var}_vec_0 = OpVectorShuffle %v2f16 %st_${var}_ex %c_v2f16_n1 0 1\n"
+		" %st_${var}_vec_1 = OpVectorShuffle %v2f16 %st_${var}_ex %c_v2f16_n1 2 3\n"
+		"  %st_${var}_bc_0 = OpBitcast %u32 %st_${var}_vec_0\n"
+		"  %st_${var}_bc_1 = OpBitcast %u32 %st_${var}_vec_1\n"
+		" %st_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		" %st_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"                    OpStore %st_${var}_gep_0 %st_${var}_bc_0\n"
+		"                    OpStore %st_${var}_gep_1 %st_${var}_bc_1\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n"
+	);
+
+	const string storeF16Arr3
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"  %st_${var}_ex_0 = OpCompositeExtract %f16 %st_${var}_param1 0 0\n"
+		"  %st_${var}_ex_1 = OpCompositeExtract %f16 %st_${var}_param1 0 1\n"
+		"  %st_${var}_ex_2 = OpCompositeExtract %f16 %st_${var}_param1 0 2\n"
+		" %st_${var}_vec_0 = OpCompositeConstruct %v2f16 %st_${var}_ex_0 %st_${var}_ex_1\n"
+		" %st_${var}_vec_1 = OpCompositeConstruct %v2f16 %st_${var}_ex_2 %c_f16_na\n"
+		"  %st_${var}_bc_0 = OpBitcast %u32 %st_${var}_vec_0\n"
+		"  %st_${var}_bc_1 = OpBitcast %u32 %st_${var}_vec_1\n"
+		" %st_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		" %st_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"                    OpStore %st_${var}_gep_0 %st_${var}_bc_0\n"
+		"                    OpStore %st_${var}_gep_1 %st_${var}_bc_1\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n"
+	);
+
+	const string storeV2F16Arr5
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"  %st_${var}_ex_0 = OpCompositeExtract %v2f16 %st_${var}_param1 0 0\n"
+		"  %st_${var}_ex_1 = OpCompositeExtract %v2f16 %st_${var}_param1 0 1\n"
+		"  %st_${var}_ex_2 = OpCompositeExtract %v2f16 %st_${var}_param1 0 2\n"
+		"  %st_${var}_ex_3 = OpCompositeExtract %v2f16 %st_${var}_param1 0 3\n"
+		"  %st_${var}_ex_4 = OpCompositeExtract %v2f16 %st_${var}_param1 0 4\n"
+		"  %st_${var}_bc_0 = OpBitcast %u32 %st_${var}_ex_0\n"
+		"  %st_${var}_bc_1 = OpBitcast %u32 %st_${var}_ex_1\n"
+		"  %st_${var}_bc_2 = OpBitcast %u32 %st_${var}_ex_2\n"
+		"  %st_${var}_bc_3 = OpBitcast %u32 %st_${var}_ex_3\n"
+		"  %st_${var}_bc_4 = OpBitcast %u32 %st_${var}_ex_4\n"
+		" %st_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		" %st_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		" %st_${var}_gep_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		" %st_${var}_gep_3 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		" %st_${var}_gep_4 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"                    OpStore %st_${var}_gep_0 %st_${var}_bc_0\n"
+		"                    OpStore %st_${var}_gep_1 %st_${var}_bc_1\n"
+		"                    OpStore %st_${var}_gep_2 %st_${var}_bc_2\n"
+		"                    OpStore %st_${var}_gep_3 %st_${var}_bc_3\n"
+		"                    OpStore %st_${var}_gep_4 %st_${var}_bc_4\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n"
+	);
+
+	const string storeV3F16Arr5
+	(
+		"       %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"%st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"%st_${var}_param2 = OpFunctionParameter %i32\n"
+		" %st_${var}_entry = OpLabel\n"
+		"  %st_${var}_ex_0 = OpCompositeExtract %v3f16 %st_${var}_param1 0 0\n"
+		"  %st_${var}_ex_1 = OpCompositeExtract %v3f16 %st_${var}_param1 0 1\n"
+		"  %st_${var}_ex_2 = OpCompositeExtract %v3f16 %st_${var}_param1 0 2\n"
+		"  %st_${var}_ex_3 = OpCompositeExtract %v3f16 %st_${var}_param1 0 3\n"
+		"  %st_${var}_ex_4 = OpCompositeExtract %v3f16 %st_${var}_param1 0 4\n"
+		"%st_${var}_v2_0_0 = OpVectorShuffle %v2f16 %st_${var}_ex_0 %c_v2f16_n1 0 1\n"
+		"%st_${var}_v2_0_1 = OpVectorShuffle %v2f16 %st_${var}_ex_0 %c_v2f16_n1 2 3\n"
+		"%st_${var}_v2_1_0 = OpVectorShuffle %v2f16 %st_${var}_ex_1 %c_v2f16_n1 0 1\n"
+		"%st_${var}_v2_1_1 = OpVectorShuffle %v2f16 %st_${var}_ex_1 %c_v2f16_n1 2 3\n"
+		"%st_${var}_v2_2_0 = OpVectorShuffle %v2f16 %st_${var}_ex_2 %c_v2f16_n1 0 1\n"
+		"%st_${var}_v2_2_1 = OpVectorShuffle %v2f16 %st_${var}_ex_2 %c_v2f16_n1 2 3\n"
+		"%st_${var}_v2_3_0 = OpVectorShuffle %v2f16 %st_${var}_ex_3 %c_v2f16_n1 0 1\n"
+		"%st_${var}_v2_3_1 = OpVectorShuffle %v2f16 %st_${var}_ex_3 %c_v2f16_n1 2 3\n"
+		"%st_${var}_v2_4_0 = OpVectorShuffle %v2f16 %st_${var}_ex_4 %c_v2f16_n1 0 1\n"
+		"%st_${var}_v2_4_1 = OpVectorShuffle %v2f16 %st_${var}_ex_4 %c_v2f16_n1 2 3\n"
+		"%st_${var}_bc_0_0 = OpBitcast %u32 %st_${var}_v2_0_0\n"
+		"%st_${var}_bc_0_1 = OpBitcast %u32 %st_${var}_v2_0_1\n"
+		"%st_${var}_bc_1_0 = OpBitcast %u32 %st_${var}_v2_1_0\n"
+		"%st_${var}_bc_1_1 = OpBitcast %u32 %st_${var}_v2_1_1\n"
+		"%st_${var}_bc_2_0 = OpBitcast %u32 %st_${var}_v2_2_0\n"
+		"%st_${var}_bc_2_1 = OpBitcast %u32 %st_${var}_v2_2_1\n"
+		"%st_${var}_bc_3_0 = OpBitcast %u32 %st_${var}_v2_3_0\n"
+		"%st_${var}_bc_3_1 = OpBitcast %u32 %st_${var}_v2_3_1\n"
+		"%st_${var}_bc_4_0 = OpBitcast %u32 %st_${var}_v2_4_0\n"
+		"%st_${var}_bc_4_1 = OpBitcast %u32 %st_${var}_v2_4_1\n"
+		" %st_${var}_gep_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		" %st_${var}_gep_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		" %st_${var}_gep_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		" %st_${var}_gep_3 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		" %st_${var}_gep_4 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		" %st_${var}_gep_5 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		" %st_${var}_gep_6 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_6\n"
+		" %st_${var}_gep_7 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_7\n"
+		" %st_${var}_gep_8 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_8\n"
+		" %st_${var}_gep_9 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_9\n"
+		"                    OpStore %st_${var}_gep_0 %st_${var}_bc_0_0\n"
+		"                    OpStore %st_${var}_gep_1 %st_${var}_bc_0_1\n"
+		"                    OpStore %st_${var}_gep_2 %st_${var}_bc_1_0\n"
+		"                    OpStore %st_${var}_gep_3 %st_${var}_bc_1_1\n"
+		"                    OpStore %st_${var}_gep_4 %st_${var}_bc_2_0\n"
+		"                    OpStore %st_${var}_gep_5 %st_${var}_bc_2_1\n"
+		"                    OpStore %st_${var}_gep_6 %st_${var}_bc_3_0\n"
+		"                    OpStore %st_${var}_gep_7 %st_${var}_bc_3_1\n"
+		"                    OpStore %st_${var}_gep_8 %st_${var}_bc_4_0\n"
+		"                    OpStore %st_${var}_gep_9 %st_${var}_bc_4_1\n"
+		"                    OpReturn\n"
+		"                    OpFunctionEnd\n"
+	);
+
+	const string storeV4F16Arr3
+	(
+		"        %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		" %st_${var}_param1 = OpFunctionParameter %st_test\n"
+		" %st_${var}_param2 = OpFunctionParameter %i32\n"
+		"  %st_${var}_entry = OpLabel\n"
+		"   %st_${var}_ex_0 = OpCompositeExtract %v4f16 %st_${var}_param1 0 0\n"
+		"   %st_${var}_ex_1 = OpCompositeExtract %v4f16 %st_${var}_param1 0 1\n"
+		"   %st_${var}_ex_2 = OpCompositeExtract %v4f16 %st_${var}_param1 0 2\n"
+		"%st_${var}_vec_0_0 = OpVectorShuffle %v2f16 %st_${var}_ex_0 %st_${var}_ex_0 0 1\n"
+		"%st_${var}_vec_0_1 = OpVectorShuffle %v2f16 %st_${var}_ex_0 %st_${var}_ex_0 2 3\n"
+		"%st_${var}_vec_1_0 = OpVectorShuffle %v2f16 %st_${var}_ex_1 %st_${var}_ex_1 0 1\n"
+		"%st_${var}_vec_1_1 = OpVectorShuffle %v2f16 %st_${var}_ex_1 %st_${var}_ex_1 2 3\n"
+		"%st_${var}_vec_2_0 = OpVectorShuffle %v2f16 %st_${var}_ex_2 %st_${var}_ex_2 0 1\n"
+		"%st_${var}_vec_2_1 = OpVectorShuffle %v2f16 %st_${var}_ex_2 %st_${var}_ex_2 2 3\n"
+		" %st_${var}_bc_0_0 = OpBitcast %u32 %st_${var}_vec_0_0\n"
+		" %st_${var}_bc_0_1 = OpBitcast %u32 %st_${var}_vec_0_1\n"
+		" %st_${var}_bc_1_0 = OpBitcast %u32 %st_${var}_vec_1_0\n"
+		" %st_${var}_bc_1_1 = OpBitcast %u32 %st_${var}_vec_1_1\n"
+		" %st_${var}_bc_2_0 = OpBitcast %u32 %st_${var}_vec_2_0\n"
+		" %st_${var}_bc_2_1 = OpBitcast %u32 %st_${var}_vec_2_1\n"
+		"%st_${var}_gep_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"%st_${var}_gep_0_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"%st_${var}_gep_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"%st_${var}_gep_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"%st_${var}_gep_2_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"%st_${var}_gep_2_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		"                     OpStore %st_${var}_gep_0_0 %st_${var}_bc_0_0\n"
+		"                     OpStore %st_${var}_gep_0_1 %st_${var}_bc_0_1\n"
+		"                     OpStore %st_${var}_gep_1_0 %st_${var}_bc_1_0\n"
+		"                     OpStore %st_${var}_gep_1_1 %st_${var}_bc_1_1\n"
+		"                     OpStore %st_${var}_gep_2_0 %st_${var}_bc_2_0\n"
+		"                     OpStore %st_${var}_gep_2_1 %st_${var}_bc_2_1\n"
+		"                     OpReturn\n"
+		"                     OpFunctionEnd\n"
+	);
+
+	const string storeStruct16Arr3
+	(
+		"          %st_${var} = OpFunction %void None %void_st_test_i32_fn\n"
+		"   %st_${var}_param1 = OpFunctionParameter %st_test\n"
+		"   %st_${var}_param2 = OpFunctionParameter %i32\n"
+		"    %st_${var}_entry = OpLabel\n"
+		"     %st_${var}_st_0 = OpCompositeExtract %struct16 %st_${var}_param1 0 0\n"
+		"     %st_${var}_st_1 = OpCompositeExtract %struct16 %st_${var}_param1 0 1\n"
+		"     %st_${var}_st_2 = OpCompositeExtract %struct16 %st_${var}_param1 0 2\n"
+		"   %st_${var}_el_0   = OpCompositeExtract   %f16 %st_${var}_st_0 0\n"
+		"   %st_${var}_v2_0_0 = OpCompositeExtract %v2f16 %st_${var}_st_0 1 0\n"
+		"   %st_${var}_v2_0_1 = OpCompositeExtract %v2f16 %st_${var}_st_0 1 1\n"
+		"   %st_${var}_v2_0_2 = OpCompositeExtract %v2f16 %st_${var}_st_0 1 2\n"
+		"   %st_${var}_el_1   = OpCompositeExtract   %f16 %st_${var}_st_1 0\n"
+		"   %st_${var}_v2_1_0 = OpCompositeExtract %v2f16 %st_${var}_st_1 1 0\n"
+		"   %st_${var}_v2_1_1 = OpCompositeExtract %v2f16 %st_${var}_st_1 1 1\n"
+		"   %st_${var}_v2_1_2 = OpCompositeExtract %v2f16 %st_${var}_st_1 1 2\n"
+		"   %st_${var}_el_2   = OpCompositeExtract   %f16 %st_${var}_st_2 0\n"
+		"   %st_${var}_v2_2_0 = OpCompositeExtract %v2f16 %st_${var}_st_2 1 0\n"
+		"   %st_${var}_v2_2_1 = OpCompositeExtract %v2f16 %st_${var}_st_2 1 1\n"
+		"   %st_${var}_v2_2_2 = OpCompositeExtract %v2f16 %st_${var}_st_2 1 2\n"
+		"     %st_${var}_v2_0 = OpCompositeConstruct %v2f16 %st_${var}_el_0 %c_f16_na\n"
+		"     %st_${var}_v2_1 = OpCompositeConstruct %v2f16 %st_${var}_el_1 %c_f16_na\n"
+		"     %st_${var}_v2_2 = OpCompositeConstruct %v2f16 %st_${var}_el_2 %c_f16_na\n"
+		"   %st_${var}_bc_0   = OpBitcast %u32 %st_${var}_v2_0\n"
+		"   %st_${var}_bc_0_0 = OpBitcast %u32 %st_${var}_v2_0_0\n"
+		"   %st_${var}_bc_0_1 = OpBitcast %u32 %st_${var}_v2_0_1\n"
+		"   %st_${var}_bc_0_2 = OpBitcast %u32 %st_${var}_v2_0_2\n"
+		"   %st_${var}_bc_1   = OpBitcast %u32 %st_${var}_v2_1\n"
+		"   %st_${var}_bc_1_0 = OpBitcast %u32 %st_${var}_v2_1_0\n"
+		"   %st_${var}_bc_1_1 = OpBitcast %u32 %st_${var}_v2_1_1\n"
+		"   %st_${var}_bc_1_2 = OpBitcast %u32 %st_${var}_v2_1_2\n"
+		"   %st_${var}_bc_2   = OpBitcast %u32 %st_${var}_v2_2\n"
+		"   %st_${var}_bc_2_0 = OpBitcast %u32 %st_${var}_v2_2_0\n"
+		"   %st_${var}_bc_2_1 = OpBitcast %u32 %st_${var}_v2_2_1\n"
+		"   %st_${var}_bc_2_2 = OpBitcast %u32 %st_${var}_v2_2_2\n"
+		"%st_${var}_gep_0_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_0\n"
+		"%st_${var}_gep_0_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_1\n"
+		"%st_${var}_gep_0_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_2\n"
+		"%st_${var}_gep_0_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_3\n"
+		"%st_${var}_gep_1_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_4\n"
+		"%st_${var}_gep_1_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_5\n"
+		"%st_${var}_gep_1_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_6\n"
+		"%st_${var}_gep_1_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_7\n"
+		"%st_${var}_gep_2_0_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_8\n"
+		"%st_${var}_gep_2_1_0 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_9\n"
+		"%st_${var}_gep_2_1_1 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_10\n"
+		"%st_${var}_gep_2_1_2 = OpAccessChain %up_u32 %${var} %c_i32_0 %c_i32_11\n"
+		"                       OpStore %st_${var}_gep_0_0_0 %st_${var}_bc_0\n"
+		"                       OpStore %st_${var}_gep_0_1_0 %st_${var}_bc_0_0\n"
+		"                       OpStore %st_${var}_gep_0_1_1 %st_${var}_bc_0_1\n"
+		"                       OpStore %st_${var}_gep_0_1_2 %st_${var}_bc_0_2\n"
+		"                       OpStore %st_${var}_gep_1_0_0 %st_${var}_bc_1\n"
+		"                       OpStore %st_${var}_gep_1_1_0 %st_${var}_bc_1_0\n"
+		"                       OpStore %st_${var}_gep_1_1_1 %st_${var}_bc_1_1\n"
+		"                       OpStore %st_${var}_gep_1_1_2 %st_${var}_bc_1_2\n"
+		"                       OpStore %st_${var}_gep_2_0_0 %st_${var}_bc_2\n"
+		"                       OpStore %st_${var}_gep_2_1_0 %st_${var}_bc_2_0\n"
+		"                       OpStore %st_${var}_gep_2_1_1 %st_${var}_bc_2_1\n"
+		"                       OpStore %st_${var}_gep_2_1_2 %st_${var}_bc_2_2\n"
+		"                       OpReturn\n"
+		"                       OpFunctionEnd\n"
+	);
+
 	struct OpParts
 	{
 		const char*	premainDecls;
@@ -12549,10 +13468,8 @@
 			"    %SSBO_src = OpTypeStruct %ra_f16\n"
 			"    %SSBO_dst = OpTypeStruct %ra_st\n",
 
-			"       %src = OpAccessChain %up_f16 %ssbo_src %c_i32_0 %ndx\n"
-			"       %dst = OpAccessChain %up_st %ssbo_dst %c_i32_0 %c_i32_0\n"
-			"   %val_new = OpLoad %f16 %src\n"
-			"   %val_old = OpLoad %st_test %dst\n"
+			"   %val_new = OpFunctionCall %f16 %ld_arg_ssbo_src %ndx\n"
+			"   %val_old = OpFunctionCall %st_test %ld_ssbo_dst %c_i32_0\n"
 			"   %val_dst = OpFunctionCall %st_test %sw_fun %val_new %val_old %ndx\n",
 
 			"   %sw_fun = OpFunction %st_test None %fun_t\n"
@@ -12568,9 +13485,7 @@
 			"    %SSBO_src = OpTypeStruct %ra_st\n"
 			"    %SSBO_dst = OpTypeStruct %ra_f16\n",
 
-			"       %src = OpAccessChain %up_st %ssbo_src %c_i32_0 %c_i32_0\n"
-			"       %dst = OpAccessChain %up_f16 %ssbo_dst %c_i32_0 %ndx\n"
-			"   %val_src = OpLoad %st_test %src\n"
+			"   %val_src = OpFunctionCall %st_test %ld_ssbo_src %c_i32_0\n"
 			"   %val_dst = OpFunctionCall %f16 %sw_fun %val_src %ndx\n",
 
 			"   %sw_fun = OpFunction %f16 None %fun_t\n",
@@ -12702,19 +13617,21 @@
 		const char*		name;
 		size_t			accessPathLength;
 		const char**	accessPath;
+		const string	loadFunction;
+		const string	storeFunction;
 	};
 
 	const TypeTestParameters typeTestParameters[] =
 	{
-		{	"f16",			DE_LENGTH_OF_ARRAY(accessPathF16),			accessPathF16			},
-		{	"v2f16",		DE_LENGTH_OF_ARRAY(accessPathV2F16),		accessPathV2F16			},
-		{	"v3f16",		DE_LENGTH_OF_ARRAY(accessPathV3F16),		accessPathV3F16			},
-		{	"v4f16",		DE_LENGTH_OF_ARRAY(accessPathV4F16),		accessPathV4F16			},
-		{	"f16arr3",		DE_LENGTH_OF_ARRAY(accessPathF16Arr3),		accessPathF16Arr3		},
-		{	"v2f16arr5",	DE_LENGTH_OF_ARRAY(accessPathV2F16Arr5),	accessPathV2F16Arr5		},
-		{	"v3f16arr5",	DE_LENGTH_OF_ARRAY(accessPathV3F16Arr5),	accessPathV3F16Arr5		},
-		{	"v4f16arr3",	DE_LENGTH_OF_ARRAY(accessPathV4F16Arr3),	accessPathV4F16Arr3		},
-		{	"struct16arr3",	DE_LENGTH_OF_ARRAY(accessPathStruct16Arr3),	accessPathStruct16Arr3	},
+		{	"f16",			DE_LENGTH_OF_ARRAY(accessPathF16),			accessPathF16,			loadF16,			storeF16		 },
+		{	"v2f16",		DE_LENGTH_OF_ARRAY(accessPathV2F16),		accessPathV2F16,		loadV2F16,			storeV2F16		 },
+		{	"v3f16",		DE_LENGTH_OF_ARRAY(accessPathV3F16),		accessPathV3F16,		loadV3F16,			storeV3F16		 },
+		{	"v4f16",		DE_LENGTH_OF_ARRAY(accessPathV4F16),		accessPathV4F16,		loadV4F16,			storeV4F16		  },
+		{	"f16arr3",		DE_LENGTH_OF_ARRAY(accessPathF16Arr3),		accessPathF16Arr3,		loadF16Arr3,		storeF16Arr3	  },
+		{	"v2f16arr5",	DE_LENGTH_OF_ARRAY(accessPathV2F16Arr5),	accessPathV2F16Arr5,	loadV2F16Arr5,		storeV2F16Arr5	  },
+		{	"v3f16arr5",	DE_LENGTH_OF_ARRAY(accessPathV3F16Arr5),	accessPathV3F16Arr5,	loadV3F16Arr5,		storeV3F16Arr5	  },
+		{	"v4f16arr3",	DE_LENGTH_OF_ARRAY(accessPathV4F16Arr3),	accessPathV4F16Arr3,	loadV4F16Arr3,		storeV4F16Arr3	  },
+		{	"struct16arr3",	DE_LENGTH_OF_ARRAY(accessPathStruct16Arr3),	accessPathStruct16Arr3,	loadStruct16Arr3,	storeStruct16Arr3},
 	};
 
 	for (size_t typeTestNdx = 0; typeTestNdx < DE_LENGTH_OF_ARRAY(typeTestParameters); ++typeTestNdx)
@@ -12764,26 +13681,39 @@
 		specs["num_elements"]			= de::toString(structItemsCount);
 		specs["field_type"]				= typeTestParameters[typeTestNdx].name;
 		specs["struct_item_size"]		= de::toString(structItemsCount * sizeof(deFloat16));
+		specs["struct_u32s"]			= de::toString(structItemsCount / 2);
 		specs["op_premain_decls"]		= opParts.premainDecls;
 		specs["op_sw_fun_call"]			= opParts.swFunCall;
 		specs["op_sw_fun_header"]		= opParts.swFunHeader;
 		specs["op_case_default_value"]	= opParts.caseDefaultValue;
+		if (opIndex == 0) {
+			specs["st_call"]			= "st_ssbo_dst";
+			specs["st_ndx"]				= "c_i32_0";
+		} else {
+			specs["st_call"]			= "st_fn_ssbo_dst";
+			specs["st_ndx"]				= "ndx";
+		}
 
-		fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"";
-		fragments["capability"]		= "OpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
+		fragments["capability"]		= "OpCapability Float16\n";
 		fragments["decoration"]		= decoration.specialize(specs);
 		fragments["pre_main"]		= preMain.specialize(specs);
 		fragments["testfun"]		= testFun.specialize(specs);
+		if (opIndex == 0) {
+			fragments["testfun"]		+= StringTemplate(loadScalarF16FromUint).specialize({{"var", "ssbo_src"}});
+			fragments["testfun"]		+= StringTemplate(typeTestParameters[typeTestNdx].loadFunction).specialize({{"var", "ssbo_dst"}});
+			fragments["testfun"]		+= StringTemplate(typeTestParameters[typeTestNdx].storeFunction).specialize({{"var", "ssbo_dst"}});
+		} else {
+			fragments["testfun"]		+= StringTemplate(typeTestParameters[typeTestNdx].loadFunction).specialize({{"var", "ssbo_src"}});
+			fragments["testfun"]		+= StringTemplate(storeScalarF16AsUint).specialize({{"var", "ssbo_dst"}});
+		}
 
 		specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(inputFP16)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(dummyFP16Output)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 		specResource.verifyIO = compareFP16CompositeFunc;
 
-		extensions.push_back("VK_KHR_16bit_storage");
 		extensions.push_back("VK_KHR_shader_float16_int8");
 
 		features.extFloat16Int8		= EXTFLOAT16INT8FEATURES_FLOAT16;
-		features.ext16BitStorage	= EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
 
 		finalizeTestsCreation(specResource, fragments, testCtx, *testGroup.get(), testName, features, extensions, IVec3(1, 1, 1));
 	}
@@ -18949,6 +19879,7 @@
 	computeTests->addChild(createOpNMinGroup(testCtx));
 	computeTests->addChild(createOpNMaxGroup(testCtx));
 	computeTests->addChild(createOpNClampGroup(testCtx));
+	computeTests->addChild(createFloatControlsExtensionlessGroup(testCtx));
 	{
 		de::MovePtr<tcu::TestCaseGroup>	computeAndroidTests	(new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersion1p4Tests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersion1p4Tests.cpp
index 12d57ef..75b8952 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersion1p4Tests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersion1p4Tests.cpp
@@ -29,6 +29,7 @@
 #include "tcuDefs.hpp"
 
 #include "vkDefs.hpp"
+#include "vktTestGroupUtil.hpp"
 #include "vktAmberTestCase.hpp"
 #include "vktSpvAsmSpirvVersion1p4Tests.hpp"
 #include "vktTestGroupUtil.hpp"
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp
index 8f64746..3fb0781 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp
@@ -99,6 +99,9 @@
 		"OpReturnValue %ret\n"
 		"OpFunctionEnd\n";
 
+	if (testParameters.spirvVersion > SPIRV_VERSION_1_3)
+		opSimpleTest["GL_entrypoint"] = "%BP_vertexIdInCurrentPatch";
+
 	switch (testParameters.operation)
 	{
 		case OPERATION_GRAPHICS_VERTEX:					return createInstanceContext(vertFragPipelineStages, opSimpleTest);
@@ -110,20 +113,24 @@
 	}
 }
 
-static void getComputeSourceCode (std::string& computeSourceCode)
+static void getComputeSourceCode (std::string& computeSourceCode, SpirvVersion spirvVersion)
 {
-	computeSourceCode =
-		string(getComputeAsmShaderPreamble()) +
+	computeSourceCode = "";
+	if (spirvVersion > SPIRV_VERSION_1_3)
+		computeSourceCode += string(getComputeAsmShaderPreamble("", "", "", "", "%indata %outdata"));
+	else
+		computeSourceCode += string(getComputeAsmShaderPreamble());
 
+	computeSourceCode +=
 		"OpSource GLSL 430\n"
 		"OpName %main           \"main\"\n"
 		"OpName %id             \"gl_GlobalInvocationID\"\n"
 
 		"OpDecorate %id BuiltIn GlobalInvocationId\n" +
 
-		string(getComputeAsmInputOutputBufferTraits()) +
-		string(getComputeAsmCommonTypes()) +
-		string(getComputeAsmInputOutputBuffer()) +
+		string(getComputeAsmInputOutputBufferTraits((spirvVersion > SPIRV_VERSION_1_3) ? "Block" : "BufferBlock")) +
+		string(getComputeAsmCommonTypes((spirvVersion > SPIRV_VERSION_1_3) ? "StorageBuffer" : "Uniform")) +
+		string(getComputeAsmInputOutputBuffer((spirvVersion > SPIRV_VERSION_1_3) ? "StorageBuffer" : "Uniform")) +
 
 		"%id        = OpVariable %uvec3ptr Input\n"
 		"%zero      = OpConstant %i32 0\n"
@@ -278,7 +285,7 @@
 		{
 			std::string comp;
 
-			getComputeSourceCode(comp);
+			getComputeSourceCode(comp, m_testParameters.spirvVersion);
 
 			programCollection.spirvAsmSources.add("compute", &spirVAsmBuildOptions) << comp;
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
index 2022f68..89036df 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
@@ -53,7 +53,7 @@
 	VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures = context.get8BitStorageFeatures();
 
 	if ((toCheck & EXT8BITSTORAGEFEATURES_STORAGE_BUFFER) != 0 && extensionFeatures.storageBuffer8BitAccess == VK_FALSE)
-		TCU_FAIL("storageBuffer8BitAccess has to be supported");
+		return false;
 
 	if ((toCheck & EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER) != 0 && extensionFeatures.uniformAndStorageBuffer8BitAccess == VK_FALSE)
 		return false;
@@ -166,7 +166,7 @@
 
 bool isFloat16Int8FeaturesSupported (const Context& context, ExtensionFloat16Int8Features toCheck)
 {
-	const VkPhysicalDeviceFloat16Int8FeaturesKHR& extensionFeatures = context.getShaderFloat16Int8Features();
+	const VkPhysicalDeviceShaderFloat16Int8Features& extensionFeatures = context.getShaderFloat16Int8Features();
 
 	if ((toCheck & EXTFLOAT16INT8FEATURES_FLOAT16) != 0 && extensionFeatures.shaderFloat16 == VK_FALSE)
 		return false;
@@ -233,7 +233,7 @@
 		instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
 	}
 
-	using FCIndependence = VkShaderFloatControlsIndependenceKHR;
+	using FCIndependence = VkShaderFloatControlsIndependence;
 	FCIndependence fcInd32		= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
 	FCIndependence fcIndAll		= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
 	FCIndependence fcIndNone	= VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;
@@ -282,6 +282,8 @@
 	case SPIRV_VERSION_1_3:
 	case SPIRV_VERSION_1_4:
 		return VK_API_VERSION_1_1;
+	case SPIRV_VERSION_1_5:
+		return VK_API_VERSION_1_2;
 	default:
 		DE_ASSERT(0);
 	}
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
index 02979d7..20adddc 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
@@ -249,7 +249,7 @@
 	EXTFLOAT16INT8FEATURES_INT8		= (1u << 2),
 };
 typedef deUint32 ExtensionFloat16Int8Features;
-typedef vk::VkPhysicalDeviceFloatControlsPropertiesKHR ExtensionFloatControlsFeatures;
+typedef vk::VkPhysicalDeviceFloatControlsProperties ExtensionFloatControlsFeatures;
 
 enum ExtensionVulkanMemoryModelFeaturesBits
 {
@@ -306,11 +306,6 @@
 							  const char**							missingFeature);
 
 // Returns true if the given 16bit storage extension features in `toCheck` are all supported.
-bool isCoreFeaturesSupported (const Context&						context,
-							  const vk::VkPhysicalDeviceFeatures&	toCheck,
-							  const char**							missingFeature);
-
-// Returns true if the given 16bit storage extension features in `toCheck` are all supported.
 bool is16BitStorageFeaturesSupported (const Context&				context,
 									  Extension16BitStorageFeatures	toCheck);
 
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariableInitTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariableInitTests.cpp
index 5185fe8..c7dc701 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariableInitTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariableInitTests.cpp
@@ -44,130 +44,170 @@
 namespace
 {
 
-void addShaderCodeOutputFloat		(vk::SourceCollections& dst, InstanceContext context);
-void addShaderCodeOutputVector		(vk::SourceCollections& dst, InstanceContext context);
-void addShaderCodeOutputMatrix		(vk::SourceCollections& dst, InstanceContext context);
-void addShaderCodeOutputFloatArray	(vk::SourceCollections& dst, InstanceContext context);
-void addShaderCodeOutputStruct		(vk::SourceCollections& dst, InstanceContext context);
+enum InitializationSource
+{
+	INITIALIZATION_SOURCE_CONSTANT,	// Variable is initialized from a constant value
+	INITIALIZATION_SOURCE_GLOBAL,	// Variable is initialized from a global variable, which in turn is initialized from a constant
+};
 
 struct TestParams
 {
-	string											name;
-	string											type;
-	int												numComponents;
-	FunctionPrograms1<InstanceContext>::Function	shaderInit;
+	string						name;
+	string						type;
+	int							numComponents;
+	InitializationSource		initializationSource;
 };
 
-const TestParams	params[]	=
+struct ShaderParams
 {
-	{ "float",		"f32",			1				, addShaderCodeOutputFloat		},
-	{ "vec4",		"v4f32",		4				, addShaderCodeOutputVector		},
-	{ "matrix",		"matrix",		2 * 4			, addShaderCodeOutputMatrix		},
-	{ "floatarray",	"floatArray",	8				, addShaderCodeOutputFloatArray	},
-	{ "struct",		"struct",		2 * 4 + 4 + 4	, addShaderCodeOutputStruct		}
+	InstanceContext			context;
+	string					type;
 };
 
-const string		common		=
-	"                %f32_1 = OpConstant %f32 1\n"
-	"              %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
-	"               %matrix = OpTypeMatrix %v4f32 2\n"
-	"             %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
-	"               %struct = OpTypeStruct %matrix %v4f32 %f32 %f32 %f32 %f32\n"
-	"             %struct_1 = OpConstantComposite %struct %matrix_1 %v4f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
-	"              %c_u32_8 = OpConstant %u32 8\n"
-	"           %floatArray = OpTypeArray %f32 %c_u32_8\n"
-	"         %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
-	"          %numElements = OpConstant %u32 ${count}\n"
-	"          %outputArray = OpTypeArray %${type} %numElements\n"
-	"               %Output = OpTypeStruct %outputArray\n"
-	"          %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
-	"                %sbPtr = OpTypePointer StorageBuffer %${type}\n"
-	"           %dataOutput = OpVariable %_ptr_Output StorageBuffer\n";
+const TestParams	testParams[]	=
+{
+	{ "float",							"f32",			1,				INITIALIZATION_SOURCE_CONSTANT	},
+	{ "vec4",							"v4f32",		4,				INITIALIZATION_SOURCE_CONSTANT	},
+	{ "matrix",							"matrix",		2 * 4,			INITIALIZATION_SOURCE_CONSTANT	},
+	{ "floatarray",						"floatArray",	8,				INITIALIZATION_SOURCE_CONSTANT	},
+	{ "struct",							"struct",		2 * 4 + 4 + 4,	INITIALIZATION_SOURCE_CONSTANT	},
 
-const string		decorations	=
-	"                         OpDecorate %outputArray ArrayStride ${arrayStride}\n"
-	"                         OpMemberDecorate %Output 0 Offset 0\n"
-	"                         OpDecorate %Output Block\n"
-	"                         OpDecorate %dataOutput DescriptorSet 0\n"
-	"                         OpDecorate %dataOutput Binding 0\n"
-	"                         OpDecorate %floatArray ArrayStride 4\n"
-	"                         OpMemberDecorate %struct 0 ColMajor\n"
-	"                         OpMemberDecorate %struct 0 Offset 0\n"
-	"                         OpMemberDecorate %struct 0 MatrixStride 16\n"
-	"                         OpMemberDecorate %struct 1 Offset 32\n"
-	"                         OpMemberDecorate %struct 2 Offset 48\n"
-	"                         OpMemberDecorate %struct 3 Offset 52\n"
-	"                         OpMemberDecorate %struct 4 Offset 56\n"
-	"                         OpMemberDecorate %struct 5 Offset 60\n"
-	"${extraDecorations:opt}";
+	{ "float_from_workgroup",			"f32",			1,				INITIALIZATION_SOURCE_GLOBAL	},
+	{ "vec4_from_workgroup",			"v4f32",		4,				INITIALIZATION_SOURCE_GLOBAL	},
+	{ "matrix_from_workgroup",			"matrix",		2 * 4,			INITIALIZATION_SOURCE_GLOBAL	},
+	{ "floatarray_from_workgroup",		"floatArray",	8,				INITIALIZATION_SOURCE_GLOBAL	},
+	{ "struct_from_workgroup",			"struct",		2 * 4 + 4 + 4,	INITIALIZATION_SOURCE_GLOBAL	}
+};
+
+const string		common			=
+	"                      %f32_1 = OpConstant %f32 1\n"
+	"                    %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
+	"                     %matrix = OpTypeMatrix %v4f32 2\n"
+	"                   %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
+	"                     %struct = OpTypeStruct %matrix %v4f32 %f32 %f32 %f32 %f32\n"
+	"                   %struct_1 = OpConstantComposite %struct %matrix_1 %v4f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
+	"                    %c_u32_8 = OpConstant %u32 8\n"
+	"                 %floatArray = OpTypeArray %f32 %c_u32_8\n"
+	"               %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
+	"                %numElements = OpConstant %u32 ${count}\n"
+	"                %outputArray = OpTypeArray %${type} %numElements\n"
+	"                     %Output = OpTypeStruct %outputArray\n"
+	"                %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
+	"                      %sbPtr = OpTypePointer StorageBuffer %${type}\n"
+	"                 %dataOutput = OpVariable %_ptr_Output StorageBuffer\n";
+
+const string		globals			=
+	"        %_ptr_${type}_global = OpTypePointer Workgroup %${type}\n"
+	"           %${type}_global_1 = OpVariable %_ptr_${type}_global Workgroup\n";
+
+const string		decorations		=
+	"${arrayStrideDecoration}"
+	"                               OpMemberDecorate %Output 0 Offset 0\n"
+	"                               OpDecorate %Output Block\n"
+	"                               OpDecorate %dataOutput DescriptorSet 0\n"
+	"                               OpDecorate %dataOutput Binding 0\n"
+	"${extraDecorations:opt}"
+	"                               OpDecorate %floatArray ArrayStride 4\n"
+	"                               OpMemberDecorate %struct 0 ColMajor\n"
+	"                               OpMemberDecorate %struct 0 Offset 0\n"
+	"                               OpMemberDecorate %struct 0 MatrixStride 16\n"
+	"                               OpMemberDecorate %struct 1 Offset 32\n"
+	"                               OpMemberDecorate %struct 2 Offset 48\n"
+	"                               OpMemberDecorate %struct 3 Offset 52\n"
+	"                               OpMemberDecorate %struct 4 Offset 56\n"
+	"                               OpMemberDecorate %struct 5 Offset 60\n";
 
 void addComputeVariableInitPrivateTest (tcu::TestCaseGroup* group)
 {
-	tcu::TestContext&	testCtx			= group->getTestContext();
-	const int			numFloats		= 128;
-	tcu::TestCaseGroup*	privateGroup	= new tcu::TestCaseGroup(testCtx, "private", "Tests OpVariable initialization in private storage class.");
-	ComputeShaderSpec	spec;
-	vector<float>		expectedOutput;
-
-	const StringTemplate shaderSourceTemplate (
-		string(
-		"                         OpCapability Shader\n"
-		"                         OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
-		"                    %1 = OpExtInstImport \"GLSL.std.450\"\n"
-		"                         OpMemoryModel Logical GLSL450\n"
-		"                         OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
-		"                         OpExecutionMode %main LocalSize 1 1 1\n"
-		"                         OpSource GLSL 430\n"
-		"                         OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n")
-		+ decorations + string(
-		"                 %void = OpTypeVoid\n"
-		"             %voidFunc = OpTypeFunction %void\n"
-		"                  %f32 = OpTypeFloat 32\n"
-		"                  %u32 = OpTypeInt 32 0\n"
-		"              %c_u32_0 = OpConstant %u32 0\n"
-		"                %v4f32 = OpTypeVector %f32 4\n")
-		+ common + string(
-		"              %dataPtr = OpTypePointer Private %${type}\n"
-		"   %_ptr_Function_uint = OpTypePointer Function %u32\n"
-		"               %v3uint = OpTypeVector %u32 3\n"
-		"    %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
-		"%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
-		"      %_ptr_Input_uint = OpTypePointer Input %u32\n"
-		"                  %int = OpTypeInt 32 1\n"
-		"                %int_0 = OpConstant %int 0\n"
-		"                   %f1 = OpVariable %dataPtr Private %${constData}\n"
-		"                 %main = OpFunction %void None %voidFunc\n"
-		"                %entry = OpLabel\n"
-		"        %invocationPtr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %c_u32_0\n"
-		"           %invocation = OpLoad %u32 %invocationPtr\n"
-		"           %outputData = OpLoad %${type} %f1\n"
-		"            %outputPtr = OpAccessChain %sbPtr %dataOutput %int_0 %invocation\n"
-		"                         OpStore %outputPtr %outputData\n"
-		"                         OpReturn\n"
-		"                         OpFunctionEnd\n"));
+	tcu::TestContext&		testCtx					= group->getTestContext();
+	const int				numFloats				= 128;
+	tcu::TestCaseGroup*		privateGroup			= new tcu::TestCaseGroup(testCtx, "private", "Tests OpVariable initialization in private storage class.");
+	vector<float>			expectedOutput			(numFloats, 1.0f);
 
 	group->addChild(privateGroup);
 
-	expectedOutput.reserve(numFloats);
-	for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
-		expectedOutput.push_back(1.0f);
-
-	spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
-
-	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
+	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(testParams); paramIdx++)
 	{
-		map<string, string> shaderSpec;
-		const int			numComponents	= params[paramIdx].numComponents;
-		const int			numElements		= numFloats / numComponents;
+		ComputeShaderSpec		spec;
+		spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
 
-		shaderSpec["type"]			= params[paramIdx].type;
-		shaderSpec["arrayStride"]	= de::toString(numComponents * 4);
-		shaderSpec["count"]			= de::toString(numElements);
-		shaderSpec["constData"]		= params[paramIdx].type + "_1";
+		map<string, string>		shaderSpec;
+		const int				numComponents			= testParams[paramIdx].numComponents;
+		const int				numElements				= numFloats / numComponents;
+		const string			type					= testParams[paramIdx].type;
 
-		if (params[paramIdx].type == "matrix")
+		const StringTemplate	shaderSourceTemplate	(
+			string(
+			"                         OpCapability Shader\n"
+			"${capabilities:opt}"
+			"                         OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
+			"${extensions:opt}"
+			"                    %1 = OpExtInstImport \"GLSL.std.450\"\n"
+			"                         OpMemoryModel Logical GLSL450\n"
+			"                         OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
+			"                         OpExecutionMode %main LocalSize 1 1 1\n"
+			"                         OpSource GLSL 430\n"
+			"                         OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n")
+			+ decorations + string(
+			"                 %void = OpTypeVoid\n"
+			"             %voidFunc = OpTypeFunction %void\n"
+			"                  %f32 = OpTypeFloat 32\n"
+			"                  %u32 = OpTypeInt 32 0\n"
+			"              %c_u32_0 = OpConstant %u32 0\n"
+			"                %v4f32 = OpTypeVector %f32 4\n")
+			+ common
+			+ (testParams[paramIdx].initializationSource == INITIALIZATION_SOURCE_GLOBAL ? globals : "")
+			+ string(
+			"              %dataPtr = OpTypePointer Private %${type}\n"
+			"   %_ptr_Function_uint = OpTypePointer Function %u32\n"
+			"               %v3uint = OpTypeVector %u32 3\n"
+			"    %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
+			"%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
+			"      %_ptr_Input_uint = OpTypePointer Input %u32\n"
+			"                  %int = OpTypeInt 32 1\n"
+			"                %int_0 = OpConstant %int 0\n"
+			"${variableInit}"
+			"                 %main = OpFunction %void None %voidFunc\n"
+			"                %entry = OpLabel\n"
+			"        %invocationPtr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %c_u32_0\n"
+			"           %invocation = OpLoad %u32 %invocationPtr\n"
+			"${dataLoad}"
+			"            %outputPtr = OpAccessChain %sbPtr %dataOutput %int_0 %invocation\n"
+			"                         OpStore %outputPtr %outputData\n"
+			"                         OpReturn\n"
+			"                         OpFunctionEnd\n"));
+
+		shaderSpec["type"]					= type;
+
+		shaderSpec["arrayStrideDecoration"] = "OpDecorate %outputArray ArrayStride " + de::toString(numComponents * 4) + "\n";
+		shaderSpec["count"]					= de::toString(numElements);
+		shaderSpec["constData"]				= type + "_1";
+
+		switch(testParams[paramIdx].initializationSource)
 		{
-			shaderSpec["extraDecorations"] =
+			case INITIALIZATION_SOURCE_CONSTANT:
+				shaderSpec["variableInit"]	= "             %f1 = OpVariable %dataPtr Private %" + type + "_1\n";
+				shaderSpec["dataLoad"]		= "     %outputData = OpLoad %" + type + " %f1\n";
+				break;
+			default:
+				DE_ASSERT(testParams[paramIdx].initializationSource == INITIALIZATION_SOURCE_GLOBAL);
+
+				shaderSpec["capabilities"]			= "                   OpCapability VariablePointers\n";
+				shaderSpec["extensions"]			= "                   OpExtension \"SPV_KHR_variable_pointers\"\n";
+				shaderSpec["variableInit"]			= "     %dataPtrPtr = OpTypePointer Private %_ptr_" + type + "_global\n"
+													  "             %f1 = OpVariable %dataPtrPtr Private %" + type + "_global_1\n";
+				shaderSpec["dataLoad"]				= "  %outputDataPtr = OpLoad %_ptr_" + type + "_global %f1\n"
+													  "                   OpStore %" + type + "_global_1 %" + type + "_1\n"
+													  "     %outputData = OpLoad %" + type + " %outputDataPtr\n";
+
+				spec.requestedVulkanFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
+				spec.extensions.push_back("VK_KHR_variable_pointers");
+				break;
+		};
+
+		if (testParams[paramIdx].type == "matrix")
+		{
+			shaderSpec["extraDecorations"] +=
 				"                         OpMemberDecorate %Output 0 ColMajor\n"
 				"                         OpMemberDecorate %Output 0 MatrixStride 16\n";
 		}
@@ -176,7 +216,7 @@
 		spec.numWorkGroups			= IVec3(numElements, 1, 1);
 		spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
 
-		privateGroup->addChild(new SpvAsmComputeShaderCase(testCtx, params[paramIdx].name.c_str(), "", spec));
+		privateGroup->addChild(new SpvAsmComputeShaderCase(testCtx, testParams[paramIdx].name.c_str(), "", spec));
 	}
 }
 
@@ -185,368 +225,365 @@
 	tcu::TestContext&		testCtx				= group->getTestContext();
 	map<string, string>		fragments;
 	RGBA					defaultColors[4];
-	GraphicsResources		resources;
-	vector<string>			extensions;
 	VulkanFeatures			features;
 	tcu::TestCaseGroup*		privateGroup		= new tcu::TestCaseGroup(testCtx, "private", "Tests OpVariable initialization in private storage class.");
 	const int				numFloats			= 128;
-	vector<float>			expectedOutput;
-
-	StringTemplate			preMain				(
-		common +
-		"              %dataPtr = OpTypePointer Private %${type}\n"
-		"                   %f1 = OpVariable %dataPtr Private %${constData}\n"
-		);
-
-	StringTemplate			decoration			(decorations);
-
-	StringTemplate			testFun				(
-		"            %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
-		"                %param = OpFunctionParameter %v4f32\n"
-		"                %entry = OpLabel\n"
-		"                    %i = OpVariable %fp_i32 Function\n"
-		"           %outputData = OpLoad %${type} %f1\n"
-		"                         OpStore %i %c_i32_0\n"
-		"                         OpBranch %loop\n"
-		"                 %loop = OpLabel\n"
-		"                   %15 = OpLoad %i32 %i\n"
-		"                   %lt = OpSLessThan %bool %15 %numElements\n"
-		"                         OpLoopMerge %merge %inc None\n"
-		"                         OpBranchConditional %lt %write %merge\n"
-		"                %write = OpLabel\n"
-		"                   %30 = OpLoad %i32 %i\n"
-		"            %outputPtr = OpAccessChain %sbPtr %dataOutput %c_i32_0 %30\n"
-		"                         OpStore %outputPtr %outputData\n"
-		"                         OpBranch %inc\n"
-		"                  %inc = OpLabel\n"
-		"                   %37 = OpLoad %i32 %i\n"
-		"                   %39 = OpIAdd %i32 %37 %c_i32_1\n"
-		"                         OpStore %i %39\n"
-		"                         OpBranch %loop\n"
-		"                %merge = OpLabel\n"
-		"                         OpReturnValue %param\n"
-		"                         OpFunctionEnd\n");
+	vector<float>			expectedOutput		(numFloats, 1.0f);
 
 	group->addChild(privateGroup);
-
 	getDefaultColors(defaultColors);
 
-	expectedOutput.reserve(numFloats);
-	for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
-		expectedOutput.push_back(1.0f);
-
-	resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
-	extensions.push_back("VK_KHR_storage_buffer_storage_class");
-
 	features.coreFeatures.vertexPipelineStoresAndAtomics	= true;
 	features.coreFeatures.fragmentStoresAndAtomics			= true;
 
-	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
+	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(testParams); paramIdx++)
 	{
+		if (testParams[paramIdx].initializationSource != INITIALIZATION_SOURCE_CONSTANT)
+			continue;
+
+		GraphicsResources	resources;
+		vector<string>		extensions;
+
+		resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
+		extensions.push_back("VK_KHR_storage_buffer_storage_class");
+
 		map<string, string> shaderSpec;
-		const int			numComponents	= params[paramIdx].numComponents;
+		const int			numComponents	= testParams[paramIdx].numComponents;
 		const int			numElements		= numFloats / numComponents;
+		const string		type			= testParams[paramIdx].type;
 
-		shaderSpec["type"]			= params[paramIdx].type;
-		shaderSpec["arrayStride"]	= de::toString(numComponents * 4);
-		shaderSpec["count"]			= de::toString(numElements);
-		shaderSpec["constData"]		= params[paramIdx].type + "_1";
+		StringTemplate			preMain		(
+			common
+			+ string(
+			"              %dataPtr = OpTypePointer Private %${type}\n"
+			"${variableInit}"
+			));
 
-		if (params[paramIdx].type == "matrix")
+		StringTemplate			decoration	(decorations);
+
+		StringTemplate			testFun		(
+			"            %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
+			"                %param = OpFunctionParameter %v4f32\n"
+			"                %entry = OpLabel\n"
+			"                    %i = OpVariable %fp_i32 Function\n"
+			"${dataLoad}"
+			"                         OpStore %i %c_i32_0\n"
+			"                         OpBranch %loop\n"
+			"                 %loop = OpLabel\n"
+			"                   %15 = OpLoad %i32 %i\n"
+			"                   %lt = OpSLessThan %bool %15 %numElements\n"
+			"                         OpLoopMerge %merge %inc None\n"
+			"                         OpBranchConditional %lt %write %merge\n"
+			"                %write = OpLabel\n"
+			"                   %30 = OpLoad %i32 %i\n"
+			"            %outputPtr = OpAccessChain %sbPtr %dataOutput %c_i32_0 %30\n"
+			"                         OpStore %outputPtr %outputData\n"
+			"                         OpBranch %inc\n"
+			"                  %inc = OpLabel\n"
+			"                   %37 = OpLoad %i32 %i\n"
+			"                   %39 = OpIAdd %i32 %37 %c_i32_1\n"
+			"                         OpStore %i %39\n"
+			"                         OpBranch %loop\n"
+			"                %merge = OpLabel\n"
+			"                         OpReturnValue %param\n"
+			"                         OpFunctionEnd\n");
+
+		shaderSpec["type"]					= type;
+		shaderSpec["arrayStrideDecoration"] = "OpDecorate %outputArray ArrayStride " + de::toString(numComponents * 4) + "\n";
+		shaderSpec["count"]					= de::toString(numElements);
+		shaderSpec["constData"]				= type + "_1";
+		shaderSpec["variableInit"]	= "             %f1 = OpVariable %dataPtr Private %" + type + "_1\n";
+		shaderSpec["dataLoad"]		= "     %outputData = OpLoad %" + type + " %f1\n";
+
+		if (testParams[paramIdx].type == "matrix")
 		{
-			shaderSpec["extraDecorations"] =
+			shaderSpec["extraDecorations"] +=
 				"                         OpMemberDecorate %Output 0 ColMajor\n"
 				"                         OpMemberDecorate %Output 0 MatrixStride 16\n";
 		}
 
-		fragments["extension"]		= "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
+		fragments["extension"]		+= "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
 		fragments["pre_main"]		= preMain.specialize(shaderSpec);
 		fragments["decoration"]		= decoration.specialize(shaderSpec);
 		fragments["testfun"]		= testFun.specialize(shaderSpec);
 
-		createTestsForAllStages(params[paramIdx].name, defaultColors, defaultColors, fragments, resources, extensions, privateGroup, features);
+		createTestsForAllStages(testParams[paramIdx].name, defaultColors, defaultColors, fragments, resources, extensions, privateGroup, features);
 	}
 }
 
-void addShaderCodeOutput(vk::SourceCollections& dst, InstanceContext& context, string type)
+tcu::TestStatus outputTest (Context& context, ShaderParams params)
 {
-	SpirvVersion			targetSpirvVersion	= context.resources.spirvVersion;
-	map<string, string>		spec;
+	return runAndVerifyDefaultPipeline(context, params.context);
+}
 
-	// Needed for preventing duplicate pointer declarations.
-	if (type == "v4f32")
+void addShaderCodeOutput (vk::SourceCollections& dst, ShaderParams params)
+{
+
+	SpirvVersion			targetSpirvVersion	= params.context.resources.spirvVersion;
+	map<string, string>		spec;
+	const deUint32			vulkanVersion		= dst.usedVulkanVersion;
+
+	spec["type"]		= params.type;
+	spec["initSource"]	= params.type + "_1";
+
+	if (params.type == "struct")
 	{
-		spec["vec4ptrDeclOutput"]	= "";
-		spec["vec4ptrOutput"]		= "outputPtr";
-		spec["vec4ptrDeclInput"]	= "";
-		spec["vec4ptrInput"]		= "inputPtr";
+		// Output structure of matrix, vec4, and four floats all having values of 1.
+		const StringTemplate	vertexShader	(
+			"                            OpCapability Shader\n"
+			"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
+			"                            OpMemoryModel Logical GLSL450\n"
+			"                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
+			"                            OpSource GLSL 430\n"
+			"                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
+			"                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
+			"                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
+			"                            OpDecorate %gl_PerVertex Block\n"
+			"                            OpDecorate %position Location 0\n"
+			"                            OpDecorate %vtxColor Location 1\n"
+			"                            OpDecorate %color Location 1\n"
+			"                            OpDecorate %outData Location 2\n"
+			"                            OpMemberDecorate %Data 0 ColMajor\n"
+			"                            OpMemberDecorate %Data 0 Offset 0\n"
+			"                            OpMemberDecorate %Data 0 MatrixStride 16\n"
+			"                            OpMemberDecorate %Data 1 Offset 32\n"
+			"                            OpMemberDecorate %Data 2 Offset 48\n"
+			"                            OpMemberDecorate %Data 3 Offset 52\n"
+			"                            OpMemberDecorate %Data 4 Offset 56\n"
+			"                            OpMemberDecorate %Data 5 Offset 60\n"
+			"                            OpMemberDecorate %DataOutput 0 Offset 0\n"
+			"                    %void = OpTypeVoid\n"
+			"                %voidFunc = OpTypeFunction %void\n"
+			"                   %float = OpTypeFloat 32\n"
+			"                 %v4float = OpTypeVector %float 4\n"
+			"                    %uint = OpTypeInt 32 0\n"
+			"                  %uint_1 = OpConstant %uint 1\n"
+			"       %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
+			"            %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1\n"
+			"%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
+			"                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
+			"                     %int = OpTypeInt 32 1\n"
+			"                   %int_0 = OpConstant %int 0\n"
+			"      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
+			"                %position = OpVariable %_ptr_Input_v4float Input\n"
+			"     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
+			"                %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
+			"                   %color = OpVariable %_ptr_Input_v4float Input\n"
+			"             %mat2v4float = OpTypeMatrix %v4float 2\n"
+			"                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
+			"              %DataOutput = OpTypeStruct %Data\n"
+			"  %_ptr_Output_DataOutput = OpTypePointer Output %DataOutput\n"
+			"                 %float_1 = OpConstant %float 1\n"
+			"                  %vec4_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n"
+			"                %matrix_1 = OpConstantComposite %mat2v4float %vec4_1 %vec4_1\n"
+			" %_ptr_Output_mat2v4float = OpTypePointer Output %mat2v4float\n"
+			"       %_ptr_Output_float = OpTypePointer Output %float\n"
+			"                  %data_1 = OpConstantComposite %Data %matrix_1 %vec4_1 %float_1 %float_1 %float_1 %float_1\n"
+			"                %struct_1 = OpConstantComposite %DataOutput %data_1\n"
+			"     %_ptr_struct_private = OpTypePointer Private %DataOutput\n"
+			"         %struct_global_1 = OpVariable %_ptr_struct_private Private %struct_1\n"
+			"                 %outData = OpVariable %_ptr_Output_DataOutput Output %${initSource}\n"
+			"                    %main = OpFunction %void None %voidFunc\n"
+			"                   %entry = OpLabel\n"
+			"                 %posData = OpLoad %v4float %position\n"
+			"                  %posPtr = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
+			"                            OpStore %posPtr %posData\n"
+			"               %colorData = OpLoad %v4float %color\n"
+			"                            OpStore %vtxColor %colorData\n"
+			"                            OpReturn\n"
+			"                            OpFunctionEnd\n");
+
+		// Pass the incoming input struct into buffer.
+		const string		fragmentShader	=
+			"                            OpCapability Shader\n"
+			"                            OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
+			"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
+			"                            OpMemoryModel Logical GLSL450\n"
+			"                            OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
+			"                            OpExecutionMode %main OriginUpperLeft\n"
+			"                            OpSource GLSL 430\n"
+			"                            OpDecorate %fragColor Location 0\n"
+			"                            OpDecorate %vtxColor Location 1\n"
+			"                            OpMemberDecorate %Data 0 ColMajor\n"
+			"                            OpMemberDecorate %Data 0 Offset 0\n"
+			"                            OpMemberDecorate %Data 0 MatrixStride 16\n"
+			"                            OpMemberDecorate %Data 1 Offset 32\n"
+			"                            OpMemberDecorate %Data 2 Offset 48\n"
+			"                            OpMemberDecorate %Data 3 Offset 52\n"
+			"                            OpMemberDecorate %Data 4 Offset 56\n"
+			"                            OpMemberDecorate %Data 5 Offset 60\n"
+			"                            OpMemberDecorate %Output 0 Offset 0\n"
+			"                            OpDecorate %Output Block\n"
+			"                            OpDecorate %dataOutput DescriptorSet 0\n"
+			"                            OpDecorate %dataOutput Binding 0\n"
+			"                            OpDecorate %inData Location 2\n"
+			"                    %void = OpTypeVoid\n"
+			"                %voidFunc = OpTypeFunction %void\n"
+			"                   %float = OpTypeFloat 32\n"
+			"                 %v4float = OpTypeVector %float 4\n"
+			"     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
+			"               %fragColor = OpVariable %_ptr_Output_v4float Output\n"
+			"      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
+			"                %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
+			"             %mat2v4float = OpTypeMatrix %v4float 2\n"
+			"                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
+			"                  %Output = OpTypeStruct %Data\n"
+			"             %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
+			"              %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
+			"                     %int = OpTypeInt 32 1\n"
+			"                   %int_0 = OpConstant %int 0\n"
+			"               %DataInput = OpTypeStruct %Data\n"
+			"    %_ptr_Input_DataInput = OpTypePointer Input %DataInput\n"
+			"                  %inData = OpVariable %_ptr_Input_DataInput Input\n"
+			"         %_ptr_Input_Data = OpTypePointer Input %Data\n"
+			"               %_ptr_Data = OpTypePointer StorageBuffer %Data\n"
+			"                    %main = OpFunction %void None %voidFunc\n"
+			"                   %entry = OpLabel\n"
+			"               %colorData = OpLoad %v4float %vtxColor\n"
+			"                            OpStore %fragColor %colorData\n"
+			"            %inputDataPtr = OpAccessChain %_ptr_Input_Data %inData %int_0\n"
+			"               %inputData = OpLoad %Data %inputDataPtr\n"
+			"           %outputDataPtr = OpAccessChain %_ptr_Data %dataOutput %int_0\n"
+			"                            OpStore %outputDataPtr %inputData\n"
+			"                            OpReturn\n"
+			"                            OpFunctionEnd\n";
+
+		dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
+		dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
 	}
 	else
 	{
-		spec["vec4ptrDeclOutput"]	= "     %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n";
-		spec["vec4ptrOutput"]		= "_ptr_Output_v4f32";
-		spec["vec4ptrDeclInput"]	= "     %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n";
-		spec["vec4ptrInput"]		= "_ptr_Input_v4f32";
+		// Needed for preventing duplicate pointer declarations.
+		if (params.type == "v4f32")
+		{
+			spec["vec4ptrDeclOutput"]	= "";
+			spec["vec4ptrOutput"]		= "outputPtr";
+			spec["vec4ptrDeclInput"]	= "";
+			spec["vec4ptrInput"]		= "inputPtr";
+		}
+		else
+		{
+			spec["vec4ptrDeclOutput"]	= "     %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n";
+			spec["vec4ptrOutput"]		= "_ptr_Output_v4f32";
+			spec["vec4ptrDeclInput"]	= "     %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n";
+			spec["vec4ptrInput"]		= "_ptr_Input_v4f32";
+		}
+
+		const string			types				=
+			"                     %u32 = OpTypeInt 32 0\n"
+			"                     %f32 = OpTypeFloat 32\n"
+			"                   %v4f32 = OpTypeVector %f32 4\n"
+			"                  %matrix = OpTypeMatrix %v4f32 2\n"
+			"                 %c_u32_0 = OpConstant %u32 0\n"
+			"                 %c_u32_8 = OpConstant %u32 8\n"
+			"              %floatArray = OpTypeArray %f32 %c_u32_8\n";
+
+		if (params.type == "matrix")
+		{
+			spec["extraDecorations"] =
+				"                       OpMemberDecorate %Output 0 ColMajor\n"
+				"                       OpMemberDecorate %Output 0 MatrixStride 16\n";
+		}
+
+		// Output selected data type with all components having value one.
+		const StringTemplate	vertexShader		(
+			string(
+			"                            OpCapability Shader\n"
+			"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
+			"                            OpMemoryModel Logical GLSL450\n"
+			"                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
+			"                            OpSource GLSL 430\n"
+			"                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
+			"                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
+			"                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
+			"                            OpDecorate %gl_PerVertex Block\n"
+			"                            OpDecorate %position Location 0\n"
+			"                            OpDecorate %vtxColor Location 1\n"
+			"                            OpDecorate %color Location 1\n"
+			"                            OpDecorate %outData Location 2\n"
+			"                            OpDecorate %floatArray ArrayStride 4\n"
+			"                    %void = OpTypeVoid\n"
+			"                       %3 = OpTypeFunction %void\n")
+			+ types + string(
+			"                   %f32_1 = OpConstant %f32 1\n"
+			"        %_ptr_f32_private = OpTypePointer Private %f32\n"
+			"            %f32_global_1 = OpVariable %_ptr_f32_private Private %f32_1\n"
+			"                 %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
+			"      %_ptr_v4f32_private = OpTypePointer Private %v4f32\n"
+			"          %v4f32_global_1 = OpVariable %_ptr_v4f32_private Private %v4f32_1\n"
+			"                %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
+			"     %_ptr_matrix_private = OpTypePointer Private %matrix\n"
+			"         %matrix_global_1 = OpVariable %_ptr_matrix_private Private %matrix_1\n"
+			"            %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
+			" %_ptr_floatArray_private = OpTypePointer Private %floatArray\n"
+			"     %floatArray_global_1 = OpVariable %_ptr_floatArray_private Private %floatArray_1\n"
+			"                 %c_u32_1 = OpConstant %u32 1\n"
+			"          %_arr_f32_u32_1 = OpTypeArray %f32 %c_u32_1\n"
+			"            %gl_PerVertex = OpTypeStruct %v4f32 %f32 %_arr_f32_u32_1\n"
+			"%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
+			"                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
+			"               %outputPtr = OpTypePointer Output %${type}\n"
+			"                 %outData = OpVariable %outputPtr Output %${initSource}\n"
+			"        %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n"
+			"                %position = OpVariable %_ptr_Input_v4f32 Input\n"
+			"${vec4ptrDeclOutput}"
+			"                %vtxColor = OpVariable %${vec4ptrOutput} Output\n"
+			"                   %color = OpVariable %_ptr_Input_v4f32 Input\n"
+			"                    %main = OpFunction %void None %3\n"
+			"                   %entry = OpLabel\n"
+			"                 %posData = OpLoad %v4f32 %position\n"
+			"            %posOutputPtr = OpAccessChain %${vec4ptrOutput} %_ %c_u32_0\n"
+			"                            OpStore %posOutputPtr %posData\n"
+			"               %colorData = OpLoad %v4f32 %color\n"
+			"                            OpStore %vtxColor %colorData\n"
+			"                            OpReturn\n"
+			"                            OpFunctionEnd\n"));
+
+		// Pass incoming data into buffer
+		const StringTemplate	fragmentShader		(
+			string(
+			"                       OpCapability Shader\n"
+			"                       OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
+			"                  %1 = OpExtInstImport \"GLSL.std.450\"\n"
+			"                       OpMemoryModel Logical GLSL450\n"
+			"                       OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
+			"                       OpExecutionMode %main OriginUpperLeft\n"
+			"                       OpSource GLSL 430\n"
+			"                       OpDecorate %fragColor Location 0\n"
+			"                       OpDecorate %vtxColor Location 1\n"
+			"                       OpMemberDecorate %Output 0 Offset 0\n"
+			"                       OpDecorate %Output Block\n"
+			"                       OpDecorate %dataOutput DescriptorSet 0\n"
+			"                       OpDecorate %dataOutput Binding 0\n"
+			"                       OpDecorate %inData Location 2\n"
+			"                       OpDecorate %floatArray ArrayStride 4\n"
+			"${extraDecorations:opt}"
+			"               %void = OpTypeVoid\n"
+			"                  %3 = OpTypeFunction %void\n")
+			+ types + string(
+			"           %inputPtr = OpTypePointer Input %${type}\n"
+			"             %inData = OpVariable %inputPtr Input\n"
+			"  %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n"
+			"          %fragColor = OpVariable %_ptr_Output_v4f32 Output\n"
+			"${vec4ptrDeclInput}"
+			"           %vtxColor = OpVariable %${vec4ptrInput} Input\n"
+			"             %Output = OpTypeStruct %${type}\n"
+			"        %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
+			"         %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
+			"          %outputPtr = OpTypePointer StorageBuffer %${type}\n"
+			"               %main = OpFunction %void None %3\n"
+			"              %entry = OpLabel\n"
+			"          %colorData = OpLoad %v4f32 %vtxColor\n"
+			"                       OpStore %fragColor %colorData\n"
+			"          %inputData = OpLoad %${type} %inData\n"
+			"      %outputDataPtr = OpAccessChain %outputPtr %dataOutput %c_u32_0\n"
+			"                       OpStore %outputDataPtr %inputData\n"
+			"                       OpReturn\n"
+			"                       OpFunctionEnd\n"));
+
+		dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
+		dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
 	}
-
-	const string			types				=
-		"                     %u32 = OpTypeInt 32 0\n"
-		"                     %f32 = OpTypeFloat 32\n"
-		"                   %v4f32 = OpTypeVector %f32 4\n"
-		"                  %matrix = OpTypeMatrix %v4f32 2\n"
-		"                 %c_u32_0 = OpConstant %u32 0\n"
-		"                 %c_u32_8 = OpConstant %u32 8\n"
-		"              %floatArray = OpTypeArray %f32 %c_u32_8\n";
-
-	string					outputDecoration	= "                       OpDecorate %Output Block\n";
-
-	if (type == "matrix")
-	{
-		spec["extraDecorations"] =
-			"                       OpMemberDecorate %Output 0 ColMajor\n"
-			"                       OpMemberDecorate %Output 0 MatrixStride 16\n";
-	}
-
-	// Output selected data type with all components having value one.
-	const StringTemplate	vertexShader		(
-		string(
-		"                            OpCapability Shader\n"
-		"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
-		"                            OpMemoryModel Logical GLSL450\n"
-		"                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
-		"                            OpSource GLSL 430\n"
-		"                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
-		"                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
-		"                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
-		"                            OpDecorate %gl_PerVertex Block\n"
-		"                            OpDecorate %position Location 0\n"
-		"                            OpDecorate %vtxColor Location 1\n"
-		"                            OpDecorate %color Location 1\n"
-		"                            OpDecorate %outData Location 2\n"
-		"                            OpDecorate %floatArray ArrayStride 4\n"
-		"                    %void = OpTypeVoid\n"
-		"                       %3 = OpTypeFunction %void\n")
-		+ types + string(
-		"                   %f32_1 = OpConstant %f32 1\n"
-		"                 %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
-		"                %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
-		"            %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
-		"                 %c_u32_1 = OpConstant %u32 1\n"
-		"          %_arr_f32_u32_1 = OpTypeArray %f32 %c_u32_1\n"
-		"            %gl_PerVertex = OpTypeStruct %v4f32 %f32 %_arr_f32_u32_1\n"
-		"%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
-		"                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
-		"               %outputPtr = OpTypePointer Output %${type}\n"
-		"                 %outData = OpVariable %outputPtr Output %${type}_1\n"
-		"        %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n"
-		"                %position = OpVariable %_ptr_Input_v4f32 Input\n"
-		"${vec4ptrDeclOutput}"
-		"                %vtxColor = OpVariable %${vec4ptrOutput} Output\n"
-		"                   %color = OpVariable %_ptr_Input_v4f32 Input\n"
-		"                    %main = OpFunction %void None %3\n"
-		"                   %entry = OpLabel\n"
-		"                 %posData = OpLoad %v4f32 %position\n"
-		"            %posOutputPtr = OpAccessChain %${vec4ptrOutput} %_ %c_u32_0\n"
-		"                            OpStore %posOutputPtr %posData\n"
-		"               %colorData = OpLoad %v4f32 %color\n"
-		"                            OpStore %vtxColor %colorData\n"
-		"                            OpReturn\n"
-		"                            OpFunctionEnd\n"));
-
-	// Pass incoming data into buffer
-	const StringTemplate	fragmentShader		(
-		string(
-		"                       OpCapability Shader\n"
-		"                       OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
-		"                  %1 = OpExtInstImport \"GLSL.std.450\"\n"
-		"                       OpMemoryModel Logical GLSL450\n"
-		"                       OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
-		"                       OpExecutionMode %main OriginUpperLeft\n"
-		"                       OpSource GLSL 430\n"
-		"                       OpDecorate %fragColor Location 0\n"
-		"                       OpDecorate %vtxColor Location 1\n"
-		"                       OpMemberDecorate %Output 0 Offset 0\n"
-		"                       OpDecorate %Output Block\n"
-		"                       OpDecorate %dataOutput DescriptorSet 0\n"
-		"                       OpDecorate %dataOutput Binding 0\n"
-		"                       OpDecorate %inData Location 2\n"
-		"                       OpDecorate %floatArray ArrayStride 4\n"
-		"${extraDecorations:opt}"
-		"               %void = OpTypeVoid\n"
-		"                  %3 = OpTypeFunction %void\n")
-		+ types + string(
-		"           %inputPtr = OpTypePointer Input %${type}\n"
-		"             %inData = OpVariable %inputPtr Input\n"
-		"  %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n"
-		"          %fragColor = OpVariable %_ptr_Output_v4f32 Output\n"
-		"${vec4ptrDeclInput}"
-		"           %vtxColor = OpVariable %${vec4ptrInput} Input\n"
-		"             %Output = OpTypeStruct %${type}\n"
-		"        %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
-		"         %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
-		"          %outputPtr = OpTypePointer StorageBuffer %${type}\n"
-		"               %main = OpFunction %void None %3\n"
-		"              %entry = OpLabel\n"
-		"          %colorData = OpLoad %v4f32 %vtxColor\n"
-		"                       OpStore %fragColor %colorData\n"
-		"          %inputData = OpLoad %${type} %inData\n"
-		"      %outputDataPtr = OpAccessChain %outputPtr %dataOutput %c_u32_0\n"
-		"                       OpStore %outputDataPtr %inputData\n"
-		"                       OpReturn\n"
-		"                       OpFunctionEnd\n"));
-
-	spec["type"] = type;
-
-	const deUint32 vulkanVersion = dst.usedVulkanVersion;
-	dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
-	dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
-}
-
-void addShaderCodeOutputFloat (vk::SourceCollections& dst, InstanceContext context)
-{
-	addShaderCodeOutput(dst, context, "f32");
-}
-
-void addShaderCodeOutputVector (vk::SourceCollections& dst, InstanceContext context)
-{
-	addShaderCodeOutput(dst, context, "v4f32");
-}
-
-void addShaderCodeOutputMatrix (vk::SourceCollections& dst, InstanceContext context)
-{
-	addShaderCodeOutput(dst, context, "matrix");
-}
-
-void addShaderCodeOutputFloatArray (vk::SourceCollections& dst, InstanceContext context)
-{
-	addShaderCodeOutput(dst, context, "floatArray");
-}
-
-void addShaderCodeOutputStruct (vk::SourceCollections& dst, InstanceContext context)
-{
-	SpirvVersion		targetSpirvVersion	= context.resources.spirvVersion;
-
-	// Output structure of matrix, vec4, and four floats all having values of 1.
-	const string	vertexShader	=
-		"                            OpCapability Shader\n"
-		"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
-		"                            OpMemoryModel Logical GLSL450\n"
-		"                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
-		"                            OpSource GLSL 430\n"
-		"                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
-		"                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
-		"                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
-		"                            OpDecorate %gl_PerVertex Block\n"
-		"                            OpDecorate %position Location 0\n"
-		"                            OpDecorate %vtxColor Location 1\n"
-		"                            OpDecorate %color Location 1\n"
-		"                            OpDecorate %outData Location 2\n"
-		"                            OpMemberDecorate %Data 0 ColMajor\n"
-		"                            OpMemberDecorate %Data 0 Offset 0\n"
-		"                            OpMemberDecorate %Data 0 MatrixStride 16\n"
-		"                            OpMemberDecorate %Data 1 Offset 32\n"
-		"                            OpMemberDecorate %Data 2 Offset 48\n"
-		"                            OpMemberDecorate %Data 3 Offset 52\n"
-		"                            OpMemberDecorate %Data 4 Offset 56\n"
-		"                            OpMemberDecorate %Data 5 Offset 60\n"
-		"                            OpMemberDecorate %DataOutput 0 Offset 0\n"
-		"                    %void = OpTypeVoid\n"
-		"                %voidFunc = OpTypeFunction %void\n"
-		"                   %float = OpTypeFloat 32\n"
-		"                 %v4float = OpTypeVector %float 4\n"
-		"                    %uint = OpTypeInt 32 0\n"
-		"                  %uint_1 = OpConstant %uint 1\n"
-		"       %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
-		"            %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1\n"
-		"%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
-		"                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
-		"                     %int = OpTypeInt 32 1\n"
-		"                   %int_0 = OpConstant %int 0\n"
-		"      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
-		"                %position = OpVariable %_ptr_Input_v4float Input\n"
-		"     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
-		"                %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
-		"                   %color = OpVariable %_ptr_Input_v4float Input\n"
-		"             %mat2v4float = OpTypeMatrix %v4float 2\n"
-		"                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
-		"              %DataOutput = OpTypeStruct %Data\n"
-		"  %_ptr_Output_DataOutput = OpTypePointer Output %DataOutput\n"
-		"                 %float_1 = OpConstant %float 1\n"
-		"                  %vec4_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n"
-		"                %matrix_1 = OpConstantComposite %mat2v4float %vec4_1 %vec4_1\n"
-		" %_ptr_Output_mat2v4float = OpTypePointer Output %mat2v4float\n"
-		"       %_ptr_Output_float = OpTypePointer Output %float\n"
-		"                  %data_1 = OpConstantComposite %Data %matrix_1 %vec4_1 %float_1 %float_1 %float_1 %float_1\n"
-		"            %dataOutput_1 = OpConstantComposite %DataOutput %data_1\n"
-		"                 %outData = OpVariable %_ptr_Output_DataOutput Output %dataOutput_1\n"
-		"                    %main = OpFunction %void None %voidFunc\n"
-		"                   %entry = OpLabel\n"
-		"                 %posData = OpLoad %v4float %position\n"
-		"                  %posPtr = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
-		"                            OpStore %posPtr %posData\n"
-		"               %colorData = OpLoad %v4float %color\n"
-		"                            OpStore %vtxColor %colorData\n"
-		"                            OpReturn\n"
-		"                            OpFunctionEnd\n";
-
-	// Pass the incoming input struct into buffer.
-	const string	fragmentShader	=
-		"                            OpCapability Shader\n"
-		"                            OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
-		"                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
-		"                            OpMemoryModel Logical GLSL450\n"
-		"                            OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
-		"                            OpExecutionMode %main OriginUpperLeft\n"
-		"                            OpSource GLSL 430\n"
-		"                            OpDecorate %fragColor Location 0\n"
-		"                            OpDecorate %vtxColor Location 1\n"
-		"                            OpMemberDecorate %Data 0 ColMajor\n"
-		"                            OpMemberDecorate %Data 0 Offset 0\n"
-		"                            OpMemberDecorate %Data 0 MatrixStride 16\n"
-		"                            OpMemberDecorate %Data 1 Offset 32\n"
-		"                            OpMemberDecorate %Data 2 Offset 48\n"
-		"                            OpMemberDecorate %Data 3 Offset 52\n"
-		"                            OpMemberDecorate %Data 4 Offset 56\n"
-		"                            OpMemberDecorate %Data 5 Offset 60\n"
-		"                            OpMemberDecorate %Output 0 Offset 0\n"
-		"                            OpDecorate %Output Block\n"
-		"                            OpDecorate %dataOutput DescriptorSet 0\n"
-		"                            OpDecorate %dataOutput Binding 0\n"
-		"                            OpDecorate %inData Location 2\n"
-		"                    %void = OpTypeVoid\n"
-		"                %voidFunc = OpTypeFunction %void\n"
-		"                   %float = OpTypeFloat 32\n"
-		"                 %v4float = OpTypeVector %float 4\n"
-		"     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
-		"               %fragColor = OpVariable %_ptr_Output_v4float Output\n"
-		"      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
-		"                %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
-		"             %mat2v4float = OpTypeMatrix %v4float 2\n"
-		"                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
-		"                  %Output = OpTypeStruct %Data\n"
-		"             %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
-		"              %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
-		"                     %int = OpTypeInt 32 1\n"
-		"                   %int_0 = OpConstant %int 0\n"
-		"               %DataInput = OpTypeStruct %Data\n"
-		"    %_ptr_Input_DataInput = OpTypePointer Input %DataInput\n"
-		"                  %inData = OpVariable %_ptr_Input_DataInput Input\n"
-		"         %_ptr_Input_Data = OpTypePointer Input %Data\n"
-		"               %_ptr_Data = OpTypePointer StorageBuffer %Data\n"
-		"                    %main = OpFunction %void None %voidFunc\n"
-		"                   %entry = OpLabel\n"
-		"               %colorData = OpLoad %v4float %vtxColor\n"
-		"                            OpStore %fragColor %colorData\n"
-		"            %inputDataPtr = OpAccessChain %_ptr_Input_Data %inData %int_0\n"
-		"               %inputData = OpLoad %Data %inputDataPtr\n"
-		"           %outputDataPtr = OpAccessChain %_ptr_Data %dataOutput %int_0\n"
-		"                            OpStore %outputDataPtr %inputData\n"
-		"                            OpReturn\n"
-		"                            OpFunctionEnd\n";
-
-	const deUint32 vulkanVersion = dst.usedVulkanVersion;
-	dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
-	dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
 }
 
 void addGraphicsVariableInitOutputTest (tcu::TestCaseGroup* group)
@@ -579,15 +616,13 @@
 	requiredFeatures.coreFeatures.fragmentStoresAndAtomics = VK_TRUE;
 	extensions.push_back("VK_KHR_storage_buffer_storage_class");
 
-	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
+	for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(testParams); paramIdx++)
 	{
-		const deUint32		numComponents	= params[paramIdx].numComponents;
-		GraphicsResources	resources;
-		vector<float>		expectedOutput;
+		if (testParams[paramIdx].initializationSource == INITIALIZATION_SOURCE_GLOBAL)
+			continue;
 
-		expectedOutput.reserve(numComponents);
-		for (deUint32 numIdx = 0; numIdx < numComponents; ++numIdx)
-			expectedOutput.push_back(1.0f);
+		GraphicsResources	resources;
+		vector<float>		expectedOutput	(testParams[paramIdx].numComponents, 1.0f);
 
 		resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
 
@@ -605,14 +640,18 @@
 																		   VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
 																		   QP_TEST_RESULT_FAIL,
 																		   string());
+			const ShaderParams		shaderParams	=
+			{
+				instanceContext,
+				testParams[paramIdx].type
+			};
 
-
-			addFunctionCaseWithPrograms<InstanceContext>(outputGroup,
-														 params[paramIdx].name.c_str(),
-														 "",
-														 params[paramIdx].shaderInit,
-														 runAndVerifyDefaultPipeline,
-														 instanceContext);
+			addFunctionCaseWithPrograms<ShaderParams>(outputGroup,
+													  testParams[paramIdx].name.c_str(),
+													  "",
+													  addShaderCodeOutput,
+													  outputTest,
+													  shaderParams);
 		}
 	}
 }
diff --git a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
index 7d780bb..6146063 100644
--- a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
+++ b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
@@ -1028,6 +1028,17 @@
 	return false;
 }
 
+bool usesDescriptorIndexing(const ShaderInterface& interface)
+{
+	// If any of blocks has DESCRIPTOR_INDEXING flag
+	for (int ndx = 0; ndx < interface.getNumBlocks(); ++ndx)
+	{
+		if (interface.getBlock(ndx).getFlags() & LAYOUT_DESCRIPTOR_INDEXING)
+			return true;
+	}
+	return false;
+}
+
 struct Indent
 {
 	int level;
@@ -1111,7 +1122,9 @@
 		if (block.getInstanceName() != DE_NULL)
 		{
 			src << " " << block.getInstanceName();
-			if (block.isArray())
+			if (block.getFlags() & LAYOUT_DESCRIPTOR_INDEXING)
+				src << "[]";
+			else if (block.isArray())
 				src << "[" << block.getArraySize() << "]";
 		}
 		else
@@ -1275,7 +1288,9 @@
 	{
 		name << block.getInstanceName();
 
-		if (block.isArray())
+		if (block.getFlags() & LAYOUT_DESCRIPTOR_INDEXING)
+			name << "[nonuniformEXT(" << instanceNdx << ")]";
+		else if (block.isArray())
 			name << "[" << instanceNdx << "]";
 
 		name << ".";
@@ -1502,15 +1517,21 @@
 {
 	std::ostringstream src;
 
-	if (uses16BitStorage(interface) || uses8BitStorage(interface) || usesRelaxedLayout(interface) || usesScalarLayout(interface))
+	if (uses16BitStorage(interface) || uses8BitStorage(interface) ||
+		usesRelaxedLayout(interface) || usesScalarLayout(interface) ||
+		usesDescriptorIndexing(interface))
+	{
 		src << "#version 450\n";
+	}
 	else
 		src << "#version 310 es\n";
 
+
 	src << "#extension GL_EXT_shader_16bit_storage : enable\n";
 	src << "#extension GL_EXT_shader_8bit_storage : enable\n";
 	src << "#extension GL_EXT_scalar_block_layout : enable\n";
 	src << "#extension GL_EXT_buffer_reference : enable\n";
+	src << "#extension GL_EXT_nonuniform_qualifier : enable\n";
 	src << "layout(local_size_x = 1) in;\n";
 	src << "\n";
 
@@ -2237,7 +2258,7 @@
 	bool memoryDeviceAddress = false;
 	if (m_usePhysStorageBuffer)
 	{
-		usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
+		usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
 		if (m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
 			memoryDeviceAddress = true;
 	}
@@ -2343,9 +2364,9 @@
 	{
 		const bool useKHR = m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address");
 
-		vk::VkBufferDeviceAddressInfoKHR info =
+		vk::VkBufferDeviceAddressInfo info =
 		{
-			vk::VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType	sType;
+			vk::VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,		// VkStructureType	sType;
 			DE_NULL,												// const void*		pNext;
 			0,														// VkBuffer			buffer
 		};
@@ -2355,7 +2376,7 @@
 			info.buffer = descriptors[i].buffer;
 			vk::VkDeviceAddress addr;
 			if (useKHR)
-				addr = vk.getBufferDeviceAddressKHR(device, &info);
+				addr = vk.getBufferDeviceAddress(device, &info);
 			else
 				addr = vk.getBufferDeviceAddressEXT(device, &info);
 			addr += descriptors[i].offset;
@@ -2558,6 +2579,8 @@
 		TCU_THROW(NotSupportedError, "scalarBlockLayout not supported");
 	if (m_usePhysStorageBuffer && !context.isBufferDeviceAddressSupported())
 		TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");
+	if (!context.getDescriptorIndexingFeatures().shaderStorageBufferArrayNonUniformIndexing && usesDescriptorIndexing(m_interface))
+		TCU_THROW(NotSupportedError, "Descriptor indexing over storage buffer not supported");
 	return new SSBOLayoutCaseInstance(context, m_bufferMode, m_interface, m_refLayout, m_initialData, m_writeData, m_usePhysStorageBuffer);
 }
 
diff --git a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.hpp b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.hpp
index 20b28ba..8693e45 100644
--- a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.hpp
+++ b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.hpp
@@ -45,16 +45,17 @@
 	LAYOUT_MASK			= LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_SCALAR,
 
 	// \todo [2013-10-14 pyry] Investigate adding these.
-/*	QUALIFIER_COHERENT	= (1<<4),
-	QUALIFIER_VOLATILE	= (1<<5),
-	QUALIFIER_RESTRICT	= (1<<6),
-	QUALIFIER_READONLY	= (1<<7),
-	QUALIFIER_WRITEONLY	= (1<<8),*/
-	ACCESS_READ			= (1<<9),	//!< Buffer variable is read in the shader.
-	ACCESS_WRITE		= (1<<10),	//!< Buffer variable is written in the shader.
-	LAYOUT_RELAXED		= (1<<11),	//!< Support VK_KHR_relaxed_block_layout extension
-	LAYOUT_16BIT_STORAGE= (1<<12),  //!< Support VK_KHR_16bit_storage extension
-	LAYOUT_8BIT_STORAGE	= (1<<13),  //!< Support VK_KHR_8bit_storage extension
+/*	QUALIFIER_COHERENT			= (1<<4),
+	QUALIFIER_VOLATILE			= (1<<5),
+	QUALIFIER_RESTRICT			= (1<<6),
+	QUALIFIER_READONLY			= (1<<7),
+	QUALIFIER_WRITEONLY			= (1<<8),*/
+	ACCESS_READ					= (1<<9),	//!< Buffer variable is read in the shader.
+	ACCESS_WRITE				= (1<<10),	//!< Buffer variable is written in the shader.
+	LAYOUT_RELAXED				= (1<<11),	//!< Support VK_KHR_relaxed_block_layout extension
+	LAYOUT_16BIT_STORAGE		= (1<<12),  //!< Support VK_KHR_16bit_storage extension
+	LAYOUT_8BIT_STORAGE			= (1 << 13),  //!< Support VK_KHR_8bit_storage extension
+	LAYOUT_DESCRIPTOR_INDEXING	= (1 << 14),  //!< Support VK_KHR_descriptor_indexing extension
 };
 
 enum MatrixLoadFlags
diff --git a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutTests.cpp b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutTests.cpp
index 432a99b..bf51c0a 100644
--- a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutTests.cpp
+++ b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutTests.cpp
@@ -75,6 +75,7 @@
 	FEATURE_16BIT_STORAGE		= (1<<14),
 	FEATURE_8BIT_STORAGE		= (1<<15),
 	FEATURE_SCALAR_LAYOUT		= (1<<16),
+	FEATURE_DESCRIPTOR_INDEXING	= (1<<17),
 };
 
 class RandomSSBOLayoutCase : public SSBOLayoutCase
@@ -105,10 +106,10 @@
 RandomSSBOLayoutCase::RandomSSBOLayoutCase (tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode, deUint32 features, deUint32 seed, bool usePhysStorageBuffer)
 	: SSBOLayoutCase		(testCtx, name, description, bufferMode, LOAD_FULL_MATRIX, usePhysStorageBuffer)
 	, m_features			(features)
-	, m_maxBlocks			(4)
-	, m_maxInstances		((features & FEATURE_INSTANCE_ARRAYS)	? 3 : 0)
-	, m_maxArrayLength		((features & FEATURE_ARRAYS)			? 8 : 1)
-	, m_maxStructDepth		((features & FEATURE_STRUCTS)			? 2 : 0)
+	, m_maxBlocks			((features & FEATURE_DESCRIPTOR_INDEXING)	? 1 : 4)
+	, m_maxInstances		((features & FEATURE_INSTANCE_ARRAYS)		? 3 : 0)
+	, m_maxArrayLength		((features & FEATURE_ARRAYS)				? 8 : 1)
+	, m_maxStructDepth		((features & FEATURE_STRUCTS)				? 2 : 0)
 	, m_maxBlockMembers		(5)
 	, m_maxStructMembers	(4)
 	, m_seed				(seed)
@@ -135,6 +136,9 @@
 	int				numInstances		= (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
 	int				numVars				= rnd.getInt(1, m_maxBlockMembers);
 
+	if (m_features & FEATURE_DESCRIPTOR_INDEXING)
+		numInstances = rnd.getInt(2, 4);
+
 	if (numInstances > 0)
 		block.setArraySize(numInstances);
 
@@ -153,14 +157,17 @@
 	if (m_features & FEATURE_RELAXED_LAYOUT)
 		layoutFlagCandidates.push_back(LAYOUT_RELAXED);
 
+	if (m_features & FEATURE_SCALAR_LAYOUT)
+		layoutFlagCandidates.push_back(LAYOUT_SCALAR);
+
 	if (m_features & FEATURE_16BIT_STORAGE)
 		layoutFlags |= LAYOUT_16BIT_STORAGE;
 
 	if (m_features & FEATURE_8BIT_STORAGE)
 		layoutFlags |= LAYOUT_8BIT_STORAGE;
 
-	if (m_features & FEATURE_SCALAR_LAYOUT)
-		layoutFlagCandidates.push_back(LAYOUT_SCALAR);
+	if (m_features & FEATURE_DESCRIPTOR_INDEXING)
+		layoutFlags |= LAYOUT_DESCRIPTOR_INDEXING;
 
 	DE_ASSERT(!layoutFlagCandidates.empty());
 
@@ -1688,14 +1695,15 @@
 
 	// ssbo.random
 	{
-		const deUint32	allStdLayouts	= FEATURE_STD140_LAYOUT|FEATURE_STD430_LAYOUT;
-		const deUint32	allBasicTypes	= FEATURE_VECTORS|FEATURE_MATRICES;
-		const deUint32	unused			= FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_VARS;
-		const deUint32	unsized			= FEATURE_UNSIZED_ARRAYS;
-		const deUint32	matFlags		= FEATURE_MATRIX_LAYOUT;
-		const deUint32	allButRelaxed	= ~FEATURE_RELAXED_LAYOUT & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE & ~FEATURE_SCALAR_LAYOUT;
-		const deUint32	allRelaxed		= FEATURE_VECTORS|FEATURE_RELAXED_LAYOUT|FEATURE_INSTANCE_ARRAYS;
-		const deUint32	allScalar		= ~FEATURE_RELAXED_LAYOUT & ~allStdLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE;
+		const deUint32	allStdLayouts		= FEATURE_STD140_LAYOUT|FEATURE_STD430_LAYOUT;
+		const deUint32	allBasicTypes		= FEATURE_VECTORS|FEATURE_MATRICES;
+		const deUint32	unused				= FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_VARS;
+		const deUint32	unsized				= FEATURE_UNSIZED_ARRAYS;
+		const deUint32	matFlags			= FEATURE_MATRIX_LAYOUT;
+		const deUint32	allButRelaxed		= ~FEATURE_RELAXED_LAYOUT & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE & ~FEATURE_SCALAR_LAYOUT & ~FEATURE_DESCRIPTOR_INDEXING;
+		const deUint32	allRelaxed			= FEATURE_VECTORS|FEATURE_RELAXED_LAYOUT|FEATURE_INSTANCE_ARRAYS;
+		const deUint32	allScalar			= ~FEATURE_RELAXED_LAYOUT & ~allStdLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE & ~FEATURE_DESCRIPTOR_INDEXING;
+		const deUint32	descriptorIndexing	= allStdLayouts|FEATURE_RELAXED_LAYOUT|FEATURE_SCALAR_LAYOUT|FEATURE_DESCRIPTOR_INDEXING|allBasicTypes|unused|matFlags;
 
 		tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
 		addChild(randomGroup);
@@ -1711,7 +1719,7 @@
 			}
 			else if (i == 2)
 			{
-				group = new tcu::TestCaseGroup(m_testCtx, "8bit", "18bit storage");
+				group = new tcu::TestCaseGroup(m_testCtx, "8bit", "8bit storage");
 				randomGroup->addChild(group);
 			}
 			const deUint32 use16BitStorage = i == 1 ? FEATURE_16BIT_STORAGE : 0;
@@ -1722,7 +1730,7 @@
 			createRandomCaseGroup(group, m_testCtx, "vector_types",		"Scalar and vector types only, per-block buffers",	SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|FEATURE_VECTORS,															25, 25, m_usePhysStorageBuffer);
 			createRandomCaseGroup(group, m_testCtx, "basic_types",		"All basic types, per-block buffers",				SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags,													25, 50, m_usePhysStorageBuffer);
 			createRandomCaseGroup(group, m_testCtx, "basic_arrays",		"Arrays, per-block buffers",						SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS,									25, 50, m_usePhysStorageBuffer);
-			createRandomCaseGroup(group, m_testCtx, "unsized_arrays",		"Unsized arrays, per-block buffers",				SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags|unsized|FEATURE_ARRAYS,							25, 50, m_usePhysStorageBuffer);
+			createRandomCaseGroup(group, m_testCtx, "unsized_arrays",	"Unsized arrays, per-block buffers",				SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags|unsized|FEATURE_ARRAYS,							25, 50, m_usePhysStorageBuffer);
 			createRandomCaseGroup(group, m_testCtx, "arrays_of_arrays",	"Arrays of arrays, per-block buffers",				SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags|unsized|FEATURE_ARRAYS|FEATURE_ARRAYS_OF_ARRAYS,	25, 950, m_usePhysStorageBuffer);
 
 			createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays",					"Basic instance arrays, per-block buffers",				SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allStdLayouts|unused|allBasicTypes|matFlags|unsized|FEATURE_INSTANCE_ARRAYS,															25, 75, m_usePhysStorageBuffer);
@@ -1733,8 +1741,9 @@
 			createRandomCaseGroup(group, m_testCtx, "all_per_block_buffers",	"All random features, per-block buffers",	SSBOLayoutCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allButRelaxed,	50, 200, m_usePhysStorageBuffer);
 			createRandomCaseGroup(group, m_testCtx, "all_shared_buffer",		"All random features, shared buffer",		SSBOLayoutCase::BUFFERMODE_SINGLE,		use8BitStorage|use16BitStorage|allButRelaxed,	50, 250, m_usePhysStorageBuffer);
 
-			createRandomCaseGroup(group, m_testCtx, "relaxed",			"VK_KHR_relaxed_block_layout",				SSBOLayoutCase::BUFFERMODE_SINGLE,		use8BitStorage|use16BitStorage|allRelaxed, 100, deInt32Hash(313), m_usePhysStorageBuffer);
-			createRandomCaseGroup(group, m_testCtx, "scalar",			"VK_EXT_scalar_block_layout",				SSBOLayoutCase::BUFFERMODE_SINGLE,		use8BitStorage|use16BitStorage|allScalar, 100, deInt32Hash(313), m_usePhysStorageBuffer);
+			createRandomCaseGroup(group, m_testCtx, "relaxed",				"VK_KHR_relaxed_block_layout",		SSBOLayoutCase::BUFFERMODE_SINGLE,	use8BitStorage|use16BitStorage|allRelaxed, 100, deInt32Hash(313), m_usePhysStorageBuffer);
+			createRandomCaseGroup(group, m_testCtx, "scalar",				"VK_EXT_scalar_block_layout",		SSBOLayoutCase::BUFFERMODE_SINGLE,	use8BitStorage|use16BitStorage|allScalar, 100, deInt32Hash(313), m_usePhysStorageBuffer);
+			createRandomCaseGroup(group, m_testCtx, "descriptor_indexing",	"VK_EXT_descriptor_indexing",		SSBOLayoutCase::BUFFERMODE_SINGLE,	use8BitStorage|use16BitStorage|descriptorIndexing, 50, 123, m_usePhysStorageBuffer);
 		}
 	}
 }
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
index dd581d0..207474d 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
@@ -464,17 +464,19 @@
 	de::SharedPtr<bool>	geometryPointSizeSupported;
 };
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+std::string getExtHeader(CaseDefinition caseDef)
+{
+	return	"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
+			"#extension GL_KHR_shader_subgroup_ballot: enable\n" +
+			subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
 	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 	std::string						indexVars;
 	std::ostringstream				bdy;
 
-	subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-		subgroups::setVertexShaderFrameBuffer(programCollection);
-
 	switch (caseDef.opType)
 	{
 		default:
@@ -500,10 +502,11 @@
 			break;
 	}
 
-	bdy << indexVars
+	bdy << "  uvec4 mask = subgroupBallot(true);\n"
+		<< indexVars
 		<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " ref = "
 		<< getIdentity(caseDef.opType, caseDef.format) << ";\n"
-		<< "  uint tempResult = 0;\n"
+		<< "  tempRes = 0;\n"
 		<< "  for (uint index = start; index < end; index++)\n"
 		<< "  {\n"
 		<< "    if (subgroupBallotBitExtract(mask, index))\n"
@@ -511,7 +514,7 @@
 		<< "      ref = " << getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") << ";\n"
 		<< "    }\n"
 		<< "  }\n"
-		<< "  tempResult = " << getCompare(caseDef.opType, caseDef.format, "ref",
+		<< "  tempRes = " << getCompare(caseDef.opType, caseDef.format, "ref",
 											getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") << " ? 0x1 : 0;\n"
 		<< "  if (1 == (gl_SubgroupInvocationID % 2))\n"
 		<< "  {\n"
@@ -524,135 +527,21 @@
 		<< "        ref = " << getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") << ";\n"
 		<< "      }\n"
 		<< "    }\n"
-		<< "    tempResult |= " << getCompare(caseDef.opType, caseDef.format, "ref",
+		<< "    tempRes |= " << getCompare(caseDef.opType, caseDef.format, "ref",
 				getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") << " ? 0x2 : 0;\n"
 		<< "  }\n"
 		<< "  else\n"
 		<< "  {\n"
-		<< "    tempResult |= 0x2;\n"
+		<< "    tempRes |= 0x2;\n"
 		<< "  }\n";
 
-	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream vertexSrc;
-		vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(location = 0) in highp vec4 in_position;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy.str()
-			<< "  out_color = float(tempResult);\n"
-			<< "  gl_Position = in_position;\n"
-			<< "  gl_PointSize = 1.0f;\n"
-			<< "}\n";
-		programCollection.glslSources.add("vert")
-			<< glu::VertexSource(vertexSrc.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream geometry;
-
-		geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(points) in;\n"
-			<< "layout(points, max_vertices = 1) out;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy.str()
-			<< "  out_color = float(tempResult);\n"
-			<< "  gl_Position = gl_in[0].gl_Position;\n"
-			<< (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-			<< "  EmitVertex();\n"
-			<< "  EndPrimitive();\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("geometry")
-				<< glu::GeometrySource(geometry.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream controlSource;
-		controlSource  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(vertices = 2) out;\n"
-			<< "layout(location = 0) out float out_color[];\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  if (gl_InvocationID == 0)\n"
-			<<"  {\n"
-			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
-			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
-			<< "  }\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy.str()
-			<< "  out_color[gl_InvocationID] = float(tempResult);"
-			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			<< "}\n";
-
-
-		programCollection.glslSources.add("tesc")
-			<< glu::TessellationControlSource(controlSource.str()) << buildOptions;
-		subgroups::setTesEvalShaderFrameBuffer(programCollection);
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-	{
-
-		std::ostringstream evaluationSource;
-		evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(isolines, equal_spacing, ccw ) in;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy.str()
-			<< "  out_color = float(tempResult);\n"
-			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-			<< "}\n";
-
-		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-	}
-	else
-	{
-		DE_FATAL("Unsupported shader stage");
-	}
+	subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef), bdy.str(), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
+
 	std::string indexVars;
 	switch (caseDef.opType)
 	{
@@ -679,11 +568,12 @@
 			break;
 	}
 
-	const string bdy =
-		indexVars +
+	const string testSrc =
+		"  uvec4 mask = subgroupBallot(true);\n"
+		+ indexVars +
 		"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " ref = "
 		+ getIdentity(caseDef.opType, caseDef.format) + ";\n"
-		"  uint tempResult = 0;\n"
+		"  tempRes = 0;\n"
 		"  for (uint index = start; index < end; index++)\n"
 		"  {\n"
 		"    if (subgroupBallotBitExtract(mask, index))\n"
@@ -691,7 +581,7 @@
 		"      ref = " + getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") + ";\n"
 		"    }\n"
 		"  }\n"
-		"  tempResult = " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x1 : 0;\n"
+		"  tempRes = " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x1 : 0;\n"
 		"  if (1 == (gl_SubgroupInvocationID % 2))\n"
 		"  {\n"
 		"    mask = subgroupBallot(true);\n"
@@ -703,189 +593,16 @@
 		"        ref = " + getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") + ";\n"
 		"      }\n"
 		"    }\n"
-		"    tempResult |= " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x2 : 0;\n"
+		"    tempRes |= " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x2 : 0;\n"
 		"  }\n"
 		"  else\n"
 		"  {\n"
-		"    tempResult |= 0x2;\n"
+		"    tempRes |= 0x2;\n"
 		"  }\n";
 
-	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream src;
+	std::string extHeader = getExtHeader(caseDef);
 
-		src << "#version 450\n"
-			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout (local_size_x_id = 0, local_size_y_id = 1, "
-			"local_size_z_id = 2) in;\n"
-			<< "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-			<< "{\n"
-			<< "  uint result[];\n"
-			<< "};\n"
-			<< "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
-			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-			"gl_GlobalInvocationID.x;\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  result[offset] = tempResult;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("comp")
-				<< glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-	}
-	else
-	{
-		{
-			const std::string vertex =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy+
-				"  result[gl_VertexIndex] = tempResult;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-				"  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-				"  gl_PointSize = 1.0f;\n"
-				"}\n";
-			programCollection.glslSources.add("vert")
-					<< glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const std::string tesc =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(vertices=1) out;\n"
-				"layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result[gl_PrimitiveID] = tempResult;\n"
-				"  if (gl_InvocationID == 0)\n"
-				"  {\n"
-				"    gl_TessLevelOuter[0] = 1.0f;\n"
-				"    gl_TessLevelOuter[1] = 1.0f;\n"
-				"  }\n"
-				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-				"}\n";
-			programCollection.glslSources.add("tesc")
-				<< glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const std::string tese =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(isolines) in;\n"
-				"layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-				"}\n";
-			programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const std::string geometry =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(${TOPOLOGY}) in;\n"
-				"layout(points, max_vertices = 1) out;\n"
-				"layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				 + bdy +
-				"  result[gl_PrimitiveIDIn] = tempResult;\n"
-				"  gl_Position = gl_in[0].gl_Position;\n"
-				"  EmitVertex();\n"
-				"  EndPrimitive();\n"
-				"}\n";
-			subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u),
-													  programCollection.glslSources);
-		}
-
-		{
-			const std::string fragment =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(location = 0) out uint result;\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result = tempResult;\n"
-				"}\n";
-			programCollection.glslSources.add("fragment")
-				<< glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-		subgroups::addNoSubgroupShader(programCollection);
-	}
+   subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -894,9 +611,7 @@
 		TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
 
 	if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_ARITHMETIC_BIT))
-	{
 		TCU_THROW(NotSupportedError, "Device does not support subgroup arithmetic operations");
-	}
 
 	if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
 		TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
@@ -936,7 +651,7 @@
 	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
 		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
 	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-		return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
 	else
 		TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -963,12 +678,12 @@
 {
 	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
 	{
-		if(!checkShaderStages(context,caseDef))
+		if (!checkShaderStages(context,caseDef))
 		{
 			return tcu::TestStatus::fail(
-							"Shader stage " +
-							subgroups::getShaderStageName(caseDef.shaderStage) +
-							" is required to support subgroup operations!");
+					"Shader stage " +
+					subgroups::getShaderStageName(caseDef.shaderStage) +
+					" is required to support subgroup operations!");
 		}
 		subgroups::SSBOData inputData;
 		inputData.format = caseDef.format;
@@ -992,7 +707,7 @@
 
 		VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage  & subgroupProperties.supportedStages);
 
-		if ( VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
+		if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
 		{
 			if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
 				TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
@@ -1011,8 +726,7 @@
 		inputData.binding			= 4u;
 		inputData.stages			= stages;
 
-		return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData,
-										 1, checkVertexPipelineStages, stages);
+		return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, stages);
 	}
 }
 }
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
index 7e66faa..96c92c2 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
@@ -39,6 +39,7 @@
 enum OpType
 {
 	OPTYPE_BROADCAST = 0,
+	OPTYPE_BROADCAST_NONCONST,
 	OPTYPE_BROADCAST_FIRST,
 	OPTYPE_LAST
 };
@@ -56,7 +57,7 @@
 	return vkt::subgroups::checkCompute(datas, numWorkgroups, localSize, 3);
 }
 
-std::string getOpTypeName(int opType)
+std::string getOpTypeCaseName(int opType)
 {
 	switch (opType)
 	{
@@ -64,12 +65,15 @@
 			DE_FATAL("Unsupported op type");
 			return "";
 		case OPTYPE_BROADCAST:
-			return "subgroupBroadcast";
+			return "subgroupbroadcast";
+		case OPTYPE_BROADCAST_NONCONST:
+			return "subgroupbroadcast_nonconst";
 		case OPTYPE_BROADCAST_FIRST:
-			return "subgroupBroadcastFirst";
+			return "subgroupbroadcastfirst";
 	}
 }
 
+
 struct CaseDefinition
 {
 	int					opType;
@@ -79,7 +83,16 @@
 	deBool				extShaderSubGroupBallotTests;
 };
 
-std::string getBodySource(CaseDefinition caseDef)
+std::string getExtHeader(CaseDefinition caseDef)
+{
+	return (caseDef.extShaderSubGroupBallotTests ?	"#extension GL_ARB_shader_ballot: enable\n"
+													"#extension GL_KHR_shader_subgroup_basic: enable\n"
+													"#extension GL_ARB_gpu_shader_int64: enable\n"
+												:	"#extension GL_KHR_shader_subgroup_ballot: enable\n")
+				+ subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
+std::string getTestSrc(const CaseDefinition &caseDef)
 {
 	std::ostringstream bdy;
 
@@ -111,28 +124,48 @@
 			<< "  uint sgInvocation = gl_SubgroupInvocationID;\n";
 	}
 
-	if (OPTYPE_BROADCAST == caseDef.opType)
+	const std::string fmt = subgroups::getFormatNameForGLSL(caseDef.format);
+
+	if (caseDef.opType == OPTYPE_BROADCAST)
 	{
-		bdy	<< "  uint tempResult = 0x3;\n";
+		bdy	<< "  tempRes = 0x3;\n";
 		for (int i = 0; i < max; i++)
 		{
 			bdy << "  {\n"
 			<< "    const uint id = "<< i << ";\n"
-			<< "    " << subgroups::getFormatNameForGLSL(caseDef.format) << " op = "
-				<< broadcast << "(data1[sgInvocation], id);\n"
+			<< "    " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
 			<< "    if ((id < sgSize) && subgroupBallotBitExtract(mask, id))\n"
 			<< "    {\n"
-			<< "      if (op != data1[id])\n"
+			<< "      if (op != data[id])\n"
 			<< "      {\n"
-			<< "        tempResult = 0;\n"
+			<< "        tempRes = 0;\n"
 			<< "      }\n"
 			<< "    }\n"
 			<< "  }\n";
 		}
 	}
+	else if (caseDef.opType == OPTYPE_BROADCAST_NONCONST)
+	{
+		const std::string validate =	"    if (subgroupBallotBitExtract(mask, id) && op != data[id])\n"
+										"        tempRes = 0;\n";
+
+		bdy	<< "  tempRes= 0x3;\n"
+			<< "  for (uint id = 0; id < sgSize; id++)\n"
+			<< "  {\n"
+			<< "    " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
+			<< validate
+			<< "  }\n"
+			<< "  // Test lane id that is only uniform across active lanes\n"
+			<< "  if (sgInvocation >= sgSize / 2)\n"
+			<< "  {\n"
+			<< "    uint id = sgInvocation & ~((sgSize / 2) - 1);\n"
+			<< "    " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
+			<< validate
+			<< "  }\n";
+	}
 	else
 	{
-		bdy << "  uint tempResult = 0;\n"
+		bdy << "  tempRes = 0;\n"
 			<< "  uint firstActive = 0;\n"
 			<< "  for (uint i = 0; i < sgSize; i++)\n"
 			<< "  {\n"
@@ -142,7 +175,7 @@
 			<< "      break;\n"
 			<< "    }\n"
 			<< "  }\n"
-			<< "  tempResult |= (" << broadcastFirst << "(data1[sgInvocation]) == data1[firstActive]) ? 0x1 : 0;\n"
+			<< "  tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x1 : 0;\n"
 			<< "  // make the firstActive invocation inactive now\n"
 			<< "  if (firstActive != sgInvocation)\n"
 			<< "  {\n"
@@ -155,18 +188,18 @@
 			<< "        break;\n"
 			<< "      }\n"
 			<< "    }\n"
-			<< "    tempResult |= (" << broadcastFirst << "(data1[sgInvocation]) == data1[firstActive]) ? 0x2 : 0;\n"
+			<< "    tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x2 : 0;\n"
 			<< "  }\n"
 			<< "  else\n"
 			<< "  {\n"
 			<< "    // the firstActive invocation didn't partake in the second result so set it to true\n"
-			<< "    tempResult |= 0x2;\n"
+			<< "    tempRes |= 0x2;\n"
 			<< "  }\n";
 	}
-   return bdy.str();
+	return bdy.str();
 }
 
-std::string getHelperFunctionARB(CaseDefinition caseDef)
+std::string getHelperFunctionARB(const CaseDefinition &caseDef)
 {
 	std::ostringstream bdy;
 
@@ -187,299 +220,26 @@
 
 void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-	const string extensionHeader =  (caseDef.extShaderSubGroupBallotTests ?	"#extension GL_ARB_shader_ballot: enable\n"
-																			"#extension GL_KHR_shader_subgroup_basic: enable\n"
-																			"#extension GL_ARB_gpu_shader_int64: enable\n"
-																		:	"#extension GL_KHR_shader_subgroup_ballot: enable\n")
-									+ subgroups::getAdditionalExtensionForFormat(caseDef.format);
+	const vk::SpirvVersion			spirvVersion = (caseDef.opType == OPTYPE_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, spirvVersion, 0u);
 
-	subgroups::setFragmentShaderFrameBuffer(programCollection);
+	std::string extHeader = getExtHeader(caseDef);
+	std::string testSrc = getTestSrc(caseDef);
+	std::string helperStr = getHelperFunctionARB(caseDef);
 
-	if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-		subgroups::setVertexShaderFrameBuffer(programCollection);
-
-	std::string bdyStr = getBodySource(caseDef);
-	std::string helperStrARB = getHelperFunctionARB(caseDef);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream				vertex;
-		vertex << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extensionHeader.c_str()
-			<< "layout(location = 0) in highp vec4 in_position;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform  Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< helperStrARB.c_str()
-			<< "void main (void)\n"
-			<< "{\n"
-			<< bdyStr
-			<< "  out_color = float(tempResult);\n"
-			<< "  gl_Position = in_position;\n"
-			<< "  gl_PointSize = 1.0f;\n"
-			<< "}\n";
-		programCollection.glslSources.add("vert")
-			<< glu::VertexSource(vertex.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream geometry;
-
-		geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extensionHeader.c_str()
-			<< "layout(points) in;\n"
-			<< "layout(points, max_vertices = 1) out;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< helperStrARB.c_str()
-			<< "void main (void)\n"
-			<< "{\n"
-			<< bdyStr
-			<< "  out_color = float(tempResult);\n"
-			<< "  gl_Position = gl_in[0].gl_Position;\n"
-			<< (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-			<< "  EmitVertex();\n"
-			<< "  EndPrimitive();\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("geometry")
-			<< glu::GeometrySource(geometry.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream controlSource;
-
-		controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extensionHeader.c_str()
-			<< "layout(vertices = 2) out;\n"
-			<< "layout(location = 0) out float out_color[];\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer2\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< helperStrARB.c_str()
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  if (gl_InvocationID == 0)\n"
-			<< "  {\n"
-			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
-			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
-			<< "  }\n"
-			<< bdyStr
-			<< "  out_color[gl_InvocationID ] = float(tempResult);\n"
-			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("tesc")
-			<< glu::TessellationControlSource(controlSource.str()) << buildOptions;
-		subgroups::setTesEvalShaderFrameBuffer(programCollection);
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream evaluationSource;
-		evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extensionHeader.c_str()
-			<< "layout(isolines, equal_spacing, ccw ) in;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< helperStrARB.c_str()
-			<< "void main (void)\n"
-			<< "{\n"
-			<< bdyStr
-			<< "  out_color  = float(tempResult);\n"
-			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-			<< "}\n";
-
-		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-		programCollection.glslSources.add("tese")
-			<< glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-	}
-	else
-	{
-		DE_FATAL("Unsupported shader stage");
-	}
+   subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, helperStr);
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-	std::string bdyStr = getBodySource(caseDef);
-	std::string helperStrARB = getHelperFunctionARB(caseDef);
+	const vk::SpirvVersion			spirvVersion = (caseDef.opType == OPTYPE_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, spirvVersion, 0u);
 
-	const string extensionHeader =  (caseDef.extShaderSubGroupBallotTests ?	"#extension GL_ARB_shader_ballot: enable\n"
-																			"#extension GL_KHR_shader_subgroup_basic: enable\n"
-																			"#extension GL_ARB_gpu_shader_int64: enable\n"
-																		:	"#extension GL_KHR_shader_subgroup_ballot: enable\n")
-									+ subgroups::getAdditionalExtensionForFormat(caseDef.format);
+	std::string extHeader = getExtHeader(caseDef);
+	std::string testSrc = getTestSrc(caseDef);
+	std::string helperStr = getHelperFunctionARB(caseDef);
 
-	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream src;
-
-		src << "#version 450\n"
-			<< extensionHeader.c_str()
-			<< "layout (local_size_x_id = 0, local_size_y_id = 1, "
-			"local_size_z_id = 2) in;\n"
-			<< "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-			<< "{\n"
-			<< "  uint result[];\n"
-			<< "};\n"
-			<< "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[];\n"
-			<< "};\n"
-			<< "\n"
-			<< helperStrARB.c_str()
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
-			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-			"gl_GlobalInvocationID.x;\n"
-			<< bdyStr
-			<< "  result[offset] = tempResult;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("comp")
-				<< glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-	}
-	else
-	{
-		const string vertex =
-			"#version 450\n"
-			+ extensionHeader +
-			"layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-			"{\n"
-			"  uint result[];\n"
-			"};\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-			"};\n"
-			"\n"
-			+ helperStrARB +
-			"void main (void)\n"
-			"{\n"
-			+ bdyStr +
-			"  result[gl_VertexIndex] = tempResult;\n"
-			"  float pixelSize = 2.0f/1024.0f;\n"
-			"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-			"  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-			"  gl_PointSize = 1.0f;\n"
-			"}\n";
-
-		const string tesc =
-			"#version 450\n"
-			+ extensionHeader +
-			"layout(vertices=1) out;\n"
-			"layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-			"{\n"
-			"  uint result[];\n"
-			"};\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-			"};\n"
-			"\n"
-			+ helperStrARB +
-			"void main (void)\n"
-			"{\n"
-			+ bdyStr +
-			"  result[gl_PrimitiveID] = tempResult;\n"
-			"  if (gl_InvocationID == 0)\n"
-			"  {\n"
-			"    gl_TessLevelOuter[0] = 1.0f;\n"
-			"    gl_TessLevelOuter[1] = 1.0f;\n"
-			"  }\n"
-			"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			"}\n";
-
-		const string tese =
-			"#version 450\n"
-			+ extensionHeader +
-			"layout(isolines) in;\n"
-			"layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-			"{\n"
-			"  uint result[];\n"
-			"};\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-			"};\n"
-			"\n"
-			+ helperStrARB +
-			"void main (void)\n"
-			"{\n"
-			+ bdyStr +
-			"  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
-			"  float pixelSize = 2.0f/1024.0f;\n"
-			"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-			"}\n";
-
-		const string geometry =
-			"#version 450\n"
-			+ extensionHeader +
-			"layout(${TOPOLOGY}) in;\n"
-			"layout(points, max_vertices = 1) out;\n"
-			"layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-			"{\n"
-			"  uint result[];\n"
-			"};\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-			"};\n"
-			"\n"
-			+ helperStrARB +
-			"void main (void)\n"
-			"{\n"
-			+ bdyStr +
-			"  result[gl_PrimitiveIDIn] = tempResult;\n"
-			"  gl_Position = gl_in[0].gl_Position;\n"
-			"  EmitVertex();\n"
-			"  EndPrimitive();\n"
-			"}\n";
-
-		const string fragment =
-			"#version 450\n"
-			+ extensionHeader +
-			"layout(location = 0) out uint result;\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer1\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-			"};\n"
-			+ helperStrARB +
-			"void main (void)\n"
-			"{\n"
-			+ bdyStr +
-			"  result = tempResult;\n"
-			"}\n";
-
-		subgroups::addNoSubgroupShader(programCollection);
-
-		programCollection.glslSources.add("vert")
-				<< glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		programCollection.glslSources.add("tesc")
-				<< glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u),
-												  programCollection.glslSources);
-		programCollection.glslSources.add("fragment")
-				<< glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-	}
+	subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, helperStr);
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -488,30 +248,26 @@
 		TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
 
 	if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
-	{
 		TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
-	}
 
 	if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
 		TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
 
 	if (caseDef.extShaderSubGroupBallotTests && !context.requireDeviceFunctionality("VK_EXT_shader_subgroup_ballot"))
-	{
 		TCU_THROW(NotSupportedError, "Device does not support VK_EXT_shader_subgroup_ballot extension");
-	}
 
 	if (caseDef.extShaderSubGroupBallotTests && !subgroups::isInt64SupportedForDevice(context))
-	{
 		TCU_THROW(NotSupportedError, "Device does not support int64 data types");
-	}
+
+	if ((caseDef.opType == OPTYPE_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context))
+		TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId");
 
 	*caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
 }
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-	if (!subgroups::areSubgroupOperationsSupportedForStage(
-			context, caseDef.shaderStage))
+	if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 	{
 		if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
 		{
@@ -526,20 +282,20 @@
 		}
 	}
 
-	subgroups::SSBOData inputData[1];
-	inputData[0].format = caseDef.format;
-	inputData[0].layout = subgroups::SSBOData::LayoutStd140;
-	inputData[0].numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
-	inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
+	subgroups::SSBOData inputData;
+	inputData.format = caseDef.format;
+	inputData.layout = subgroups::SSBOData::LayoutStd140;
+	inputData.numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
+	inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
 	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-		return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages);
+		return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
 	else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-		return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages);
+		return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
 	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
+		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
 	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
 	else
 		TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -551,25 +307,18 @@
 	{
 		if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 		{
-			if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
-			{
-				return tcu::TestStatus::fail(
-						   "Shader stage " +
-						   subgroups::getShaderStageName(caseDef.shaderStage) +
-						   " is required to support subgroup operations!");
-			}
-			else
-			{
-				TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
-			}
+			return tcu::TestStatus::fail(
+					"Shader stage " +
+					subgroups::getShaderStageName(caseDef.shaderStage) +
+					" is required to support subgroup operations!");
 		}
-		subgroups::SSBOData inputData[1];
-		inputData[0].format = caseDef.format;
-		inputData[0].layout = subgroups::SSBOData::LayoutStd430;
-		inputData[0].numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
-		inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
+		subgroups::SSBOData inputData;
+		inputData.format = caseDef.format;
+		inputData.layout = subgroups::SSBOData::LayoutStd430;
+		inputData.numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
+		inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
-		return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkCompute);
+		return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkCompute);
 	}
 	else
 	{
@@ -585,7 +334,7 @@
 
 		VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage  & subgroupProperties.supportedStages);
 
-		if ( VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
+		if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
 		{
 			if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
 				TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
@@ -648,8 +397,7 @@
 
 		for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
 		{
-			const std::string op = de::toLower(getOpTypeName(opTypeIndex));
-			const std::string name = op + "_" + subgroups::getFormatNameForGLSL(format);
+			const std::string name = getOpTypeCaseName(opTypeIndex) + "_" + subgroups::getFormatNameForGLSL(format);
 
 			{
 				CaseDefinition caseDef = {opTypeIndex, VK_SHADER_STAGE_COMPUTE_BIT, format, de::SharedPtr<bool>(new bool), DE_FALSE};
@@ -699,6 +447,5 @@
 
 	return group.release();
 }
-
 } // subgroups
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
index 32648ab..9f6c0e1 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
@@ -895,7 +895,6 @@
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
 {
-	DE_UNREF(caseDef);
 	if (!subgroups::isSubgroupSupported(context))
 		TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
 
@@ -1055,7 +1054,7 @@
 
 	for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
 	{
-		CaseDefinition caseDef = {stages[stageIndex],de::SharedPtr<bool>(new bool), DE_TRUE};
+		CaseDefinition caseDef = {stages[stageIndex],de::SharedPtr<bool>(new bool), DE_FALSE};
 		addFunctionCaseWithPrograms(framebufferGroup.get(), getShaderStageName(caseDef.shaderStage), "",
 					supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
 		caseDef.extShaderSubGroupBallotTests = DE_TRUE;
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
index 20a46f8..8388d5a 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBasicTests.cpp
@@ -2167,27 +2167,16 @@
 										supportedCheck, initPrograms, test, caseDef);
 		}
 
-		if (OPTYPE_ELECT == opTypeIndex)
+		for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
 		{
-			for (int stageIndex = 1; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
-			{
-				const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], de::SharedPtr<bool>(new bool)};
-				addFunctionCaseWithPrograms(framebufferGroup.get(),
-							op + "_" + getShaderStageName(caseDef.shaderStage), "",
-							supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
-			}
-		}
-		else
-		{
-			for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
-			{
-				const CaseDefinition caseDefFrag = {opTypeIndex, stages[stageIndex], de::SharedPtr<bool>(new bool)};
-				addFunctionCaseWithPrograms(framebufferGroup.get(),
-							op + "_" + getShaderStageName(caseDefFrag.shaderStage), "",
-							supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDefFrag);
-			}
-		}
+			if (OPTYPE_ELECT == opTypeIndex && stageIndex == 0)
+				continue;		// This is not tested. I don't know why.
 
+			const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], de::SharedPtr<bool>(new bool)};
+			addFunctionCaseWithPrograms(framebufferGroup.get(),
+						op + "_" + getShaderStageName(caseDef.shaderStage), "",
+						supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
+		}
 	}
 
 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
index 1acbd85..efd30d1 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
@@ -375,10 +375,18 @@
 	de::SharedPtr<bool>	geometryPointSizeSupported;
 };
 
+std::string getExtHeader(CaseDefinition caseDef)
+{
+	return	"#extension GL_KHR_shader_subgroup_clustered: enable\n"
+			"#extension GL_KHR_shader_subgroup_ballot: enable\n"
+			+ subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
 std::string getBodySource(CaseDefinition caseDef)
 {
 	std::ostringstream bdy;
-	bdy << "  bool tempResult = true;\n";
+	bdy << "  bool tempResult = true;\n"
+		<< "  uvec4 mask = subgroupBallot(true);\n";
 
 	for (deUint32 i = 1; i <= subgroups::maxSupportedSubgroupSize(); i *= 2)
 	{
@@ -408,324 +416,27 @@
 			<< "        }\n"
 			<< "      }\n"
 			<< "    }\n"
-			<< "  }\n";
+			<< "  }\n"
+			<< "  tempRes = tempResult ? 1 : 0;\n";
 	}
 	return bdy.str();
 }
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
 	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-	subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-		subgroups::setVertexShaderFrameBuffer(programCollection);
-
-	std::string bdy = getBodySource(caseDef);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream				vertexSrc;
-		vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450 )<< "\n"
-			<< "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(location = 0) in highp vec4 in_position;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  out_color = float(tempResult ? 1 : 0);\n"
-			<< "  gl_Position = in_position;\n"
-			<< "  gl_PointSize = 1.0f;\n"
-			<< "}\n";
-		programCollection.glslSources.add("vert")
-			<< glu::VertexSource(vertexSrc.str()) <<buildOptions;
-	}
-	else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream geometry;
-
-		geometry  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(points) in;\n"
-			<< "layout(points, max_vertices = 1) out;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  out_color = tempResult ? 1.0 : 0.0;\n"
-			<< "  gl_Position = gl_in[0].gl_Position;\n"
-			<< (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-			<< "  EmitVertex();\n"
-			<< "  EndPrimitive();\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("geometry")
-			<< glu::GeometrySource(geometry.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream controlSource;
-
-		controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(vertices = 2) out;\n"
-			<< "layout(location = 0) out float out_color[];\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  if (gl_InvocationID == 0)\n"
-			<<"  {\n"
-			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
-			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
-			<< "  }\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  out_color[gl_InvocationID] = tempResult ? 1.0 : 0.0;\n"
-			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("tesc")
-			<< glu::TessellationControlSource(controlSource.str()) << buildOptions;
-		subgroups::setTesEvalShaderFrameBuffer(programCollection);
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream evaluationSource;
-
-		evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout(isolines, equal_spacing, ccw ) in;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  out_color = tempResult ? 1.0 : 0.0;\n"
-			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-			<< "}\n";
-
-		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-		programCollection.glslSources.add("tese")
-			<< glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-	}
-	else
-	{
-		DE_FATAL("Unsupported shader stage");
-	}
+	subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef), getBodySource(caseDef), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-	std::string bdy = getBodySource(caseDef);
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream src;
+	std::string extHeader = getExtHeader(caseDef);
+	std::string testSrc = getBodySource(caseDef);
 
-		src << "#version 450\n"
-			<< "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			<< subgroups::getAdditionalExtensionForFormat(caseDef.format)
-			<< "layout (local_size_x_id = 0, local_size_y_id = 1, "
-			"local_size_z_id = 2) in;\n"
-			<< "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-			<< "{\n"
-			<< "  uint result[];\n"
-			<< "};\n"
-			<< "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
-			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-			"gl_GlobalInvocationID.x;\n"
-			<< "  uvec4 mask = subgroupBallot(true);\n"
-			<< bdy
-			<< "  result[offset] = tempResult ? 1 : 0;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("comp")
-				<< glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-	}
-	else
-	{
-		{
-			const string vertex =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_clustered: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result[gl_VertexIndex] = tempResult ? 1 : 0;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-				"  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-				"  gl_PointSize = 1.0f;\n"
-				"}\n";
-
-			programCollection.glslSources.add("vert")
-				<< glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const string tesc =
-			"#version 450\n"
-			"#extension GL_KHR_shader_subgroup_clustered: enable\n"
-			"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-			+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-			"layout(vertices=1) out;\n"
-			"layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-			"{\n"
-			"  uint result[];\n"
-			"};\n"
-			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-			"{\n"
-			"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-			"};\n"
-			"\n"
-			"void main (void)\n"
-			"{\n"
-			"  uvec4 mask = subgroupBallot(true);\n"
-			+ bdy +
-			"  result[gl_PrimitiveID] = tempResult ? 1 : 0;\n"
-			"  if (gl_InvocationID == 0)\n"
-			"  {\n"
-			"    gl_TessLevelOuter[0] = 1.0f;\n"
-			"    gl_TessLevelOuter[1] = 1.0f;\n"
-			"  }\n"
-			"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			"}\n";
-
-			programCollection.glslSources.add("tesc")
-					<< glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const string tese =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_clustered: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(isolines) in;\n"
-				"layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult ? 1 : 0;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-				"}\n";
-			programCollection.glslSources.add("tese")
-					<< glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		{
-			const string geometry =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_clustered: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(${TOPOLOGY}) in;\n"
-				"layout(points, max_vertices = 1) out;\n"
-				"layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result[gl_PrimitiveIDIn] = tempResult ? 1 : 0;\n"
-				"  gl_Position = gl_in[0].gl_Position;\n"
-				"  EmitVertex();\n"
-				"  EndPrimitive();\n"
-				"}\n";
-			subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u), programCollection.glslSources);
-		}
-
-		{
-			const string fragment =
-				"#version 450\n"
-				"#extension GL_KHR_shader_subgroup_clustered: enable\n"
-				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
-				+ subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-				"layout(location = 0) out uint result;\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"void main (void)\n"
-				"{\n"
-				"  uvec4 mask = subgroupBallot(true);\n"
-				+ bdy +
-				"  result = tempResult ? 1 : 0;\n"
-				"}\n";
-			programCollection.glslSources.add("fragment")
-				<< glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-		}
-
-		subgroups::addNoSubgroupShader(programCollection);
-	}
+   subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -744,11 +455,9 @@
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-	if (!subgroups::areSubgroupOperationsSupportedForStage(
-				context, caseDef.shaderStage))
+	if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 	{
-		if (subgroups::areSubgroupOperationsRequiredForStage(
-					caseDef.shaderStage))
+		if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
 		{
 			return tcu::TestStatus::fail(
 					   "Shader stage " +
@@ -774,21 +483,22 @@
 	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
 		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
 	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-		return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
 	else
 		TCU_THROW(InternalError, "Unhandled shader stage");
 }
 
+
 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
 {
 	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
 	{
 		if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 		{
-				return tcu::TestStatus::fail(
-						   "Shader stage " +
-						   subgroups::getShaderStageName(caseDef.shaderStage) +
-						   " is required to support subgroup operations!");
+			return tcu::TestStatus::fail(
+					"Shader stage " +
+					subgroups::getShaderStageName(caseDef.shaderStage) +
+					" is required to support subgroup operations!");
 		}
 		subgroups::SSBOData inputData;
 		inputData.format = caseDef.format;
@@ -854,7 +564,7 @@
 		VK_SHADER_STAGE_VERTEX_BIT,
 		VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
 		VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
-		VK_SHADER_STAGE_GEOMETRY_BIT
+		VK_SHADER_STAGE_GEOMETRY_BIT,
 	};
 
 	const std::vector<VkFormat> formats = subgroups::getAllFormats();
@@ -937,7 +647,7 @@
 			{
 				const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format, de::SharedPtr<bool>(new bool)};
 				addFunctionCaseWithPrograms(framebufferGroup.get(), name +"_" + getShaderStageName(caseDef.shaderStage), "",
-											supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
+							supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
 			}
 		}
 	}
@@ -950,6 +660,5 @@
 
 	return group.release();
 }
-
 } // subgroups
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
index 15f76f5..080a783 100755
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
@@ -39,6 +39,7 @@
 enum OpType
 {
 	OPTYPE_QUAD_BROADCAST = 0,
+	OPTYPE_QUAD_BROADCAST_NONCONST,
 	OPTYPE_QUAD_SWAP_HORIZONTAL,
 	OPTYPE_QUAD_SWAP_VERTICAL,
 	OPTYPE_QUAD_SWAP_DIAGONAL,
@@ -66,6 +67,7 @@
 			DE_FATAL("Unsupported op type");
 			return "";
 		case OPTYPE_QUAD_BROADCAST:
+		case OPTYPE_QUAD_BROADCAST_NONCONST:
 			return "subgroupQuadBroadcast";
 		case OPTYPE_QUAD_SWAP_HORIZONTAL:
 			return "subgroupQuadSwapHorizontal";
@@ -76,6 +78,26 @@
 	}
 }
 
+std::string getOpTypeCaseName(int opType)
+{
+	switch (opType)
+	{
+		default:
+			DE_FATAL("Unsupported op type");
+			return "";
+		case OPTYPE_QUAD_BROADCAST:
+			return "subgroupquadbroadcast";
+		case OPTYPE_QUAD_BROADCAST_NONCONST:
+			return "subgroupquadbroadcast_nonconst";
+		case OPTYPE_QUAD_SWAP_HORIZONTAL:
+			return "subgroupquadswaphorizontal";
+		case OPTYPE_QUAD_SWAP_VERTICAL:
+			return "subgroupquadswapvertical";
+		case OPTYPE_QUAD_SWAP_DIAGONAL:
+			return "subgroupquadswapdiagonal";
+	}
+}
+
 struct CaseDefinition
 {
 	int					opType;
@@ -84,17 +106,18 @@
 	de::SharedPtr<bool>	geometryPointSizeSupported;
 };
 
-std::string GetExtHeader(VkFormat format)
+std::string getExtHeader(VkFormat format)
 {
 	return	"#extension GL_KHR_shader_subgroup_quad: enable\n"
 			"#extension GL_KHR_shader_subgroup_ballot: enable\n" +
 			subgroups::getAdditionalExtensionForFormat(format);
 }
 
-std::string GetTestSrc(const CaseDefinition &caseDef)
+std::string getTestSrc(const CaseDefinition &caseDef)
 {
 	const std::string swapTable[OPTYPE_LAST] = {
 		"",
+		"",
 		"  const uint swapTable[4] = {1, 0, 3, 2};\n",
 		"  const uint swapTable[4] = {2, 3, 0, 1};\n",
 		"  const uint swapTable[4] = {3, 2, 1, 0};\n",
@@ -123,6 +146,32 @@
 					<< "  }\n";
 		}
 	}
+	else if (caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST)
+	{
+		testSrc << "  for (int i=0; i<4; i++)"
+				<< "  {\n"
+				<< "  " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], i);\n"
+				<< "  uint otherID = (gl_SubgroupInvocationID & ~0x3) + i;\n"
+				<< validate
+				<< "  }\n"
+				<< "  uint quadID = gl_SubgroupInvocationID >> 2;\n"
+				<< "  uint quadInvocation = gl_SubgroupInvocationID & 0x3;\n"
+				<< "  // Test lane ID that is only uniform in active lanes\n"
+				<< "  if (quadInvocation >= 2)\n"
+				<< "  {\n"
+				<< "    uint id = quadInvocation & ~1;\n"
+				<< "    " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], id);\n"
+				<< "    uint otherID = 4*quadID + id;\n"
+				<< validate
+				<< "  }\n"
+				<< "  // Test lane ID that is only quad uniform, not subgroup uniform\n"
+				<< "  {\n"
+				<< "    uint id = quadID & 0x3;\n"
+				<< "    " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], id);\n"
+				<< "    uint otherID = 4*quadID + id;\n"
+				<< validate
+				<< "  }\n";
+	}
 	else
 	{
 		testSrc << "  " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID]);\n"
@@ -133,295 +182,23 @@
 	return testSrc.str();
 }
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
+	const vk::SpirvVersion			spirvVersion = (caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, spirvVersion, 0u);
 
-	subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-		subgroups::setVertexShaderFrameBuffer(programCollection);
-
-	std::string extHeader = GetExtHeader(caseDef.format);
-	std::string testSrc = GetTestSrc(caseDef);
-
-	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream	vertexSrc;
-		vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extHeader.c_str()
-			<< "layout(location = 0) in highp vec4 in_position;\n"
-			<< "layout(location = 0) out float result;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uint tempRes;\n"
-			<< testSrc
-			<< "  result = float(tempRes);\n"
-			<< "  gl_Position = in_position;\n"
-			<< "  gl_PointSize = 1.0f;\n"
-			<< "}\n";
-		programCollection.glslSources.add("vert")
-			<< glu::VertexSource(vertexSrc.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream geometry;
-
-		geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extHeader.c_str()
-			<< "layout(points) in;\n"
-			<< "layout(points, max_vertices = 1) out;\n"
-			<< "layout(location = 0) out float out_color;\n"
-
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uint tempRes;\n"
-			<< testSrc
-			<< "  out_color = float(tempRes);\n"
-			<< "  gl_Position = gl_in[0].gl_Position;\n"
-			<< (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-			<< "  EmitVertex();\n"
-			<< "  EndPrimitive();\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("geometry")
-			<< glu::GeometrySource(geometry.str()) << buildOptions;
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream controlSource;
-
-		controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extHeader.c_str()
-			<< "layout(vertices = 2) out;\n"
-			<< "layout(location = 0) out float out_color[];\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  if (gl_InvocationID == 0)\n"
-			<<"  {\n"
-			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
-			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
-			<< "  }\n"
-			<< "  uint tempRes;\n"
-			<< testSrc
-			<< "  out_color[gl_InvocationID] = float(tempRes);\n"
-			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("tesc")
-			<< glu::TessellationControlSource(controlSource.str()) << buildOptions;
-		subgroups::setTesEvalShaderFrameBuffer(programCollection);
-	}
-	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-	{
-		ostringstream evaluationSource;
-		evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-			<< extHeader.c_str()
-			<< "layout(isolines, equal_spacing, ccw ) in;\n"
-			<< "layout(location = 0) out float out_color;\n"
-			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uint tempRes;\n"
-			<< testSrc
-			<< "  out_color = float(tempRes);\n"
-			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-			<< "}\n";
-
-		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-		programCollection.glslSources.add("tese")
-				<< glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-	}
-	else
-	{
-		DE_FATAL("Unsupported shader stage");
-	}
+   subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef.format), getTestSrc(caseDef), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
+	const vk::SpirvVersion			spirvVersion = (caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, spirvVersion, 0u);
 
-	std::string extHeader = GetExtHeader(caseDef.format);
-	std::string sourceType = GetTestSrc(caseDef);
+	std::string extHeader = getExtHeader(caseDef.format);
+	std::string testSrc = getTestSrc(caseDef);
 
-	if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-	{
-		std::ostringstream src;
-
-		src << "#version 450\n"
-			<< extHeader.c_str()
-			<< "layout (local_size_x_id = 0, local_size_y_id = 1, "
-			"local_size_z_id = 2) in;\n"
-			<< "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-			<< "{\n"
-			<< "  uint result[];\n"
-			<< "};\n"
-			<< "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-			<< "{\n"
-			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-			<< "};\n"
-			<< "\n"
-			<< "void main (void)\n"
-			<< "{\n"
-			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
-			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-			"gl_GlobalInvocationID.x;\n"
-			<< "  uint tempRes;\n"
-			<< sourceType
-			<< "  result[offset] = tempRes;\n"
-			<< "}\n";
-
-		programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
-	}
-	else
-	{
-		{
-			const string vertex =
-				"#version 450\n"
-				+ extHeader +
-				"layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uint tempRes;\n"
-				+ sourceType +
-				"  result[gl_VertexIndex] = tempRes;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-				"  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-				"  gl_PointSize = 1.0f;\n"
-				"}\n";
-			programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions;
-		}
-
-		{
-			const string tesc =
-				"#version 450\n"
-				+ extHeader +
-				"layout(vertices=1) out;\n"
-				"layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uint tempRes;\n"
-				+ sourceType +
-				"  result[gl_PrimitiveID] = tempRes;\n"
-				"  if (gl_InvocationID == 0)\n"
-				"  {\n"
-				"    gl_TessLevelOuter[0] = 1.0f;\n"
-				"    gl_TessLevelOuter[1] = 1.0f;\n"
-				"  }\n"
-				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-				"}\n";
-			programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc) << buildOptions;
-		}
-
-		{
-			const string tese =
-				"#version 450\n"
-				+ extHeader +
-				"layout(isolines) in;\n"
-				"layout(set = 0, binding = 2, std430)  buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uint tempRes;\n"
-				+ sourceType +
-				"  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempRes;\n"
-				"  float pixelSize = 2.0f/1024.0f;\n"
-				"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-				"}\n";
-			programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese) << buildOptions;
-		}
-
-		{
-			const string geometry =
-				"#version 450\n"
-				+ extHeader +
-				"layout(${TOPOLOGY}) in;\n"
-				"layout(points, max_vertices = 1) out;\n"
-				"layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-				"{\n"
-				"  uint result[];\n"
-				"};\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"\n"
-				"void main (void)\n"
-				"{\n"
-				"  uint tempRes;\n"
-				+ sourceType +
-				"  result[gl_PrimitiveIDIn] = tempRes;\n"
-				"  gl_Position = gl_in[0].gl_Position;\n"
-				"  EmitVertex();\n"
-				"  EndPrimitive();\n"
-				"}\n";
-			subgroups::addGeometryShadersFromTemplate(geometry, buildOptions, programCollection.glslSources);
-		}
-
-		{
-			const string fragment =
-				"#version 450\n"
-				+ extHeader +
-				"layout(location = 0) out uint result;\n"
-				"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-				"{\n"
-				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-				"};\n"
-				"void main (void)\n"
-				"{\n"
-				"  uint tempRes;\n"
-				+ sourceType +
-				"  result = tempRes;\n"
-				"}\n";
-			programCollection.glslSources.add("fragment") << glu::FragmentSource(fragment)<< buildOptions;
-		}
-		subgroups::addNoSubgroupShader(programCollection);
-	}
+	subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -435,16 +212,17 @@
 	if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
 		TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
 
+	if ((caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context))
+		TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId");
+
 	*caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
 }
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-	if (!subgroups::areSubgroupOperationsSupportedForStage(
-				context, caseDef.shaderStage))
+	if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 	{
-		if (subgroups::areSubgroupOperationsRequiredForStage(
-					caseDef.shaderStage))
+		if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
 		{
 			return tcu::TestStatus::fail(
 					   "Shader stage " +
@@ -461,7 +239,7 @@
 	inputData.format = caseDef.format;
 	inputData.layout = subgroups::SSBOData::LayoutStd140;
 	inputData.numElements = subgroups::maxSupportedSubgroupSize();
-	inputData.initializeType = subgroups::SSBOData::InitializeNonZero;;
+	inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
 	if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
 		return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
@@ -470,7 +248,7 @@
 	else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
 		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
 	else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-		return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+		return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
 	else
 		TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -483,9 +261,9 @@
 		if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
 		{
 			return tcu::TestStatus::fail(
-					   "Shader stage " +
-					   subgroups::getShaderStageName(caseDef.shaderStage) +
-					   " is required to support subgroup operations!");
+					"Shader stage " +
+					subgroups::getShaderStageName(caseDef.shaderStage) +
+					" is required to support subgroup operations!");
 		}
 		subgroups::SSBOData inputData;
 		inputData.format = caseDef.format;
@@ -562,9 +340,8 @@
 
 		for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
 		{
-			const std::string op = de::toLower(getOpTypeName(opTypeIndex));
 			std::ostringstream name;
-			name << de::toLower(op);
+			name << getOpTypeCaseName(opTypeIndex);
 
 			name << "_" << subgroups::getFormatNameForGLSL(format);
 
@@ -589,7 +366,6 @@
 				addFunctionCaseWithPrograms(framebufferGroup.get(), name.str()+"_"+ getShaderStageName(caseDef.shaderStage), "",
 											supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
 			}
-
 		}
 	}
 
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
index 15fded0..8e31326 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
@@ -961,6 +961,299 @@
 	}
 }
 
+void vkt::subgroups::initStdFrameBufferPrograms(	SourceCollections&				programCollection,
+													const vk::ShaderBuildOptions&	buildOptions,
+													VkShaderStageFlags				shaderStage,
+													VkFormat						format,
+													bool							gsPointSize,
+													std::string						extHeader,
+													std::string						testSrc,
+													std::string						helperStr)
+{
+	subgroups::setFragmentShaderFrameBuffer(programCollection);
+
+	if (shaderStage != VK_SHADER_STAGE_VERTEX_BIT)
+		subgroups::setVertexShaderFrameBuffer(programCollection);
+
+	if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
+	{
+		std::ostringstream vertex;
+		vertex << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+			<< extHeader.c_str()
+			<< "layout(location = 0) in highp vec4 in_position;\n"
+			<< "layout(location = 0) out float result;\n"
+			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
+			<< "{\n"
+			<< "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+			<< "};\n"
+			<< "\n"
+			<< helperStr.c_str()
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "  uint tempRes;\n"
+			<< testSrc
+			<< "  result = float(tempRes);\n"
+			<< "  gl_Position = in_position;\n"
+			<< "  gl_PointSize = 1.0f;\n"
+			<< "}\n";
+		programCollection.glslSources.add("vert")
+			<< glu::VertexSource(vertex.str()) << buildOptions;
+	}
+	else if (shaderStage == VK_SHADER_STAGE_GEOMETRY_BIT)
+	{
+		std::ostringstream geometry;
+
+		geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+			<< extHeader.c_str()
+			<< "layout(points) in;\n"
+			<< "layout(points, max_vertices = 1) out;\n"
+			<< "layout(location = 0) out float out_color;\n"
+			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
+			<< "{\n"
+			<< "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+			<< "};\n"
+			<< "\n"
+			<< helperStr.c_str()
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "  uint tempRes;\n"
+			<< testSrc
+			<< "  out_color = float(tempRes);\n"
+			<< "  gl_Position = gl_in[0].gl_Position;\n"
+			<< (gsPointSize ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
+			<< "  EmitVertex();\n"
+			<< "  EndPrimitive();\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("geometry")
+			<< glu::GeometrySource(geometry.str()) << buildOptions;
+	}
+	else if (shaderStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
+	{
+		std::ostringstream controlSource;
+		controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+			<< extHeader.c_str()
+			<< "layout(vertices = 2) out;\n"
+			<< "layout(location = 0) out float out_color[];\n"
+			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
+			<< "{\n"
+			<< "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+			<< "};\n"
+			<< "\n"
+			<< helperStr.c_str()
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "  if (gl_InvocationID == 0)\n"
+			<< "  {\n"
+			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
+			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
+			<< "  }\n"
+			<< "  uint tempRes;\n"
+			<< testSrc
+			<< "  out_color[gl_InvocationID] = float(tempRes);\n"
+			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("tesc")
+			<< glu::TessellationControlSource(controlSource.str()) << buildOptions;
+		subgroups::setTesEvalShaderFrameBuffer(programCollection);
+	}
+	else if (shaderStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
+	{
+		ostringstream evaluationSource;
+		evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+			<< extHeader.c_str()
+			<< "layout(isolines, equal_spacing, ccw ) in;\n"
+			<< "layout(location = 0) out float out_color;\n"
+			<< "layout(set = 0, binding = 0) uniform Buffer1\n"
+			<< "{\n"
+			<< "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+			<< "};\n"
+			<< "\n"
+			<< helperStr.c_str()
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "  uint tempRes;\n"
+			<< testSrc
+			<< "  out_color = float(tempRes);\n"
+			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
+			<< "}\n";
+
+		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
+		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
+	}
+	else
+	{
+		DE_FATAL("Unsupported shader stage");
+	}
+}
+
+void vkt::subgroups::initStdPrograms(	vk::SourceCollections&			programCollection,
+										const vk::ShaderBuildOptions&	buildOptions,
+										vk::VkShaderStageFlags			shaderStage,
+										vk::VkFormat					format,
+										std::string						extHeader,
+										std::string						testSrc,
+										std::string						helperStr)
+{
+	if (shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
+	{
+		std::ostringstream src;
+
+		src << "#version 450\n"
+			<< extHeader.c_str()
+			<< "layout (local_size_x_id = 0, local_size_y_id = 1, "
+			"local_size_z_id = 2) in;\n"
+			<< "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
+			<< "{\n"
+			<< "  uint result[];\n"
+			<< "};\n"
+			<< "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
+			<< "{\n"
+			<< "  " << subgroups::getFormatNameForGLSL(format) << " data[];\n"
+			<< "};\n"
+			<< "\n"
+			<< helperStr.c_str()
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
+			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
+			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
+			"gl_GlobalInvocationID.x;\n"
+			<< "  uint tempRes;\n"
+			<< testSrc
+			<< "  result[offset] = tempRes;\n"
+			<< "}\n";
+
+		programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
+	}
+	else
+	{
+		const string vertex =
+			"#version 450\n"
+			+ extHeader +
+			"layout(set = 0, binding = 0, std430) buffer Buffer1\n"
+			"{\n"
+			"  uint result[];\n"
+			"};\n"
+			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+			"{\n"
+			"  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+			"};\n"
+			"\n"
+			+ helperStr +
+			"void main (void)\n"
+			"{\n"
+			"  uint tempRes;\n"
+			+ testSrc +
+			"  result[gl_VertexIndex] = tempRes;\n"
+			"  float pixelSize = 2.0f/1024.0f;\n"
+			"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
+			"  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
+			"  gl_PointSize = 1.0f;\n"
+			"}\n";
+
+		const string tesc =
+			"#version 450\n"
+			+ extHeader +
+			"layout(vertices=1) out;\n"
+			"layout(set = 0, binding = 1, std430) buffer Buffer1\n"
+			"{\n"
+			"  uint result[];\n"
+			"};\n"
+			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+			"{\n"
+			"  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+			"};\n"
+			"\n"
+			+ helperStr +
+			"void main (void)\n"
+			"{\n"
+			"  uint tempRes;\n"
+			+ testSrc +
+			"  result[gl_PrimitiveID] = tempRes;\n"
+			"  if (gl_InvocationID == 0)\n"
+			"  {\n"
+			"    gl_TessLevelOuter[0] = 1.0f;\n"
+			"    gl_TessLevelOuter[1] = 1.0f;\n"
+			"  }\n"
+			"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+			"}\n";
+
+		const string tese =
+			"#version 450\n"
+			+ extHeader +
+			"layout(isolines) in;\n"
+			"layout(set = 0, binding = 2, std430) buffer Buffer1\n"
+			"{\n"
+			"  uint result[];\n"
+			"};\n"
+			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+			"{\n"
+			"  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+			"};\n"
+			"\n"
+			+ helperStr +
+			"void main (void)\n"
+			"{\n"
+			"  uint tempRes;\n"
+			+ testSrc +
+			"  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempRes;\n"
+			"  float pixelSize = 2.0f/1024.0f;\n"
+			"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
+			"}\n";
+
+		const string geometry =
+			"#version 450\n"
+			+ extHeader +
+			"layout(${TOPOLOGY}) in;\n"
+			"layout(points, max_vertices = 1) out;\n"
+			"layout(set = 0, binding = 3, std430) buffer Buffer1\n"
+			"{\n"
+			"  uint result[];\n"
+			"};\n"
+			"layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+			"{\n"
+			"  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+			"};\n"
+			"\n"
+			+ helperStr +
+			"void main (void)\n"
+			"{\n"
+			"  uint tempRes;\n"
+			+ testSrc +
+			"  result[gl_PrimitiveIDIn] = tempRes;\n"
+			"  gl_Position = gl_in[0].gl_Position;\n"
+			"  EmitVertex();\n"
+			"  EndPrimitive();\n"
+			"}\n";
+
+		const string fragment =
+			"#version 450\n"
+			+ extHeader +
+			"layout(location = 0) out uint result;\n"
+			"layout(set = 0, binding = 4, std430) readonly buffer Buffer1\n"
+			"{\n"
+			"  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+			"};\n"
+			+ helperStr +
+			"void main (void)\n"
+			"{\n"
+			"  uint tempRes;\n"
+			+ testSrc +
+			"  result = tempRes;\n"
+			"}\n";
+
+		subgroups::addNoSubgroupShader(programCollection);
+
+		programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions;
+		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc) << buildOptions;
+		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese) << buildOptions;
+		subgroups::addGeometryShadersFromTemplate(geometry, buildOptions, programCollection.glslSources);
+		programCollection.glslSources.add("fragment") << glu::FragmentSource(fragment)<< buildOptions;
+	}
+}
+
 bool vkt::subgroups::isSubgroupSupported(Context& context)
 {
 	return context.contextSupports(vk::ApiVersion(1, 1, 0));
@@ -1040,14 +1333,14 @@
 
 bool vkt::subgroups::isFormatSupportedForDevice(Context& context, vk::VkFormat format)
 {
-	VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR subgroupExtendedTypesFeatures;
+	VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures subgroupExtendedTypesFeatures;
 	deMemset(&subgroupExtendedTypesFeatures, 0, sizeof(subgroupExtendedTypesFeatures));
-	subgroupExtendedTypesFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR;
+	subgroupExtendedTypesFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;
 	subgroupExtendedTypesFeatures.pNext = DE_NULL;
 
-	VkPhysicalDeviceShaderFloat16Int8FeaturesKHR float16Int8Features;
+	VkPhysicalDeviceShaderFloat16Int8Features float16Int8Features;
 	deMemset(&float16Int8Features, 0, sizeof(float16Int8Features));
-	float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
+	float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
 	float16Int8Features.pNext = DE_NULL;
 
 	VkPhysicalDeviceFeatures2 features2;
@@ -1123,6 +1416,12 @@
 	}
 }
 
+bool vkt::subgroups::isSubgroupBroadcastDynamicIdSupported (Context& context)
+{
+	return context.contextSupports(vk::ApiVersion(1, 2, 0)) &&
+		vk::getPhysicalDeviceVulkan12Features(context.getInstanceInterface(), context.getPhysicalDevice()).subgroupBroadcastDynamicId;
+}
+
 std::string vkt::subgroups::getFormatNameForGLSL (VkFormat format)
 {
 	switch (format)
@@ -3143,23 +3442,16 @@
 
 	const deUint32 numWorkgroups[3] = {4, 2, 2};
 
-	const deUint32 localSizesToTestCount = 15;
+	const deUint32 localSizesToTestCount = 8;
 	deUint32 localSizesToTest[localSizesToTestCount][3] =
 	{
 		{1, 1, 1},
-		{32, 4, 1},
-		{32, 1, 4},
-		{1, 32, 4},
-		{1, 4, 32},
-		{4, 1, 32},
-		{4, 32, 1},
 		{subgroupSize, 1, 1},
 		{1, subgroupSize, 1},
 		{1, 1, subgroupSize},
+		{32, 4, 1},
+		{1, 4, 32},
 		{3, 5, 7},
-		{128, 1, 1},
-		{1, 128, 1},
-		{1, 1, 64},
 		{1, 1, 1} // Isn't used, just here to make double buffering checks easier
 	};
 
diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp
index 67e2256..80e48e1 100644
--- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp
+++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp
@@ -104,6 +104,23 @@
 
 std::string getVertShaderForStage(vk::VkShaderStageFlags stage);//TODO
 
+void initStdFrameBufferPrograms(	vk::SourceCollections&			programCollection,
+									const vk::ShaderBuildOptions&	buildOptions,
+									vk::VkShaderStageFlags			shaderStage,
+									vk::VkFormat					format,
+									bool							gsPointSize,
+									std::string						extHeader,
+									std::string						testSrc,
+									std::string						helperStr);
+
+void initStdPrograms(	vk::SourceCollections&			programCollection,
+								const vk::ShaderBuildOptions&	buildOptions,
+								vk::VkShaderStageFlags			shaderStage,
+								vk::VkFormat					format,
+								std::string						extHeader,
+								std::string						testSrc,
+								std::string						helperStr);
+
 bool isSubgroupSupported(Context& context);
 
 bool areSubgroupOperationsSupportedForStage(
@@ -123,6 +140,8 @@
 
 bool isTessellationAndGeometryPointSizeSupported(Context& context);
 
+bool isSubgroupBroadcastDynamicIdSupported(Context& context);
+
 std::string getFormatNameForGLSL (vk::VkFormat format);
 
 std::string getAdditionalExtensionForFormat (vk::VkFormat format);
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicEventTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicEventTests.cpp
index c80d24d..c2e76f1 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicEventTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicEventTests.cpp
@@ -122,52 +122,6 @@
 	return tcu::TestStatus::pass("Device set and reset event tests pass");
 }
 
-tcu::TestStatus deviceWaitForEventCase (Context& context)
-{
-	const DeviceInterface&			vk					= context.getDeviceInterface();
-	const VkDevice					device				= context.getDevice();
-	const VkQueue					queue				= context.getUniversalQueue();
-	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
-	const Unique<VkFence>			fence				(createFence(vk, device));
-	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
-	const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
-	const VkSubmitInfo				submitInfo			=
-														{
-															VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
-															DE_NULL,						// const void*					pNext;
-															0u,								// deUint32						waitSemaphoreCount;
-															DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
-															DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
-															1u,								// deUint32						commandBufferCount;
-															&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
-															0u,								// deUint32						signalSemaphoreCount;
-															DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
-														};
-	const VkEventCreateInfo			eventInfo			=
-														{
-															VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
-															DE_NULL,
-															0
-														};
-	const Unique<VkEvent>			event				(createEvent(vk, device, &eventInfo, DE_NULL));
-
-	beginCommandBuffer(vk, *cmdBuffer);
-	vk.cmdWaitEvents(*cmdBuffer, 1u, &event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
-	endCommandBuffer(vk, *cmdBuffer);
-
-	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
-	if (VK_TIMEOUT != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, SHORT_FENCE_WAIT))
-		return tcu::TestStatus::fail("Queue should not end execution");
-
-	if (VK_SUCCESS != vk.setEvent(device, *event))
-		return tcu::TestStatus::fail("Couldn't set event");
-
-	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
-		return tcu::TestStatus::fail("Queue should end execution");
-
-	return tcu::TestStatus::pass("Device wait for event tests pass");
-}
-
 tcu::TestStatus singleSubmissionCase (Context& context)
 {
 	enum {SET=0, WAIT, COUNT};
@@ -347,7 +301,6 @@
 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event", "Basic event tests"));
 	addFunctionCase(basicTests.get(), "host_set_reset",   "Basic event tests set and reset on host", hostResetSetEventCase);
 	addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", deviceResetSetEventCase);
-	addFunctionCase(basicTests.get(), "host_set_device_wait", "Wait for event on device test", deviceWaitForEventCase);
 	addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", singleSubmissionCase);
 	addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", multiSubmissionCase);
 	addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", secondaryCommandBufferCase);
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicSemaphoreTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicSemaphoreTests.cpp
index f697be1..208e9a4 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicSemaphoreTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationBasicSemaphoreTests.cpp
@@ -47,8 +47,8 @@
 
 struct TestConfig
 {
-	bool				useTypeCreate;
-	VkSemaphoreTypeKHR	semaphoreType;
+	bool			useTypeCreate;
+	VkSemaphoreType	semaphoreType;
 };
 
 static const int basicChainLength	= 32768;
@@ -83,18 +83,18 @@
 																};
 	const VkPipelineStageFlags				stageBits[]			= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
 	const deUint64							timelineValue		= 1u;
-	const VkTimelineSemaphoreSubmitInfoKHR	timelineWaitInfo	=
+	const VkTimelineSemaphoreSubmitInfo		timelineWaitInfo	=
 																{
-																	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+																	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 																	DE_NULL,												// const void*		pNext;
 																	1u,														// deUint32			waitSemaphoreValueCount
 																	&timelineValue,											// const deUint64*	pWaitSemaphoreValues
 																	0u,														// deUint32			signalSemaphoreValueCount
 																	DE_NULL,												// const deUint64*	pSignalSemaphoreValues
 																};
-	const VkTimelineSemaphoreSubmitInfoKHR	timelineSignalInfo	=
+	const VkTimelineSemaphoreSubmitInfo		timelineSignalInfo	=
 																{
-																	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+																	VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 																	DE_NULL,												// const void*		pNext;
 																	0u,														// deUint32			waitSemaphoreValueCount
 																	DE_NULL,												// const deUint64*	pWaitSemaphoreValues
@@ -196,7 +196,7 @@
 	const VkDevice&					device		= context.getDevice();
 	const VkQueue					queue		= context.getUniversalQueue();
 	VkPipelineStageFlags			flags		= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-	VkSemaphoreTypeCreateInfoKHR	scti		= { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE_KHR, 0 };
+	VkSemaphoreTypeCreateInfo		scti		= { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE_KHR, 0 };
 	VkSemaphoreCreateInfo			sci			= { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
 	VkFenceCreateInfo				fci			= { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
 	VkSemaphore						semaphore;
@@ -209,11 +209,11 @@
 
 	for (int i = 0; err == VK_SUCCESS && i < basicChainLength; i++)
 	{
-		deUint64							waitValue = i;
-		deUint64							signalValue = i + 1;
-		VkTimelineSemaphoreSubmitInfoKHR	tsi =
+		deUint64						waitValue = i;
+		deUint64						signalValue = i + 1;
+		VkTimelineSemaphoreSubmitInfo	tsi =
 		{
-			VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+			VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 			DE_NULL,												// const void*		pNext;
 			i == 0 ? 0u : 1u,										// deUint32			waitSemaphoreValueCount
 			&waitValue,												// const deUint64*	pWaitSemaphoreValues
@@ -237,10 +237,10 @@
 
 	VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
 
-	deUint64							waitValue = basicChainLength;
-	VkTimelineSemaphoreSubmitInfoKHR	tsi =
+	deUint64						waitValue = basicChainLength;
+	VkTimelineSemaphoreSubmitInfo	tsi =
 	{
-		VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+		VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 		DE_NULL,												// const void*		pNext;
 		1u,														// deUint32			waitSemaphoreValueCount
 		&waitValue,												// const deUint64*	pWaitSemaphoreValues
@@ -310,7 +310,7 @@
 	Move<VkCommandBuffer>					cmdBuffer[COUNT];
 	const VkPipelineStageFlags				stageBits[]					= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
 	VkSubmitInfo							submitInfo[COUNT];
-	VkTimelineSemaphoreSubmitInfoKHR		timelineSubmitInfo[COUNT];
+	VkTimelineSemaphoreSubmitInfo			timelineSubmitInfo[COUNT];
 	deUint64								timelineValues[COUNT];
 	Move<VkFence>							fence[COUNT];
 
@@ -380,7 +380,7 @@
 
 	timelineValues[FIRST]									= 1ull;
 
-	timelineSubmitInfo[FIRST].sType							= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
+	timelineSubmitInfo[FIRST].sType							= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
 	timelineSubmitInfo[FIRST].pNext							= DE_NULL;
 	timelineSubmitInfo[FIRST].waitSemaphoreValueCount		= 0;
 	timelineSubmitInfo[FIRST].pWaitSemaphoreValues			= DE_NULL;
@@ -399,7 +399,7 @@
 
 	timelineValues[SECOND]									= 2ull;
 
-	timelineSubmitInfo[SECOND].sType						= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
+	timelineSubmitInfo[SECOND].sType						= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
 	timelineSubmitInfo[SECOND].pNext						= DE_NULL;
 	timelineSubmitInfo[SECOND].waitSemaphoreValueCount		= 1;
 	timelineSubmitInfo[SECOND].pWaitSemaphoreValues			= &timelineValues[FIRST];
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationCrossInstanceSharingTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationCrossInstanceSharingTests.cpp
index a6e9dcb..08f1dc6 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationCrossInstanceSharingTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationCrossInstanceSharingTests.cpp
@@ -58,7 +58,7 @@
 struct TestConfig
 {
 								TestConfig		(const ResourceDescription&						resource_,
-												 vk::VkSemaphoreTypeKHR							semaphoreType_,
+												 vk::VkSemaphoreType							semaphoreType_,
 												 OperationName									writeOp_,
 												 OperationName									readOp_,
 												 vk::VkExternalMemoryHandleTypeFlagBits			memoryHandleType_,
@@ -75,7 +75,7 @@
 	}
 
 	const ResourceDescription							resource;
-	const vk::VkSemaphoreTypeKHR						semaphoreType;
+	const vk::VkSemaphoreType							semaphoreType;
 	const OperationName									writeOp;
 	const OperationName									readOp;
 	const vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleType;
@@ -95,29 +95,29 @@
 	: m_context	(context)
 	{
 		// Check instance support
-		requireInstanceExtension("VK_KHR_get_physical_device_properties2");
+		m_context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
 
-		requireInstanceExtension("VK_KHR_external_semaphore_capabilities");
-		requireInstanceExtension("VK_KHR_external_memory_capabilities");
+		m_context.requireInstanceFunctionality("VK_KHR_external_semaphore_capabilities");
+		m_context.requireInstanceFunctionality("VK_KHR_external_memory_capabilities");
 
 		// Check device support
 		if (config.dedicated)
-			requireDeviceExtension("VK_KHR_dedicated_allocation");
+			m_context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
 
-		requireDeviceExtension("VK_KHR_external_semaphore");
-		requireDeviceExtension("VK_KHR_external_memory");
+		m_context.requireDeviceFunctionality("VK_KHR_external_semaphore");
+		m_context.requireDeviceFunctionality("VK_KHR_external_memory");
 
 		if (config.semaphoreType == vk::VK_SEMAPHORE_TYPE_TIMELINE_KHR)
 		{
-			requireDeviceExtension("VK_KHR_timeline_semaphore");
+			m_context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
 		}
 
 		if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
 			|| config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
 			|| config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
 		{
-			requireDeviceExtension("VK_KHR_external_semaphore_fd");
-			requireDeviceExtension("VK_KHR_external_memory_fd");
+			m_context.requireDeviceFunctionality("VK_KHR_external_semaphore_fd");
+			m_context.requireDeviceFunctionality("VK_KHR_external_memory_fd");
 		}
 
 		if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
@@ -125,8 +125,8 @@
 			|| config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
 			|| config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
 		{
-			requireDeviceExtension("VK_KHR_external_semaphore_win32");
-			requireDeviceExtension("VK_KHR_external_memory_win32");
+			m_context.requireDeviceFunctionality("VK_KHR_external_semaphore_win32");
+			m_context.requireDeviceFunctionality("VK_KHR_external_memory_win32");
 		}
 
 		TestLog&						log				= context.getTestContext().getLog();
@@ -260,17 +260,6 @@
 	}
 
 private:
-	void requireDeviceExtension(const char* name) const
-	{
-		if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), name))
-			TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
-	}
-
-	void requireInstanceExtension(const char* name) const
-	{
-		if (!de::contains(m_context.getInstanceExtensions().begin(), m_context.getInstanceExtensions().end(), name))
-			TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
-	}
 
 	const Context& m_context;
 };
@@ -324,8 +313,7 @@
 										 const vk::PlatformInterface&	vkp,
 										 vk::VkInstance					instance,
 										 const vk::InstanceInterface&	vki,
-										 const vk::VkPhysicalDevice		physicalDevice,
-										 bool							timelineSemaphores)
+										 const vk::VkPhysicalDevice		physicalDevice)
 {
 	const bool										validationEnabled		= context.getTestContext().getCommandLine().isValidationEnabled();
 	const float										priority				= 0.0f;
@@ -354,7 +342,7 @@
 	if (context.isDeviceFunctionalitySupported("VK_KHR_external_memory_win32"))
 		extensions.push_back("VK_KHR_external_memory_win32");
 
-	if (timelineSemaphores)
+	if (context.isDeviceFunctionalitySupported("VK_KHR_timeline_semaphore"))
 		extensions.push_back("VK_KHR_timeline_semaphore");
 
 	try
@@ -414,34 +402,74 @@
 // Class to wrap a singleton instance and device
 class InstanceAndDevice
 {
-public:
-	InstanceAndDevice	(Context&			context,
-	                     const TestConfig&	config)
+	InstanceAndDevice	(Context& context)
 		: m_instance		(createTestInstance(context))
 		, m_vki				(m_instance.getDriver())
 		, m_physicalDevice	(vk::chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
-		, m_logicalDevice	(createTestDevice(context, context.getPlatformInterface(), m_instance, m_vki, m_physicalDevice, config.semaphoreType == vk::VK_SEMAPHORE_TYPE_TIMELINE_KHR))
+		, m_logicalDevice	(createTestDevice(context, context.getPlatformInterface(), m_instance, m_vki, m_physicalDevice))
 	{
 	}
 
-	vk::VkInstance				getInstance()
-	{
-		return m_instance;
-	}
+public:
 
-	const vk::InstanceDriver&	getDriver()
+	static vk::VkInstance getInstanceA(Context& context)
 	{
-		return m_vki;
-	}
+		if (!m_instanceA)
+			m_instanceA = SharedPtr<InstanceAndDevice>(new InstanceAndDevice(context));
 
-	vk::VkPhysicalDevice		getPhysicalDevice()
-	{
-		return m_physicalDevice;
+		return m_instanceA->m_instance;
 	}
-
-	const Unique<vk::VkDevice>& getDevice()
+	static vk::VkInstance getInstanceB(Context& context)
 	{
-		return m_logicalDevice;
+		if (!m_instanceB)
+			m_instanceB = SharedPtr<InstanceAndDevice>(new InstanceAndDevice(context));
+
+		return m_instanceB->m_instance;
+	}
+	static const vk::InstanceDriver& getDriverA()
+	{
+		DE_ASSERT(m_instanceA);
+		return m_instanceA->m_instance.getDriver();
+	}
+	static const vk::InstanceDriver& getDriverB()
+	{
+		DE_ASSERT(m_instanceB);
+		return m_instanceB->m_instance.getDriver();
+	}
+	static vk::VkPhysicalDevice getPhysicalDeviceA()
+	{
+		DE_ASSERT(m_instanceA);
+		return m_instanceA->m_physicalDevice;
+	}
+	static vk::VkPhysicalDevice getPhysicalDeviceB()
+	{
+		DE_ASSERT(m_instanceB);
+		return m_instanceB->m_physicalDevice;
+	}
+	static const Unique<vk::VkDevice>& getDeviceA()
+	{
+		DE_ASSERT(m_instanceA);
+		return m_instanceA->m_logicalDevice;
+	}
+	static const Unique<vk::VkDevice>& getDeviceB()
+	{
+		DE_ASSERT(m_instanceB);
+		return m_instanceB->m_logicalDevice;
+	}
+	static void collectMessagesA()
+	{
+		DE_ASSERT(m_instanceA);
+		m_instanceA->m_instance.collectMessages();
+	}
+	static void collectMessagesB()
+	{
+		DE_ASSERT(m_instanceB);
+		m_instanceB->m_instance.collectMessages();
+	}
+	static void destroy()
+	{
+		m_instanceA.clear();
+		m_instanceB.clear();
 	}
 
 private:
@@ -449,7 +477,12 @@
 	const vk::InstanceDriver&		m_vki;
 	const vk::VkPhysicalDevice		m_physicalDevice;
 	const Unique<vk::VkDevice>		m_logicalDevice;
+
+	static SharedPtr<InstanceAndDevice>	m_instanceA;
+	static SharedPtr<InstanceAndDevice>	m_instanceB;
 };
+SharedPtr<InstanceAndDevice>		InstanceAndDevice::m_instanceA;
+SharedPtr<InstanceAndDevice>		InstanceAndDevice::m_instanceB;
 
 
 vk::VkQueue getQueue (const vk::DeviceInterface&	vkd,
@@ -968,7 +1001,6 @@
 
 	const bool											m_getMemReq2Supported;
 
-	InstanceAndDevice									m_instanceAndDeviceA;
 	const vk::VkInstance								m_instanceA;
 	const vk::InstanceDriver&							m_vkiA;
 	const vk::VkPhysicalDevice							m_physicalDeviceA;
@@ -977,7 +1009,6 @@
 	const vk::Unique<vk::VkDevice>&						m_deviceA;
 	const vk::DeviceDriver								m_vkdA;
 
-	InstanceAndDevice									m_instanceAndDeviceB;
 	const vk::VkInstance								m_instanceB;
 	const vk::InstanceDriver&							m_vkiB;
 	const vk::VkPhysicalDevice							m_physicalDeviceB;
@@ -1005,22 +1036,20 @@
 	, m_notSupportedChecker		(context, m_config, *m_supportWriteOp, *m_supportReadOp)
 	, m_getMemReq2Supported		(context.isDeviceFunctionalitySupported("VK_KHR_get_memory_requirements2"))
 
-	, m_instanceAndDeviceA		(context, config)
-	, m_instanceA				(m_instanceAndDeviceA.getInstance())
-	, m_vkiA					(m_instanceAndDeviceA.getDriver())
-	, m_physicalDeviceA			(m_instanceAndDeviceA.getPhysicalDevice())
+	, m_instanceA				(InstanceAndDevice::getInstanceA(context))
+	, m_vkiA					(InstanceAndDevice::getDriverA())
+	, m_physicalDeviceA			(InstanceAndDevice::getPhysicalDeviceA())
 	, m_queueFamiliesA			(vk::getPhysicalDeviceQueueFamilyProperties(m_vkiA, m_physicalDeviceA))
 	, m_queueFamilyIndicesA		(getFamilyIndices(m_queueFamiliesA))
-	, m_deviceA					(m_instanceAndDeviceA.getDevice())
+	, m_deviceA					(InstanceAndDevice::getDeviceA())
 	, m_vkdA					(context.getPlatformInterface(), m_instanceA, *m_deviceA)
 
-	, m_instanceAndDeviceB		(context, config)
-	, m_instanceB				(m_instanceAndDeviceB.getInstance())
-	, m_vkiB					(m_instanceAndDeviceB.getDriver())
-	, m_physicalDeviceB			(m_instanceAndDeviceB.getPhysicalDevice())
+	, m_instanceB				(InstanceAndDevice::getInstanceB(context))
+	, m_vkiB					(InstanceAndDevice::getDriverB())
+	, m_physicalDeviceB			(InstanceAndDevice::getPhysicalDeviceB())
 	, m_queueFamiliesB			(vk::getPhysicalDeviceQueueFamilyProperties(m_vkiB, m_physicalDeviceB))
 	, m_queueFamilyIndicesB		(getFamilyIndices(m_queueFamiliesB))
-	, m_deviceB					(m_instanceAndDeviceB.getDevice())
+	, m_deviceB					(InstanceAndDevice::getDeviceB())
 	, m_vkdB					(context.getPlatformInterface(), m_instanceB, *m_deviceB)
 
 	, m_semaphoreHandleType		(m_config.semaphoreHandleType)
@@ -1061,8 +1090,7 @@
 		const vk::Unique<vk::VkCommandPool>		commandPoolA		(createCommandPool(m_vkdA, *m_deviceA, queueFamilyA));
 		const vk::Unique<vk::VkCommandBuffer>	commandBufferA		(createCommandBuffer(m_vkdA, *m_deviceA, *commandPoolA));
 		vk::SimpleAllocator						allocatorA			(m_vkdA, *m_deviceA, vk::getPhysicalDeviceMemoryProperties(m_vkiA, m_physicalDeviceA));
-		const std::vector<std::string>			deviceExtensionsA;
-		OperationContext						operationContextA	(m_context, m_vkiA, m_vkdA, m_physicalDeviceA, *m_deviceA, allocatorA, deviceExtensionsA, m_context.getBinaryCollection(), m_pipelineCacheData);
+		OperationContext						operationContextA	(m_context, m_vkiA, m_vkdA, m_physicalDeviceA, *m_deviceA, allocatorA, m_context.getBinaryCollection(), m_pipelineCacheData);
 
 		if (!checkQueueFlags(m_queueFamiliesA[m_queueANdx].queueFlags , m_supportWriteOp->getQueueFlags(operationContextA)))
 			TCU_THROW(NotSupportedError, "Operation not supported by the source queue");
@@ -1071,8 +1099,7 @@
 		const vk::Unique<vk::VkCommandPool>		commandPoolB		(createCommandPool(m_vkdB, *m_deviceB, queueFamilyB));
 		const vk::Unique<vk::VkCommandBuffer>	commandBufferB		(createCommandBuffer(m_vkdB, *m_deviceB, *commandPoolB));
 		vk::SimpleAllocator						allocatorB			(m_vkdB, *m_deviceB, vk::getPhysicalDeviceMemoryProperties(m_vkiB, m_physicalDeviceB));
-		const std::vector<std::string>			deviceExtensionsB;
-		OperationContext						operationContextB	(m_context, m_vkiB, m_vkdB, m_physicalDeviceB, *m_deviceB, allocatorB, deviceExtensionsB, m_context.getBinaryCollection(), m_pipelineCacheData);
+		OperationContext						operationContextB	(m_context, m_vkiB, m_vkdB, m_physicalDeviceB, *m_deviceB, allocatorB, m_context.getBinaryCollection(), m_pipelineCacheData);
 
 		if (!checkQueueFlags(m_queueFamiliesB[m_queueBNdx].queueFlags , m_supportReadOp->getQueueFlags(operationContextB)))
 			TCU_THROW(NotSupportedError, "Operation not supported by the destination queue");
@@ -1098,9 +1125,9 @@
 			const deUint64								timelineValue				= rng.getInt(1, deIntMaxValue32(32));
 			const vk::VkCommandBuffer					commandBuffer				= *commandBufferA;
 			const vk::VkSemaphore						semaphore					= *semaphoreA;
-			const vk::VkTimelineSemaphoreSubmitInfoKHR	semaphoreSubmitInfo	=
+			const vk::VkTimelineSemaphoreSubmitInfo		semaphoreSubmitInfo	=
 			{
-				vk::VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+				vk::VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 				DE_NULL,													// const void*		pNext;
 				0u,															// deUint32			waitSemaphoreValueCount
 				DE_NULL,													// const deUint64*	pWaitSemaphoreValues
@@ -1134,9 +1161,9 @@
 			const vk::VkCommandBuffer					commandBuffer			= *commandBufferB;
 			const vk::VkSemaphore						semaphore				= *semaphoreB;
 			const vk::VkPipelineStageFlags				dstStage				= readSync.stageMask;
-			const vk::VkTimelineSemaphoreSubmitInfoKHR	semaphoreSubmitInfo		=
+			const vk::VkTimelineSemaphoreSubmitInfo		semaphoreSubmitInfo		=
 			{
-				vk::VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+				vk::VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 				DE_NULL,													// const void*		pNext;
 				1u,															// deUint32			waitSemaphoreValueCount
 				&timelineValue,												// const deUint64*	pWaitSemaphoreValues
@@ -1169,8 +1196,8 @@
 			deUint64	valueA;
 			deUint64	valueB;
 
-			VK_CHECK(m_vkdA.getSemaphoreCounterValueKHR(*m_deviceA, *semaphoreA, &valueA));
-			VK_CHECK(m_vkdB.getSemaphoreCounterValueKHR(*m_deviceB, *semaphoreB, &valueB));
+			VK_CHECK(m_vkdA.getSemaphoreCounterValue(*m_deviceA, *semaphoreA, &valueA));
+			VK_CHECK(m_vkdB.getSemaphoreCounterValue(*m_deviceB, *semaphoreB, &valueB));
 
 			if (valueA != valueB)
 				return tcu::TestStatus::fail("Inconsistent values between shared semaphores");
@@ -1252,6 +1279,10 @@
 		m_resultCollector.fail(std::string("Exception: ") + error.getMessage());
 	}
 
+	// Collect possible validation errors.
+	InstanceAndDevice::collectMessagesA();
+	InstanceAndDevice::collectMessagesB();
+
 	// Move to next queue
 	{
 		m_queueBNdx++;
@@ -1322,7 +1353,7 @@
 		},
 	};
 
-	const std::string semaphoreNames[vk::VK_SEMAPHORE_TYPE_KHR_LAST] =
+	const std::string semaphoreNames[vk::VK_SEMAPHORE_TYPE_LAST] =
 	{
 		"_binary_semaphore",
 		"_timeline_semaphore",
@@ -1349,11 +1380,11 @@
 
 				for (size_t caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
 				{
-					for (int semaphoreType = 0; semaphoreType < vk::VK_SEMAPHORE_TYPE_KHR_LAST; semaphoreType++)
+					for (int semaphoreType = 0; semaphoreType < vk::VK_SEMAPHORE_TYPE_LAST; semaphoreType++)
 					{
 						if (isResourceSupported(writeOp, resource) && isResourceSupported(readOp, resource))
 						{
-							const TestConfig	config (resource, (vk::VkSemaphoreTypeKHR)semaphoreType, writeOp, readOp, cases[caseNdx].memoryType, cases[caseNdx].semaphoreType, dedicated);
+							const TestConfig	config (resource, (vk::VkSemaphoreType)semaphoreType, writeOp, readOp, cases[caseNdx].memoryType, cases[caseNdx].semaphoreType, dedicated);
 							std::string			name	= getResourceName(resource) + semaphoreNames[semaphoreType] + cases[caseNdx].nameSuffix;
 
 							opGroup->addChild(new InstanceFactory1<SharingTestInstance, TestConfig, Progs>(testCtx, tcu::NODETYPE_SELF_VALIDATE,  name, "", Progs(), config));
@@ -1375,7 +1406,7 @@
 {
 	DE_UNREF(group);
 	// Destroy singleton object
-
+	InstanceAndDevice::destroy();
 }
 
 tcu::TestCaseGroup* createCrossInstanceSharingTest (tcu::TestContext& testCtx)
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
index 8b552e8..aebfbce 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp
@@ -386,41 +386,6 @@
 	}
 }
 
-//! Storage image format that requires StorageImageExtendedFormats SPIR-V capability (listed only Vulkan-defined formats).
-bool isStorageImageExtendedFormat (const VkFormat format)
-{
-	switch (format)
-	{
-		case VK_FORMAT_R32G32_SFLOAT:
-		case VK_FORMAT_R32G32_SINT:
-		case VK_FORMAT_R32G32_UINT:
-		case VK_FORMAT_R16G16B16A16_UNORM:
-		case VK_FORMAT_R16G16B16A16_SNORM:
-		case VK_FORMAT_R16G16_SFLOAT:
-		case VK_FORMAT_R16G16_UNORM:
-		case VK_FORMAT_R16G16_SNORM:
-		case VK_FORMAT_R16G16_SINT:
-		case VK_FORMAT_R16G16_UINT:
-		case VK_FORMAT_R16_SFLOAT:
-		case VK_FORMAT_R16_UNORM:
-		case VK_FORMAT_R16_SNORM:
-		case VK_FORMAT_R16_SINT:
-		case VK_FORMAT_R16_UINT:
-		case VK_FORMAT_R8G8_UNORM:
-		case VK_FORMAT_R8G8_SNORM:
-		case VK_FORMAT_R8G8_SINT:
-		case VK_FORMAT_R8G8_UINT:
-		case VK_FORMAT_R8_UNORM:
-		case VK_FORMAT_R8_SNORM:
-		case VK_FORMAT_R8_SINT:
-		case VK_FORMAT_R8_UINT:
-			return true;
-
-		default:
-			return false;
-	}
-}
-
 VkImageViewType getImageViewType (const VkImageType imageType)
 {
 	switch (imageType)
@@ -1723,9 +1688,8 @@
 		// Image stores are always required, in either access mode.
 		requireFeaturesForSSBOAccess(m_context, m_stage);
 
-		// Some storage image formats require additional capability.
-		if (isStorageImageExtendedFormat(m_resource.getImage().format))
-			requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
+		// Some storage image formats may not be supported
+		requireStorageImageSupport(vki, physDevice, m_resource.getImage().format);
 
 		m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
 			vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
@@ -2468,9 +2432,8 @@
 		// Image stores are always required, in either access mode.
 		requireFeaturesForSSBOAccess(m_context, m_stage);
 
-		// Some storage image formats require additional capability.
-		if (isStorageImageExtendedFormat(m_inResource.getImage().format))
-			requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
+		// Some storage image formats may not be supported
+		requireStorageImageSupport(vki, physDevice, m_inResource.getImage().format);
 
 		// Image resources
 		{
@@ -4625,8 +4588,6 @@
 	, m_allocator			(context.getDefaultAllocator())
 	, m_progCollection		(context.getBinaryCollection())
 	, m_pipelineCacheData	(pipelineCacheData)
-	, m_deviceExtensions	(context.getDeviceExtensions())
-	, m_usedApiVersion		(context.getUsedApiVersion())
 {
 }
 
@@ -4639,8 +4600,6 @@
 	, m_allocator			(allocator)
 	, m_progCollection		(context.getBinaryCollection())
 	, m_pipelineCacheData	(pipelineCacheData)
-	, m_deviceExtensions	(context.getDeviceExtensions())
-	, m_usedApiVersion		(context.getUsedApiVersion())
 {
 }
 
@@ -4650,7 +4609,6 @@
 									vk::VkPhysicalDevice			physicalDevice,
 									vk::VkDevice					device,
 									vk::Allocator&					allocator,
-									const std::vector<std::string>&	deviceExtensions,
 									vk::BinaryCollection&			programCollection,
 									PipelineCacheData&				pipelineCacheData)
 	: m_context				(context)
@@ -4661,8 +4619,6 @@
 	, m_allocator			(allocator)
 	, m_progCollection		(programCollection)
 	, m_pipelineCacheData	(pipelineCacheData)
-	, m_deviceExtensions	(deviceExtensions)
-	, m_usedApiVersion		(context.getUsedApiVersion())
 {
 }
 
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
index 7b9db4d..66422b4 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.hpp
@@ -144,7 +144,6 @@
 															 vk::VkPhysicalDevice				physicalDevice,
 															 vk::VkDevice						device,
 															 vk::Allocator&						allocator,
-															 const std::vector<std::string>&	deviceExtensions,
 															 vk::BinaryCollection&				programCollection,
 															 PipelineCacheData&					pipelineCacheData);
 
@@ -155,8 +154,6 @@
 	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; }
 
 	bool isDeviceFunctionalitySupported(const std::string& extension) const
 	{
@@ -172,8 +169,6 @@
 	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&);
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationMultiQueueTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationMultiQueueTests.cpp
index 60b04f7..c149a35 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationMultiQueueTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationMultiQueueTests.cpp
@@ -114,6 +114,9 @@
 		const VkPhysicalDevice						physicalDevice			= context.getPhysicalDevice();
 		const std::vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
 
+		if (timelineSemaphore)
+			context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+
 		for (deUint32 queuePropertiesNdx = 0; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx)
 		{
 			addQueueIndex(queuePropertiesNdx,
@@ -157,9 +160,6 @@
 				&context.getDeviceFeatures()									//const VkPhysicalDeviceFeatures*	pEnabledFeatures;
 			};
 
-			if (timelineSemaphore && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
-				TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
-
 			m_logicalDevice	= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instance, physicalDevice, &deviceInfo);
 			m_deviceDriver	= MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), context.getInstance(), *m_logicalDevice));
 			m_allocator		= MovePtr<Allocator>(new SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
@@ -586,9 +586,9 @@
 		for (deUint32 opIdx = 0; opIdx < m_ops.size(); opIdx++)
 		{
 			const VkPipelineStageFlags				stageBits[]				= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
-			const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo		=
+			const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo		=
 			{
-				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 				DE_NULL,												// const void*		pNext;
 				opIdx == 0 ? 0u : 1u,									// deUint32			waitSemaphoreValueCount
 				opIdx == 0 ? DE_NULL : &timelineValues[opIdx - 1],		// const deUint64*	pWaitSemaphoreValues
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationSingleQueueTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationSingleQueueTests.cpp
index 64d5920..f21b98c 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationSingleQueueTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperationSingleQueueTests.cpp
@@ -353,7 +353,7 @@
 		std::vector<VkCommandBuffer>							cmdBuffers;
 		const VkPipelineStageFlags								stageBits[]				= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
 		std::vector<deUint64>									timelineValues;
-		std::vector<VkTimelineSemaphoreSubmitInfoKHR>			timelineSubmitInfos;
+		std::vector<VkTimelineSemaphoreSubmitInfo>				timelineSubmitInfos;
 		std::vector<VkSubmitInfo>								submitInfos;
 
 		for (deUint32 opNdx = 0; opNdx < m_ops.size(); opNdx++)
@@ -371,9 +371,9 @@
 
 		for (deUint32 opNdx = 0; opNdx < m_ops.size(); opNdx++)
 		{
-			const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+			const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 			{
-				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 				DE_NULL,												// const void*		pNext;
 				opNdx == 0 ? 0u : 1u,									// deUint32			waitSemaphoreValueCount
 				opNdx == 0 ? DE_NULL : &timelineValues[opNdx - 1],		// const deUint64*	pWaitSemaphoreValues
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSignalOrderTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSignalOrderTests.cpp
index 57f1797..0d95a19 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSignalOrderTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSignalOrderTests.cpp
@@ -84,43 +84,34 @@
 {
 	VkSemaphoreSignalInfoKHR	ssi	=
 	{
-		VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR,// VkStructureType				sType;
+		VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,	// VkStructureType				sType;
 		DE_NULL,									// const void*					pNext;
 		semaphore,									// VkSemaphore					semaphore;
 		timelineValue,								// deUint64						value;
 	};
 
-	VK_CHECK(vk.signalSemaphoreKHR(device, &ssi));
+	VK_CHECK(vk.signalSemaphore(device, &ssi));
 }
 
-Move<VkDevice> createDevice (const deUint32							apiVersion,
-							 const VkPhysicalDeviceFeatures&		deviceFeatures,
-							 const PlatformInterface&				vkp,
-							 VkInstance								instance,
-							 const vk::InstanceInterface&			vki,
-							 VkPhysicalDevice						physicalDevice,
-							 VkSemaphoreTypeKHR						semaphoreType,
-							 VkExternalSemaphoreHandleTypeFlagBits	semaphoreHandleType)
+Move<VkDevice> createDevice (const Context& context)
 {
 	const float									priority				= 0.0f;
-	const std::vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
+	const std::vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
 	std::vector<deUint32>						queueFamilyIndices		(queueFamilyProperties.size(), 0xFFFFFFFFu);
 	std::vector<const char*>					extensions;
 
-	if (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR)
+	if (context.isDeviceFunctionalitySupported("VK_KHR_timeline_semaphore"))
 		extensions.push_back("VK_KHR_timeline_semaphore");
 
-	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_external_semaphore"))
+	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_external_semaphore"))
 		extensions.push_back("VK_KHR_external_semaphore");
-	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory"))
+	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_external_memory"))
 		extensions.push_back("VK_KHR_external_memory");
 
-	if (semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT ||
-		semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
+	if (context.isDeviceFunctionalitySupported("VK_KHR_external_semaphore_fd"))
 		extensions.push_back("VK_KHR_external_semaphore_fd");
 
-	if (semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
-		semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
+	if (context.isDeviceFunctionalitySupported("VK_KHR_external_semaphore_win32"))
 		extensions.push_back("VK_KHR_external_semaphore_win32");
 
 	try
@@ -147,7 +138,7 @@
 		{
 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
 			DE_NULL,
-			deviceFeatures,
+			context.getDeviceFeatures(),
 		};
 		const VkDeviceCreateInfo				createInfo				=
 		{
@@ -166,7 +157,7 @@
 			0u
 		};
 
-		return createDevice(vkp, instance, vki, physicalDevice, &createInfo);
+		return createDevice(context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &createInfo);
 	}
 	catch (const vk::Error& error)
 	{
@@ -177,6 +168,43 @@
 	}
 }
 
+// Class to wrap a singleton instance and device
+class SingletonDevice
+{
+	SingletonDevice	(const Context& context)
+		: m_logicalDevice	(createDevice(context))
+	{
+	}
+
+public:
+
+	static const Unique<vk::VkDevice>& getDevice(const Context& context)
+	{
+		if (!m_singletonDevice)
+			m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
+
+		DE_ASSERT(m_singletonDevice);
+		return m_singletonDevice->m_logicalDevice;
+	}
+
+	static void destroy()
+	{
+		m_singletonDevice.clear();
+	}
+
+private:
+	const Unique<vk::VkDevice>					m_logicalDevice;
+
+	static SharedPtr<SingletonDevice>	m_singletonDevice;
+};
+SharedPtr<SingletonDevice>		SingletonDevice::m_singletonDevice;
+
+static void cleanupGroup ()
+{
+	// Destroy singleton object
+	SingletonDevice::destroy();
+}
+
 class SimpleAllocation : public Allocation
 {
 public:
@@ -546,7 +574,7 @@
 											  const SharedPtr<OperationSupport>			readOpSupport,
 											  const ResourceDescription&				resourceDesc,
 											  VkExternalMemoryHandleTypeFlagBits		memoryHandleType,
-											  VkSemaphoreTypeKHR						semaphoreType,
+											  VkSemaphoreType							semaphoreType,
 											  VkExternalSemaphoreHandleTypeFlagBits		semaphoreHandleType,
 											  PipelineCacheData&						pipelineCacheData)
 		: TestInstance			(context)
@@ -603,14 +631,7 @@
 		// We're using 2 devices to make sure we have 2 queues even on
 		// implementations that only have a single queue.
 		const VkDevice&										deviceA						= m_context.getDevice();
-		const Unique<VkDevice>								deviceB						(createDevice(m_context.getUsedApiVersion(),
-																									  m_context.getDeviceFeatures(),
-																									  m_context.getPlatformInterface(),
-																									  m_context.getInstance(),
-																									  m_context.getInstanceInterface(),
-																									  m_context.getPhysicalDevice(),
-																									  m_semaphoreType,
-																									  m_semaphoreHandleType));
+		const Unique<VkDevice>&								deviceB						(SingletonDevice::getDevice(m_context));
 		const DeviceInterface&								vkA							= m_context.getDeviceInterface();
 		const DeviceDriver									vkB							(m_context.getPlatformInterface(), m_context.getInstance(), *deviceB);
 		UniquePtr<SimpleAllocator>							allocatorA					(new SimpleAllocator(vkA, deviceA, vk::getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(),
@@ -821,9 +842,9 @@
 
 			if (m_semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR)
 			{
-				const VkSemaphoreWaitInfoKHR		waitInfo	=
+				const VkSemaphoreWaitInfo		waitInfo	=
 				{
-					VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR,// VkStructureType			sType;
+					VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,	// VkStructureType			sType;
 					DE_NULL,								// const void*				pNext;
 					0u,										// VkSemaphoreWaitFlagsKHR	flags;
 					1u,										// deUint32					semaphoreCount;
@@ -834,7 +855,7 @@
 				// Unblock the whole lot.
 				hostSignal(vkA, deviceA, semaphoreHandlesA.front(), 1);
 
-				VK_CHECK(vkB.waitSemaphoresKHR(*deviceB, &waitInfo, ~0ull));
+				VK_CHECK(vkB.waitSemaphores(*deviceB, &waitInfo, ~0ull));
 			}
 			else
 			{
@@ -991,7 +1012,7 @@
 	SharedPtr<OperationSupport>					m_readOpSupport;
 	const ResourceDescription&					m_resourceDesc;
 	VkExternalMemoryHandleTypeFlagBits			m_memoryHandleType;
-	VkSemaphoreTypeKHR							m_semaphoreType;
+	VkSemaphoreType								m_semaphoreType;
 	VkExternalSemaphoreHandleTypeFlagBits		m_semaphoreHandleType;
 	PipelineCacheData&							m_pipelineCacheData;
 	de::Random									m_rng;
@@ -1006,7 +1027,7 @@
 										  OperationName							readOp,
 										  const ResourceDescription&			resourceDesc,
 										  VkExternalMemoryHandleTypeFlagBits	memoryHandleType,
-										  VkSemaphoreTypeKHR					semaphoreType,
+										  VkSemaphoreType						semaphoreType,
 										  VkExternalSemaphoreHandleTypeFlagBits	semaphoreHandleType,
 										  PipelineCacheData&					pipelineCacheData)
 		: TestCase				(testCtx, name.c_str(), "")
@@ -1020,6 +1041,23 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		if (m_semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR &&
+			!context.getTimelineSemaphoreFeatures().timelineSemaphore)
+			TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
+
+		if ((m_semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT ||
+			 m_semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) &&
+			 !context.isDeviceFunctionalitySupported("VK_KHR_external_semaphore_fd"))
+			TCU_THROW(NotSupportedError, "VK_KHR_external_semaphore_fd not supported");
+
+		if ((m_semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
+			 m_semaphoreHandleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) &&
+			!context.isDeviceFunctionalitySupported("VK_KHR_external_semaphore_win32"))
+			TCU_THROW(NotSupportedError, "VK_KHR_external_semaphore_win32 not supported");
+	}
+
 	TestInstance* createInstance (Context& context) const
 	{
 		return new QueueSubmitSignalOrderSharedTestInstance(context,
@@ -1043,7 +1081,7 @@
 	SharedPtr<OperationSupport>				m_readOpSupport;
 	const ResourceDescription&				m_resourceDesc;
 	VkExternalMemoryHandleTypeFlagBits		m_memoryHandleType;
-	VkSemaphoreTypeKHR						m_semaphoreType;
+	VkSemaphoreType							m_semaphoreType;
 	VkExternalSemaphoreHandleTypeFlagBits	m_semaphoreHandleType;
 	PipelineCacheData&						m_pipelineCacheData;
 };
@@ -1051,7 +1089,7 @@
 class QueueSubmitSignalOrderSharedTests : public tcu::TestCaseGroup
 {
 public:
-	QueueSubmitSignalOrderSharedTests (tcu::TestContext& testCtx, VkSemaphoreTypeKHR semaphoreType, const char *name)
+	QueueSubmitSignalOrderSharedTests (tcu::TestContext& testCtx, VkSemaphoreType semaphoreType, const char *name)
 		: tcu::TestCaseGroup	(testCtx, name, "Signal ordering of semaphores")
 		, m_semaphoreType		(semaphoreType)
 	{
@@ -1175,8 +1213,13 @@
 		}
 	}
 
+	void deinit (void)
+	{
+		cleanupGroup();
+	}
+
 private:
-	VkSemaphoreTypeKHR	m_semaphoreType;
+	VkSemaphoreType		m_semaphoreType;
 	// synchronization.op tests share pipeline cache data to speed up test
 	// execution.
 	PipelineCacheData	m_pipelineCacheData;
@@ -1210,21 +1253,14 @@
 										const SharedPtr<OperationSupport>			writeOpSupport,
 										const SharedPtr<OperationSupport>			readOpSupport,
 										const ResourceDescription&					resourceDesc,
-										VkSemaphoreTypeKHR							semaphoreType,
+										VkSemaphoreType								semaphoreType,
 										PipelineCacheData&							pipelineCacheData)
 		: TestInstance			(context)
 		, m_writeOpSupport		(writeOpSupport)
 		, m_readOpSupport		(readOpSupport)
 		, m_resourceDesc		(resourceDesc)
 		, m_semaphoreType		(semaphoreType)
-		, m_device				(createDevice(context.getUsedApiVersion(),
-											  context.getDeviceFeatures(),
-											  context.getPlatformInterface(),
-											  context.getInstance(),
-											  context.getInstanceInterface(),
-											  context.getPhysicalDevice(),
-											  semaphoreType,
-											  (VkExternalSemaphoreHandleTypeFlagBits)0))
+		, m_device				(SingletonDevice::getDevice(context))
 		, m_deviceInterface		(context.getPlatformInterface(), context.getInstance(), *m_device)
 		, m_allocator			(new SimpleAllocator(m_deviceInterface,
 													 *m_device,
@@ -1455,9 +1491,9 @@
 
 			if (m_semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR)
 			{
-				const VkSemaphoreWaitInfoKHR		waitInfo	=
+				const VkSemaphoreWaitInfo		waitInfo	=
 				{
-					VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR,// VkStructureType			sType;
+					VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,	// VkStructureType			sType;
 					DE_NULL,								// const void*				pNext;
 					0u,										// VkSemaphoreWaitFlagsKHR	flags;
 					1u,										// deUint32					semaphoreCount;
@@ -1468,7 +1504,7 @@
 				// Unblock the whole lot.
 				hostSignal(vk, device, semaphoreHandlesA.front(), 1);
 
-				VK_CHECK(vk.waitSemaphoresKHR(device, &waitInfo, ~0ull));
+				VK_CHECK(vk.waitSemaphores(device, &waitInfo, ~0ull));
 			}
 			else
 			{
@@ -1533,8 +1569,8 @@
 	SharedPtr<OperationSupport>					m_writeOpSupport;
 	SharedPtr<OperationSupport>					m_readOpSupport;
 	const ResourceDescription&					m_resourceDesc;
-	VkSemaphoreTypeKHR							m_semaphoreType;
-	Unique<VkDevice>							m_device;
+	VkSemaphoreType								m_semaphoreType;
+	const Unique<VkDevice>&						m_device;
 	const DeviceDriver							m_deviceInterface;
 	UniquePtr<SimpleAllocator>					m_allocator;
 	UniquePtr<OperationContext>					m_operationContext;
@@ -1553,7 +1589,7 @@
 									OperationName				writeOp,
 									OperationName				readOp,
 									const ResourceDescription&	resourceDesc,
-									VkSemaphoreTypeKHR			semaphoreType,
+									VkSemaphoreType				semaphoreType,
 									PipelineCacheData&			pipelineCacheData)
 		: TestCase				(testCtx, name.c_str(), "")
 		, m_writeOpSupport		(makeOperationSupport(writeOp, resourceDesc).release())
@@ -1564,6 +1600,13 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		if (m_semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR &&
+			!context.getTimelineSemaphoreFeatures().timelineSemaphore)
+			TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
+	}
+
 	TestInstance* createInstance (Context& context) const
 	{
 		return new QueueSubmitSignalOrderTestInstance(context,
@@ -1584,14 +1627,14 @@
 	SharedPtr<OperationSupport>				m_writeOpSupport;
 	SharedPtr<OperationSupport>				m_readOpSupport;
 	const ResourceDescription&				m_resourceDesc;
-	VkSemaphoreTypeKHR						m_semaphoreType;
+	VkSemaphoreType							m_semaphoreType;
 	PipelineCacheData&						m_pipelineCacheData;
 };
 
 class QueueSubmitSignalOrderTests : public tcu::TestCaseGroup
 {
 public:
-	QueueSubmitSignalOrderTests (tcu::TestContext& testCtx, VkSemaphoreTypeKHR semaphoreType, const char *name)
+	QueueSubmitSignalOrderTests (tcu::TestContext& testCtx, VkSemaphoreType semaphoreType, const char *name)
 		: tcu::TestCaseGroup	(testCtx, name, "Signal ordering of semaphores")
 		, m_semaphoreType		(semaphoreType)
 	{
@@ -1686,8 +1729,13 @@
 		}
 	}
 
+	void deinit (void)
+	{
+		cleanupGroup();
+	}
+
 private:
-	VkSemaphoreTypeKHR		m_semaphoreType;
+	VkSemaphoreType		m_semaphoreType;
 	// synchronization.op tests share pipeline cache data to speed up test
 	// execution.
 	PipelineCacheData	m_pipelineCacheData;
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSmokeTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSmokeTests.cpp
index 24abcec..a3a36b5 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSmokeTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationSmokeTests.cpp
@@ -973,11 +973,11 @@
 	}
 }
 
-static void initTimelineSemaphoreSubmitInfo (VkTimelineSemaphoreSubmitInfoKHR* submitInfo, deUint32 submitInfoCount)
+static void initTimelineSemaphoreSubmitInfo (VkTimelineSemaphoreSubmitInfo* submitInfo, deUint32 submitInfoCount)
 {
 	for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
 	{
-		submitInfo[ndx].sType						= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
+		submitInfo[ndx].sType						= VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
 		submitInfo[ndx].pNext						= DE_NULL;
 		submitInfo[ndx].waitSemaphoreValueCount		= 0;
 		submitInfo[ndx].pWaitSemaphoreValues		= DE_NULL;
@@ -1090,19 +1090,19 @@
 	return TestStatus::pass("synchronization-fences passed");
 }
 
-tcu::TestStatus testSemaphores (Context& context, VkSemaphoreTypeKHR semaphoreType)
+tcu::TestStatus testSemaphores (Context& context, VkSemaphoreType semaphoreType)
 {
-	TestLog&							log						= context.getTestContext().getLog();
-	const PlatformInterface&			platformInterface		= context.getPlatformInterface();
-	const InstanceInterface&			instanceInterface		= context.getInstanceInterface();
-	const VkPhysicalDevice				physicalDevice			= context.getPhysicalDevice();
-	deUint32							queueFamilyIdx;
-	vk::Move<VkDevice>					device					= createTestDevice(platformInterface, context.getInstance(), instanceInterface, physicalDevice, context.getTestContext().getCommandLine().isValidationEnabled(), &queueFamilyIdx);
-	const DeviceDriver					deviceInterface			(platformInterface, context.getInstance(), *device);
-	SimpleAllocator						allocator				(deviceInterface,
-																 *device,
-																 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
-	const VkQueue						queue[2]				=
+	TestLog&					log					= context.getTestContext().getLog();
+	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
+	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
+	deUint32					queueFamilyIdx;
+	vk::Move<VkDevice>			device				= createTestDevice(platformInterface, context.getInstance(), instanceInterface, physicalDevice, context.getTestContext().getCommandLine().isValidationEnabled(), &queueFamilyIdx);
+	const DeviceDriver			deviceInterface		(platformInterface, context.getInstance(), *device);
+	SimpleAllocator				allocator			(deviceInterface,
+													 *device,
+													 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
+	const VkQueue				queue[2]			=
 	{
 		getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 0),
 		getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 1)
@@ -1112,7 +1112,7 @@
 	TestContext							testContext2			(deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
 	Unique<VkSemaphore>					semaphore				(createSemaphoreType(deviceInterface, *device, semaphoreType));
 	VkSubmitInfo						submitInfo[2];
-	VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo[2];
+	VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo[2];
 	const deUint64						timelineValue			= 1u;
 
 	void*						resultImage;
@@ -1161,12 +1161,12 @@
 	submitInfo[0].pSignalSemaphores					= &semaphore.get();
 	timelineSubmitInfo[0].pSignalSemaphoreValues	= &timelineValue;
 	timelineSubmitInfo[0].signalSemaphoreValueCount	= 1;
-	submitInfo[0].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR ? &timelineSubmitInfo[0] : DE_NULL);
+	submitInfo[0].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE ? &timelineSubmitInfo[0] : DE_NULL);
 	submitInfo[1].waitSemaphoreCount				= 1;
 	submitInfo[1].pWaitSemaphores					= &semaphore.get();
 	timelineSubmitInfo[1].pWaitSemaphoreValues		= &timelineValue;
 	timelineSubmitInfo[1].waitSemaphoreValueCount	= 1;
-	submitInfo[1].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR ? &timelineSubmitInfo[1] : DE_NULL);
+	submitInfo[1].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE ? &timelineSubmitInfo[1] : DE_NULL);
 	submitInfo[1].pWaitDstStageMask					= &waitDstStageMask;
 
 	VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
@@ -1224,91 +1224,6 @@
 	return testSemaphores(context, VK_SEMAPHORE_TYPE_TIMELINE_KHR);
 }
 
-tcu::TestStatus testEvents (Context& context)
-{
-	TestLog&					log					= context.getTestContext().getLog();
-	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
-	VkDevice					device				= context.getDevice();
-	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
-	Allocator&					allocator			= context.getDefaultAllocator();
-	VkQueue						queue				= context.getUniversalQueue();
-	VkResult					testStatus;
-	VkResult					eventStatus;
-	TestContext					testContext			(deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), allocator);
-	Unique<VkEvent>				event				(createEvent(deviceInterface, device));
-	VkSubmitInfo				submitInfo;
-	void*						resultImage;
-
-	const tcu::Vec4		vertices1[]			=
-	{
-		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
-		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
-		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
-	};
-
-	testContext.vertices = vertices1;
-	testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
-	testContext.renderDimension = tcu::IVec2(256, 256);
-	testContext.waitEvent = true;
-	testContext.event = event.get();
-	testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
-
-	createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
-	generateWork(testContext);
-
-	initSubmitInfo(&submitInfo, 1);
-	submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
-
-	// 6.3 An event is initially in the unsignaled state
-	eventStatus = deviceInterface.getEventStatus(device, event.get());
-	if (eventStatus != VK_EVENT_RESET)
-	{
-		log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage;
-		return tcu::TestStatus::fail("Event in incorrect status");
-	}
-
-	// The recorded command buffer should wait at the top of the graphics pipe for an event signaled by the host and so should not
-	// make forward progress as long as the event is not signaled
-	VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
-
-	testStatus  = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 10000000);
-	if (testStatus != VK_TIMEOUT)
-	{
-		log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set event from host." << TestLog::EndMessage;
-		return tcu::TestStatus::fail("failed to wait for event set from host");
-	}
-
-	// Should allow the recorded command buffer to finally make progress
-	VK_CHECK(deviceInterface.setEvent(device, event.get()));
-	eventStatus = deviceInterface.getEventStatus(device, event.get());
-	if (eventStatus != VK_EVENT_SET)
-	{
-		log << TestLog::Message << "testEvents failed to transition event to signaled state via setEvent call from host" << TestLog::EndMessage;
-		return tcu::TestStatus::fail("failed to signal event from host");
-	}
-
-	testStatus  = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, ~(0ull));
-	if (testStatus != VK_SUCCESS)
-	{
-		log << TestLog::Message << "testSynchronizationPrimitives failed to proceed after set event from host." << TestLog::EndMessage;
-		return tcu::TestStatus::fail("failed to proceed after event set from host");
-	}
-
-	invalidateAlloc(deviceInterface, device, *testContext.renderReadBuffer);
-	resultImage = testContext.renderReadBuffer->getHostPtr();
-
-	log << TestLog::Image(	"result",
-							"result",
-							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
-									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
-									testContext.renderDimension.x(),
-									testContext.renderDimension.y(),
-									1,
-									resultImage));
-
-	return tcu::TestStatus::pass("synchronization-events passed");
-}
-
 } // anonymous
 
 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx)
@@ -1318,7 +1233,6 @@
 	addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
 	addFunctionCaseWithPrograms(synchTests.get(), "binary_semaphores", "", buildShaders, testBinarySemaphores);
 	addFunctionCaseWithPrograms(synchTests.get(), "timeline_semaphores", "", buildShaders, testTimelineSemaphores);
-	addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
 
 	return synchTests.release();
 }
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTimelineSemaphoreTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTimelineSemaphoreTests.cpp
index cc2db0c..ab682b7 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTimelineSemaphoreTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTimelineSemaphoreTests.cpp
@@ -84,11 +84,11 @@
 deUint64 getMaxTimelineSemaphoreValueDifference(const InstanceInterface& vk,
 												const VkPhysicalDevice physicalDevice)
 {
-	VkPhysicalDeviceTimelineSemaphorePropertiesKHR	timelineSemaphoreProperties;
+	VkPhysicalDeviceTimelineSemaphoreProperties		timelineSemaphoreProperties;
 	VkPhysicalDeviceProperties2						properties;
 
 	deMemset(&timelineSemaphoreProperties, 0, sizeof(timelineSemaphoreProperties));
-	timelineSemaphoreProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR;
+	timelineSemaphoreProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;
 
 	deMemset(&properties, 0, sizeof(properties));
 	properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
@@ -106,9 +106,9 @@
 				   const VkSemaphore		semaphore,
 				   const deUint64			timelineValue)
 {
-	VkTimelineSemaphoreSubmitInfoKHR	tsi			=
+	VkTimelineSemaphoreSubmitInfo		tsi			=
 	{
-		VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType				sType;
+		VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType				sType;
 		DE_NULL,												// const void*					pNext;
 		0u,														// deUint32						waitSemaphoreValueCount
 		DE_NULL,												// const deUint64*				pWaitSemaphoreValues
@@ -152,13 +152,13 @@
 {
 	VkSemaphoreSignalInfoKHR	ssi	=
 	{
-		VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR,// VkStructureType				sType;
+		VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,	// VkStructureType				sType;
 		DE_NULL,									// const void*					pNext;
 		semaphore,									// VkSemaphore					semaphore;
 		timelineValue,								// deUint64						value;
 	};
 
-	VK_CHECK(vk.signalSemaphoreKHR(device, &ssi));
+	VK_CHECK(vk.signalSemaphore(device, &ssi));
 }
 
 class WaitTestInstance : public TestInstance
@@ -169,8 +169,6 @@
 		, m_waitAll				(waitAll)
 		, m_signalFromDevice	(signalFromDevice)
 	{
-		if (!context.getTimelineSemaphoreFeatures().timelineSemaphore)
-			TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
 	}
 
 	tcu::TestStatus iterate (void)
@@ -215,18 +213,18 @@
 		}
 
 		{
-			const VkSemaphoreWaitInfoKHR	waitInfo	=
+			const VkSemaphoreWaitInfo		waitInfo	=
 			{
-				VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR,									// VkStructureType			sType;
-				DE_NULL,																	// const void*				pNext;
-				m_waitAll ? 0u : (VkSemaphoreWaitFlagsKHR) VK_SEMAPHORE_WAIT_ANY_BIT_KHR,	// VkSemaphoreWaitFlagsKHR	flags;
-				(deUint32) semaphores.size(),												// deUint32					semaphoreCount;
-				&semaphores[0],																// const VkSemaphore*		pSemaphores;
-				&timelineValues[0],															// const deUint64*			pValues;
+				VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,									// VkStructureType			sType;
+				DE_NULL,																// const void*				pNext;
+				m_waitAll ? 0u : (VkSemaphoreWaitFlags) VK_SEMAPHORE_WAIT_ANY_BIT_KHR,	// VkSemaphoreWaitFlagsKHR	flags;
+				(deUint32) semaphores.size(),											// deUint32					semaphoreCount;
+				&semaphores[0],															// const VkSemaphore*		pSemaphores;
+				&timelineValues[0],														// const deUint64*			pValues;
 			};
 			VkResult						result;
 
-			result = vk.waitSemaphoresKHR(device, &waitInfo, 0ull);
+			result = vk.waitSemaphores(device, &waitInfo, 0ull);
 
 			if (result != VK_SUCCESS)
 				return tcu::TestStatus::fail("Wait failed");
@@ -263,6 +261,11 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+	}
+
 	TestInstance* createInstance (Context& context) const
 	{
 		return new WaitTestInstance(context, m_waitAll, m_signalFromDevice);
@@ -281,8 +284,6 @@
 	HostWaitBeforeSignalTestInstance (Context& context)
 		: TestInstance			(context)
 	{
-		if (!context.getTimelineSemaphoreFeatures().timelineSemaphore)
-			TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
 	}
 
 	tcu::TestStatus iterate (void)
@@ -300,9 +301,9 @@
 		for (deUint32 i = 0; i < 12; i++)
 		{
 			const deUint64							newTimelineValue	= (timelineValues.back() + rng.getInt(1, 10000));
-			const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+			const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 			{
-				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 				DE_NULL,												// const void*		pNext;
 				1u,														// deUint32			waitSemaphoreValueCount
 				&timelineValues.back(),									// const deUint64*	pWaitSemaphoreValues
@@ -340,7 +341,7 @@
 			};
 			VkResult						result;
 
-			result = vk.waitSemaphoresKHR(device, &waitInfo, 0ull);
+			result = vk.waitSemaphores(device, &waitInfo, 0ull);
 
 			if (result != VK_TIMEOUT)
 				return tcu::TestStatus::fail("Wait failed");
@@ -360,7 +361,7 @@
 			};
 			VkResult						result;
 
-			result = vk.waitSemaphoresKHR(device, &waitInfo, ~(0ull));
+			result = vk.waitSemaphores(device, &waitInfo, ~(0ull));
 
 			if (result != VK_SUCCESS)
 				return tcu::TestStatus::fail("Wait failed");
@@ -392,16 +393,21 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+	}
+
 	TestInstance* createInstance (Context& context) const
 	{
 		return new HostWaitBeforeSignalTestInstance(context);
 	}
 };
 
-class MonoticallyIncrementChecker : public de::Thread
+class MonotonicallyIncrementChecker : public de::Thread
 {
 public:
-	MonoticallyIncrementChecker						(const DeviceInterface& vkd, VkDevice device, VkSemaphore semaphore)
+	MonotonicallyIncrementChecker					(const DeviceInterface& vkd, VkDevice device, VkSemaphore semaphore)
 		: de::Thread()
 		, m_vkd(vkd)
 		, m_device(device)
@@ -410,7 +416,7 @@
 		, m_status(tcu::TestStatus::incomplete())
 	{}
 
-	virtual			~MonoticallyIncrementChecker	(void)	{}
+	virtual			~MonotonicallyIncrementChecker	(void)	{}
 
 	tcu::TestStatus	getStatus						() { return m_status; }
 	void			stop							() { m_running = false; }
@@ -422,17 +428,18 @@
 		{
 			deUint64 value;
 
-			VK_CHECK(m_vkd.getSemaphoreCounterValueKHR(m_device, m_semaphore, &value));
+			VK_CHECK(m_vkd.getSemaphoreCounterValue(m_device, m_semaphore, &value));
 
 			if (value < lastValue) {
-				m_status = tcu::TestStatus::fail("Value not monotically increasing");
+				m_status = tcu::TestStatus::fail("Value not monotonically increasing");
 				return;
 			}
 
 			lastValue = value;
+			deYield();
 		}
 
-		m_status = tcu::TestStatus::pass("Value monotically increasing");
+		m_status = tcu::TestStatus::pass("Value monotonically increasing");
 	}
 
 private:
@@ -462,7 +469,7 @@
 	const Unique<VkSemaphore>						semaphore					(createSemaphoreType(vk, device, VK_SEMAPHORE_TYPE_TIMELINE_KHR));
 	const Unique<VkFence>							fence						(createFence(vk, device));
 	tcu::TestLog&									log							= context.getTestContext().getLog();
-	MonoticallyIncrementChecker						checkerThread				(vk, device, *semaphore);
+	MonotonicallyIncrementChecker					checkerThread				(vk, device, *semaphore);
 	deUint64										iterations;
 	deUint64										timelineBackValue;
 	deUint64										timelineFrontValue;
@@ -497,7 +504,7 @@
 			deviceSignal(vk, device, queue, DE_NULL, *semaphore, ++timelineFrontValue);
 
 		deUint64 value;
-		VK_CHECK(vk.getSemaphoreCounterValueKHR(device, *semaphore, &value));
+		VK_CHECK(vk.getSemaphoreCounterValue(device, *semaphore, &value));
 
 		VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~(0ull)));
 		VK_CHECK(vk.resetFences(device, 1, &fence.get()));
@@ -523,9 +530,9 @@
 	const Unique<VkSemaphore>						semaphoreDefaultValue		(createSemaphoreType(vk, device, VK_SEMAPHORE_TYPE_TIMELINE_KHR));
 	const Unique<VkSemaphore>						semaphoreInitialValue		(createSemaphoreType(vk, device, VK_SEMAPHORE_TYPE_TIMELINE_KHR, 0, nonZeroValue));
 	deUint64										initialValue;
-	VkSemaphoreWaitInfoKHR							waitInfo					=
+	VkSemaphoreWaitInfo								waitInfo					=
 	{
-		VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR,	// VkStructureType			sType;
+		VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,		// VkStructureType			sType;
 		DE_NULL,									// const void*				pNext;
 		0u,											// VkSemaphoreWaitFlagsKHR	flags;
 		1u,											// deUint32					semaphoreCount;
@@ -537,21 +544,21 @@
 
 	waitInfo.pSemaphores = &semaphoreDefaultValue.get();
 	initialValue = 0;
-	result = vk.waitSemaphoresKHR(device, &waitInfo, 0ull);
+	result = vk.waitSemaphores(device, &waitInfo, 0ull);
 	if (result != VK_SUCCESS)
 		return tcu::TestStatus::fail("Wait zero initial value failed");
 
-	VK_CHECK(vk.getSemaphoreCounterValueKHR(device, *semaphoreDefaultValue, &value));
+	VK_CHECK(vk.getSemaphoreCounterValue(device, *semaphoreDefaultValue, &value));
 	if (value != initialValue)
 		return tcu::TestStatus::fail("Invalid zero initial value");
 
 	waitInfo.pSemaphores = &semaphoreInitialValue.get();
 	initialValue = nonZeroValue;
-	result = vk.waitSemaphoresKHR(device, &waitInfo, 0ull);
+	result = vk.waitSemaphores(device, &waitInfo, 0ull);
 	if (result != VK_SUCCESS)
 		return tcu::TestStatus::fail("Wait non zero initial value failed");
 
-	VK_CHECK(vk.getSemaphoreCounterValueKHR(device, *semaphoreInitialValue, &value));
+	VK_CHECK(vk.getSemaphoreCounterValue(device, *semaphoreInitialValue, &value));
 	if (value != nonZeroValue)
 		return tcu::TestStatus::fail("Invalid non zero initial value");
 
@@ -562,11 +569,11 @@
 
 		waitInfo.pSemaphores = &semaphoreMaxValue.get();
 		initialValue = nonZeroMaxValue;
-		result = vk.waitSemaphoresKHR(device, &waitInfo, 0ull);
+		result = vk.waitSemaphores(device, &waitInfo, 0ull);
 		if (result != VK_SUCCESS)
 			return tcu::TestStatus::fail("Wait max value failed");
 
-		VK_CHECK(vk.getSemaphoreCounterValueKHR(device, *semaphoreMaxValue, &value));
+		VK_CHECK(vk.getSemaphoreCounterValue(device, *semaphoreMaxValue, &value));
 		if (value != nonZeroMaxValue)
 			return tcu::TestStatus::fail("Invalid max value initial value");
 	}
@@ -659,7 +666,7 @@
 				};
 				VkResult						result;
 
-				result = m_vkd.waitSemaphoresKHR(m_device, &waitInfo, ~(deUint64)0u);
+				result = m_vkd.waitSemaphores(m_device, &waitInfo, ~(deUint64)0u);
 				if (result != VK_SUCCESS)
 					return;
 			}
@@ -679,7 +686,7 @@
 				};
 				VkResult						result;
 
-				result = m_vkd.signalSemaphoreKHR(m_device, &signalInfo);
+				result = m_vkd.signalSemaphore(m_device, &signalInfo);
 				if (result != VK_SUCCESS)
 					return;
 			}
@@ -745,9 +752,6 @@
 	{
 		de::Random	rng		(1234);
 
-		if (!context.getTimelineSemaphoreFeatures().timelineSemaphore)
-			TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
-
 		// Create a dozen couple of operations and their associated
 		// resource.
 		for (deUint32 i = 0; i < 12; i++)
@@ -769,7 +773,7 @@
 		HostCopyThread										hostCopyThread			(vk, device, *semaphore, m_iterations);
 		std::vector<SharedPtr<Move<VkCommandBuffer> > >		ptrCmdBuffers;
 		std::vector<VkCommandBuffer>						cmdBuffers;
-		std::vector<VkTimelineSemaphoreSubmitInfoKHR>		timelineSubmitInfos;
+		std::vector<VkTimelineSemaphoreSubmitInfo>			timelineSubmitInfos;
 		std::vector<VkSubmitInfo>							submitInfos;
 
 		hostCopyThread.start();
@@ -800,9 +804,9 @@
 		{
 			// Write operation
 			{
-				const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+				const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 				{
-					VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,			// VkStructureType	sType;
+					VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,				// VkStructureType	sType;
 					DE_NULL,														// const void*		pNext;
 					iterIdx == 0 ? 0u : 1u,											// deUint32			waitSemaphoreValueCount
 					iterIdx == 0 ? DE_NULL : &m_iterations[iterIdx - 1]->cpuValue,	// const deUint64*	pWaitSemaphoreValues
@@ -858,9 +862,9 @@
 
 			// Read operation
 			{
-				const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+				const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 				{
-					VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType	sType;
+					VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
 					DE_NULL,												// const void*		pNext;
 					1u,														// deUint32			waitSemaphoreValueCount
 					&m_iterations[iterIdx]->writeValue,						// const deUint64*	pWaitSemaphoreValues
@@ -930,6 +934,11 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+	}
+
 	void initPrograms (SourceCollections& programCollection) const
 	{
 		m_writeOp->initPrograms(programCollection);
@@ -1095,7 +1104,7 @@
 	return infos;
 }
 
-Move<VkDevice> createDevice(Context& context)
+Move<VkDevice> createDevice(const Context& context)
 {
 	const std::vector<VkQueueFamilyProperties>		queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
 	std::vector<VkDeviceQueueCreateInfo>			queueCreateInfos		= getQueueCreateInfo(queueFamilyProperties);
@@ -1129,13 +1138,48 @@
 		queueCreateInfo.pQueuePriorities = &(*queuePriorities.back().get())[0];
 	}
 
-	if (!context.getTimelineSemaphoreFeatures().timelineSemaphore)
-		TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
-
 	return createDevice(context.getPlatformInterface(), context.getInstance(),
 						context.getInstanceInterface(), context.getPhysicalDevice(), &deviceInfo);
 }
 
+
+// Class to wrap a singleton instance and device
+class SingletonDevice
+{
+	SingletonDevice	(const Context& context)
+		: m_logicalDevice	(createDevice(context))
+	{
+	}
+
+public:
+
+	static const Unique<vk::VkDevice>& getDevice(const Context& context)
+	{
+		if (!m_singletonDevice)
+			m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
+
+		DE_ASSERT(m_singletonDevice);
+		return m_singletonDevice->m_logicalDevice;
+	}
+
+	static void destroy()
+	{
+		m_singletonDevice.clear();
+	}
+
+private:
+	const Unique<vk::VkDevice>					m_logicalDevice;
+
+	static SharedPtr<SingletonDevice>	m_singletonDevice;
+};
+SharedPtr<SingletonDevice>		SingletonDevice::m_singletonDevice;
+
+static void cleanupGroup ()
+{
+	// Destroy singleton object
+	SingletonDevice::destroy();
+}
+
 // Create a chain of operations with data copied across queues & host
 // and submit the operations out of order to verify that the queues
 // are properly unblocked as the work progresses.
@@ -1149,7 +1193,7 @@
 								  PipelineCacheData&					pipelineCacheData)
 		: TestInstance		(context)
 		, m_resourceDesc	(resourceDesc)
-		, m_device			(createDevice(context))
+		, m_device			(SingletonDevice::getDevice(context))
 		, m_deviceDriver	(MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), context.getInstance(), *m_device)))
 		, m_allocator		(new SimpleAllocator(*m_deviceDriver, *m_device,
 												 getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
@@ -1265,9 +1309,9 @@
 			// exercise the wait-before-submit behavior.
 			deUint32 iterIdx = (deUint32)(m_iterations.size() - 2 - _iterIdx);
 
-			const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+			const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 			{
-				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,								// VkStructureType	sType;
+				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,									// VkStructureType	sType;
 				DE_NULL,																			// const void*		pNext;
 				1u,																					// deUint32			waitSemaphoreValueCount
 				iterIdx == 0 ? &m_hostTimelineValue : &m_iterations[iterIdx - 1]->timelineValue,	// const deUint64*	pWaitSemaphoreValues
@@ -1327,9 +1371,9 @@
 		// Submit the last read operation in order.
 		{
 			const deUint32							iterIdx				= (deUint32) (m_iterations.size() - 1);
-			const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+			const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 			{
-				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,				// VkStructureType	sType;
+				VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,					// VkStructureType	sType;
 				DE_NULL,															// const void*		pNext;
 				1u,																	// deUint32			waitSemaphoreValueCount
 				&m_iterations[iterIdx - 1]->timelineValue,							// const deUint64*	pWaitSemaphoreValues
@@ -1375,7 +1419,7 @@
 
 protected:
 	const ResourceDescription						m_resourceDesc;
-	Move<VkDevice>									m_device;
+	const Unique<VkDevice>&							m_device;
 	MovePtr<DeviceDriver>							m_deviceDriver;
 	MovePtr<Allocator>								m_allocator;
 	OperationContext								m_opContext;
@@ -1402,6 +1446,11 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+	}
+
 	void initPrograms (SourceCollections& programCollection) const
 	{
 		m_writeOp->initPrograms(programCollection);
@@ -1518,6 +1567,11 @@
 		}
 	}
 
+	void deinit (void)
+	{
+		cleanupGroup();
+	}
+
 private:
 	// synchronization.op tests share pipeline cache data to speed up test
 	// execution.
@@ -1541,7 +1595,7 @@
 						PipelineCacheData&					pipelineCacheData)
 		: TestInstance		(context)
 		, m_resourceDesc	(resourceDesc)
-		, m_device			(createDevice(context))
+		, m_device			(SingletonDevice::getDevice(context))
 		, m_deviceDriver	(MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), context.getInstance(), *m_device)))
 		, m_allocator		(new SimpleAllocator(*m_deviceDriver, *m_device,
 												 getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
@@ -1680,9 +1734,9 @@
 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
 		};
-		const VkTimelineSemaphoreSubmitInfoKHR	timelineSubmitInfo	=
+		const VkTimelineSemaphoreSubmitInfo		timelineSubmitInfo	=
 		{
-			VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,			// VkStructureType	sType;
+			VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,				// VkStructureType	sType;
 			DE_NULL,														// const void*		pNext;
 			waitValuesCount,												// deUint32			waitSemaphoreValueCount
 			waitValues,														// const deUint64*	pWaitSemaphoreValues
@@ -1818,7 +1872,7 @@
 
 protected:
 	ResourceDescription								m_resourceDesc;
-	Move<VkDevice>									m_device;
+	const Unique<VkDevice>&							m_device;
 	MovePtr<DeviceDriver>							m_deviceDriver;
 	MovePtr<Allocator>								m_allocator;
 	OperationContext								m_opContext;
@@ -1848,6 +1902,11 @@
 	{
 	}
 
+	virtual void checkSupport(Context& context) const
+	{
+		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
+	}
+
 	void initPrograms (SourceCollections& programCollection) const
 	{
 		m_writeOp->initPrograms(programCollection);
@@ -1964,6 +2023,11 @@
 		}
 	}
 
+	void deinit (void)
+	{
+		cleanupGroup();
+	}
+
 private:
 	// synchronization.op tests share pipeline cache data to speed up test
 	// execution.
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.cpp
index a3f594f..f703185 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.cpp
@@ -395,9 +395,13 @@
 
 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
+}
 
-	if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats)
-		throw tcu::NotSupportedError("Storage image extended formats not supported");
+void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
+{
+	const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
+	if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
+		throw tcu::NotSupportedError("Storage image format not supported");
 }
 
 std::string getResourceName (const ResourceDescription& resource)
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.hpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.hpp
index fb95a8d..df0bf02 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.hpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationUtil.hpp
@@ -176,7 +176,6 @@
 	FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			= 1u << 3,
 	FEATURE_FRAGMENT_STORES_AND_ATOMICS					= 1u << 4,
 	FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	= 1u << 5,
-	FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS		= 1u << 6,
 };
 typedef deUint32 FeatureFlags;
 
@@ -229,6 +228,7 @@
 vk::Move<vk::VkPipeline>		makeComputePipeline							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkShaderModule shaderModule, const vk::VkSpecializationInfo* specInfo, PipelineCacheData& pipelineCacheData);
 void							beginRenderPassWithRasterizationDisabled	(const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer);
 void							requireFeatures								(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags);
+void							requireStorageImageSupport					(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const vk::VkFormat fmt);
 std::string						getResourceName								(const ResourceDescription& resource);
 bool							isIndirectBuffer							(const ResourceType type);
 
diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationWin32KeyedMutexTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationWin32KeyedMutexTests.cpp
index 22eb3a8..2271d48 100644
--- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationWin32KeyedMutexTests.cpp
+++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationWin32KeyedMutexTests.cpp
@@ -283,7 +283,7 @@
 		(requiresDedicated) ? &dedicatedInfo : DE_NULL,
 		externalType,
 		handle.getWin32Handle(),
-		NULL
+		(vk::pt::Win32LPCWSTR)NULL
 	};
 
 	deUint32 handleCompatibleMemoryTypeBits = ~0u;
@@ -1644,8 +1644,7 @@
 		const vk::Unique<vk::VkCommandBuffer>	commandBufferWrite	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 		const vk::Unique<vk::VkCommandBuffer>	commandBufferRead	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 		vk::SimpleAllocator						allocator			(m_vkd, *m_device, vk::getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice));
-		const std::vector<std::string>			deviceExtensions;
-		OperationContext						operationContext	(m_context, m_vki, m_vkd, m_physicalDevice, *m_device, allocator, deviceExtensions, m_context.getBinaryCollection(), m_pipelineCacheData);
+		OperationContext						operationContext	(m_context, m_vki, m_vkd, m_physicalDevice, *m_device, allocator, m_context.getBinaryCollection(), m_pipelineCacheData);
 
 		if (!checkQueueFlags(m_queueFamilies[m_queueNdx].queueFlags, vk::VK_QUEUE_GRAPHICS_BIT))
 			TCU_THROW(NotSupportedError, "Operation not supported by the source queue");
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureCompressedFormatTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureCompressedFormatTests.cpp
index d0724c8..28fb0cd 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureCompressedFormatTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureCompressedFormatTests.cpp
@@ -91,7 +91,7 @@
 	, m_texture				(TestTexture2DSp(new pipeline::TestTexture2D(m_compressedFormat, testParameters.width, testParameters.height)))
 	, m_renderer			(context, testParameters.sampleCount, testParameters.width, testParameters.height)
 {
-	m_renderer.add2DTexture(m_texture, testParameters.backingMode);
+	m_renderer.add2DTexture(m_texture, testParameters.aspectMask, testParameters.backingMode);
 }
 
 tcu::TestStatus Compressed2DTestInstance::iterate (void)
@@ -262,6 +262,7 @@
 		testParameters.height		= sizes[sizeNdx].height;
 		testParameters.minFilter	= tcu::Sampler::NEAREST;
 		testParameters.magFilter	= tcu::Sampler::NEAREST;
+		testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 		testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 		compressedTextureTests->addChild(new TextureTestCase<Compressed2DTestInstance>(testCtx, (nameBase + "_2d_" + sizes[sizeNdx].name + backingModes[backingNdx].name).c_str(), (formatStr + ", TEXTURETYPE_2D").c_str(), testParameters));
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
index aa31693..c9582b0 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
@@ -113,7 +113,7 @@
 		}
 
 		renderer.setViewport(0.0f, 0.0f, static_cast<float>(ANISOTROPY_TEST_RESOLUTION), static_cast<float>(ANISOTROPY_TEST_RESOLUTION));
-		renderer.add2DTexture(texture);
+		renderer.add2DTexture(texture, VK_IMAGE_ASPECT_COLOR_BIT);
 
 		{
 			Surface			renderedFrame			(ANISOTROPY_TEST_RESOLUTION, ANISOTROPY_TEST_RESOLUTION);
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringTests.cpp
index 7c24146..e0d0c38 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringTests.cpp
@@ -115,14 +115,24 @@
 {
 	const bool						mipmaps		= m_testParameters.mipmaps;
 	const int						numLevels	= mipmaps ? deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1 : 1;
-	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
-	const tcu::Vec4					cBias		= fmtInfo.valueMin;
-	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
+	const tcu::TextureFormat		texFormat	= vk::mapVkFormat(m_testParameters.format);
+	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFormat);
+	tcu::Vec4						cBias, cScale;
+	if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		const tcu::TextureFormat		texFormatStencil	= vk::mapVkFormat(VK_FORMAT_S8_UINT);
+		const tcu::TextureFormatInfo	fmtInfoStencil		= tcu::getTextureFormatInfo(texFormatStencil);
+		cBias												= fmtInfoStencil.valueMin;
+		cScale												= fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
+	}
+	else
+	{
+		cBias												= fmtInfo.valueMin;
+		cScale												= fmtInfo.valueMax - fmtInfo.valueMin;
+	}
 
-	if ((testParameters.wrapS == Sampler::MIRRORED_ONCE ||
-		testParameters.wrapT == Sampler::MIRRORED_ONCE) &&
-		!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
-		TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+	if (testParameters.wrapS == Sampler::MIRRORED_ONCE || testParameters.wrapT == Sampler::MIRRORED_ONCE)
+		context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
 
 	// Create 2 textures.
 	m_textures.reserve(2);
@@ -138,7 +148,10 @@
 		const tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
 		const tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
 
-		tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
+		if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+			tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), gMin, gMax);
+		else
+			tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
 	}
 
 	// Fill second with grid texture.
@@ -149,13 +162,16 @@
 		const deUint32	colorA	= 0xff000000 | rgb;
 		const deUint32	colorB	= 0xff000000 | ~rgb;
 
-		tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+		if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+			tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+		else
+			tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
 	}
 
 	// Upload.
 	for (vector<TestTexture2DSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
 	{
-		m_renderer.add2DTexture(*i);
+		m_renderer.add2DTexture(*i, testParameters.aspectMask);
 	}
 
 	// Compute cases.
@@ -209,8 +225,13 @@
 	// Setup params for reference.
 
 	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter, !m_testParameters.unnormal);
-	refParams.samplerType	= getSamplerType(texFmt);
-	refParams.lodMode		= LODMODE_EXACT;
+	if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		refParams.sampler.depthStencilMode = tcu::Sampler::MODE_STENCIL;
+		refParams.samplerType = SAMPLERTYPE_UINT;
+	}
+	else
+		refParams.samplerType = getSamplerType(texFmt);
 	refParams.colorBias		= fmtInfo.lookupBias;
 	refParams.colorScale	= fmtInfo.lookupScale;
 	refParams.unnormal		= m_testParameters.unnormal;
@@ -314,14 +335,24 @@
 	, m_caseNdx				(0)
 {
 	const int						numLevels	= deLog2Floor32(m_testParameters.size)+1;
-	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
-	const tcu::Vec4					cBias		= fmtInfo.valueMin;
-	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
+	const tcu::TextureFormat		texFormat	= vk::mapVkFormat(m_testParameters.format);
+	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFormat);
+	tcu::Vec4						cBias, cScale;
+	if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		const tcu::TextureFormat		texFormatStencil	= vk::mapVkFormat(VK_FORMAT_S8_UINT);
+		const tcu::TextureFormatInfo	fmtInfoStencil		= tcu::getTextureFormatInfo(texFormatStencil);
+		cBias												= fmtInfoStencil.valueMin;
+		cScale												= fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
+	}
+	else
+	{
+		cBias												= fmtInfo.valueMin;
+		cScale												= fmtInfo.valueMax - fmtInfo.valueMin;
+	}
 
-	if ((testParameters.wrapS == Sampler::MIRRORED_ONCE ||
-		testParameters.wrapT == Sampler::MIRRORED_ONCE) &&
-		!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
-		TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+	if (testParameters.wrapS == Sampler::MIRRORED_ONCE || testParameters.wrapT == Sampler::MIRRORED_ONCE)
+		context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
 
 	m_textures.reserve(2);
 	for (int ndx = 0; ndx < 2; ndx++)
@@ -342,7 +373,10 @@
 	{
 		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
 		{
-			tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
+			if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+				tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, face), tcu::Sampler::MODE_STENCIL), gradients[face][0] * cScale + cBias, gradients[face][1] * cScale + cBias);
+			else
+				tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, face), gradients[face][0] * cScale + cBias, gradients[face][1] * cScale + cBias);
 		}
 	}
 
@@ -357,13 +391,18 @@
 			const deUint32	colorB	= 0xff000000 | ~rgb;
 
 			tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+
+			if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+				tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, face), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+			else
+				tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
 		}
 	}
 
 	// Upload.
 	for (vector<TestTextureCubeSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
 	{
-		m_renderer.addCubeTexture(*i);
+		m_renderer.addCubeTexture(*i, testParameters.aspectMask);
 	}
 
 	// Compute cases
@@ -421,8 +460,14 @@
 
 	// Params for reference computation.
 	refParams.sampler					= util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_testParameters.minFilter, m_testParameters.magFilter);
+	if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		refParams.sampler.depthStencilMode	= tcu::Sampler::MODE_STENCIL;
+		refParams.samplerType				= SAMPLERTYPE_UINT;
+	}
+	else
+		refParams.samplerType				= getSamplerType(texFmt);
 	refParams.sampler.seamlessCubeMap	= true;
-	refParams.samplerType				= getSamplerType(texFmt);
 	refParams.lodMode					= LODMODE_EXACT;
 	refParams.colorBias					= fmtInfo.lookupBias;
 	refParams.colorScale				= fmtInfo.lookupScale;
@@ -535,15 +580,25 @@
 	, m_renderer			(context, testParameters.sampleCount, TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT)
 	, m_caseNdx				(0)
 {
-	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
-	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
-	const tcu::Vec4					cBias		= fmtInfo.valueMin;
 	const int						numLevels	= deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height)) + 1;
+	const tcu::TextureFormat		texFormat	= vk::mapVkFormat(m_testParameters.format);
+	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFormat);
+	tcu::Vec4						cBias, cScale;
+	if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		const tcu::TextureFormat		texFormatStencil	= vk::mapVkFormat(VK_FORMAT_S8_UINT);
+		const tcu::TextureFormatInfo	fmtInfoStencil		= tcu::getTextureFormatInfo(texFormatStencil);
+		cBias												= fmtInfoStencil.valueMin;
+		cScale												= fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
+	}
+	else
+	{
+		cBias												= fmtInfo.valueMin;
+		cScale												= fmtInfo.valueMax - fmtInfo.valueMin;
+	}
 
-	if ((testParameters.wrapS == Sampler::MIRRORED_ONCE ||
-		testParameters.wrapT == Sampler::MIRRORED_ONCE) &&
-		!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
-		TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+	if (testParameters.wrapS == Sampler::MIRRORED_ONCE || testParameters.wrapT == Sampler::MIRRORED_ONCE)
+		context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
 
 	// Create textures.
 	m_textures.reserve(2);
@@ -563,13 +618,14 @@
 	{
 		for (int layerNdx = 0; layerNdx < m_testParameters.numLayers; layerNdx++)
 		{
-			const tcu::PixelBufferAccess levelBuf = m_textures[0]->getLevel(levelNdx, layerNdx);
-
 			const tcu::IVec4	swz		= levelSwz[layerNdx%DE_LENGTH_OF_ARRAY(levelSwz)];
 			const tcu::Vec4		gMin	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
 			const tcu::Vec4		gMax	= tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
 
-			tcu::fillWithComponentGradients(levelBuf, gMin, gMax);
+			if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+				tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, layerNdx), tcu::Sampler::MODE_STENCIL), gMin, gMax);
+			else
+				tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, layerNdx), gMin, gMax);
 		}
 	}
 
@@ -578,21 +634,22 @@
 	{
 		for (int layerNdx = 0; layerNdx < m_testParameters.numLayers; layerNdx++)
 		{
-			const tcu::PixelBufferAccess levelBuf = m_textures[1]->getLevel(levelNdx, layerNdx);
-
 			const deUint32	step	= 0x00ffffff / (numLevels*m_testParameters.numLayers - 1);
 			const deUint32	rgb		= step * (levelNdx + layerNdx*numLevels);
 			const deUint32	colorA	= 0xff000000 | rgb;
 			const deUint32	colorB	= 0xff000000 | ~rgb;
 
-			tcu::fillWithGrid(levelBuf, 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+			if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+				tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, layerNdx), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+			else
+				tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, layerNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
 		}
 	}
 
 	// Upload.
 	for (vector<TestTexture2DArraySp>::const_iterator i = m_textures.begin(); i != m_textures.end(); i++)
 	{
-		m_renderer.add2DArrayTexture(*i);
+		m_renderer.add2DArrayTexture(*i, testParameters.aspectMask);
 	}
 
 	// Test cases
@@ -622,7 +679,13 @@
 	// Params for reference computation.
 
 	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
-	refParams.samplerType	= getSamplerType(texFmt);
+	if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		refParams.sampler.depthStencilMode	= tcu::Sampler::MODE_STENCIL;
+		refParams.samplerType				= SAMPLERTYPE_UINT;
+	}
+	else
+		refParams.samplerType				= getSamplerType(texFmt);
 	refParams.lodMode		= LODMODE_EXACT;
 	refParams.colorBias		= fmtInfo.lookupBias;
 	refParams.colorScale	= fmtInfo.lookupScale;
@@ -738,16 +801,25 @@
 	, m_renderer			(context, testParameters.sampleCount, TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT)
 	, m_caseNdx				(0)
 {
-	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
-	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
-	const tcu::Vec4					cBias		= fmtInfo.valueMin;
 	const int						numLevels	= deLog2Floor32(de::max(de::max(m_testParameters.width, m_testParameters.height), m_testParameters.depth)) + 1;
+	const tcu::TextureFormat		texFormat	= vk::mapVkFormat(m_testParameters.format);
+	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFormat);
+	tcu::Vec4						cBias, cScale;
+	if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		const tcu::TextureFormat		texFormatStencil	= vk::mapVkFormat(VK_FORMAT_S8_UINT);
+		const tcu::TextureFormatInfo	fmtInfoStencil		= tcu::getTextureFormatInfo(texFormatStencil);
+		cBias												= fmtInfoStencil.valueMin;
+		cScale												= fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
+	}
+	else
+	{
+		cBias												= fmtInfo.valueMin;
+		cScale												= fmtInfo.valueMax - fmtInfo.valueMin;
+	}
 
-	if ((testParameters.wrapS == Sampler::MIRRORED_ONCE ||
-		testParameters.wrapT == Sampler::MIRRORED_ONCE ||
-		testParameters.wrapR == Sampler::MIRRORED_ONCE) &&
-		!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
-		TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+	if (testParameters.wrapS == Sampler::MIRRORED_ONCE || testParameters.wrapT == Sampler::MIRRORED_ONCE || testParameters.wrapR == Sampler::MIRRORED_ONCE)
+		context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
 
 	// Create textures.
 	m_textures.reserve(2);
@@ -760,7 +832,11 @@
 		const tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
 		const tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
 
-		tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
+		if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+			tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), gMin, gMax);
+		else
+			tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
+
 	}
 
 	// Fill second with grid texture.
@@ -771,13 +847,17 @@
 		const deUint32	colorA	= 0xff000000 | rgb;
 		const deUint32	colorB	= 0xff000000 | ~rgb;
 
-		tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+		if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+			tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+		else
+			tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
+
 	}
 
 	// Upload.
 	for (vector<TestTexture3DSp>::const_iterator i = m_textures.begin(); i != m_textures.end(); i++)
 	{
-		m_renderer.add3DTexture(*i);
+		m_renderer.add3DTexture(*i, testParameters.aspectMask);
 	}
 
 	// Test cases
@@ -806,7 +886,13 @@
 
 	// Params for reference computation.
 	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.wrapR, m_testParameters.minFilter, m_testParameters.magFilter);
-	refParams.samplerType	= getSamplerType(texFmt);
+	if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+	{
+		refParams.sampler.depthStencilMode	= tcu::Sampler::MODE_STENCIL;
+		refParams.samplerType				= SAMPLERTYPE_UINT;
+	}
+	else
+		refParams.samplerType				= getSamplerType(texFmt);
 	refParams.lodMode		= LODMODE_EXACT;
 	refParams.colorBias		= fmtInfo.lookupBias;
 	refParams.colorScale	= fmtInfo.lookupScale;
@@ -982,20 +1068,28 @@
 
 	static const struct
 	{
-		const char* const	name;
-		const VkFormat		format;
+		const char* const			name;
+		const VkFormat				format;
+		const VkImageAspectFlags	aspectMask;
+		const Program				program2D;
+		const Program				programCube;
+		const Program				program2DArray;
+		const Program				program3D;
 	} filterableFormatsByType[] =
 	{
-		{ "r16g16b16a16_sfloat",	VK_FORMAT_R16G16B16A16_SFLOAT		},
-		{ "b10g11r11_ufloat",		VK_FORMAT_B10G11R11_UFLOAT_PACK32	},
-		{ "e5b9g9r9_ufloat",		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32	},
-		{ "r8g8b8a8_unorm",			VK_FORMAT_R8G8B8A8_UNORM			},
-		{ "r8g8b8a8_snorm",			VK_FORMAT_R8G8B8A8_SNORM			},
-		{ "r5g6b5_unorm",			VK_FORMAT_R5G6B5_UNORM_PACK16		},
-		{ "r4g4b4a4_unorm",			VK_FORMAT_R4G4B4A4_UNORM_PACK16		},
-		{ "r5g5b5a1_unorm",			VK_FORMAT_R5G5B5A1_UNORM_PACK16		},
-		{ "a8b8g8r8_srgb",			VK_FORMAT_A8B8G8R8_SRGB_PACK32		},
-		{ "a1r5g5b5_unorm",			VK_FORMAT_A1R5G5B5_UNORM_PACK16		}
+		{ "r16g16b16a16_sfloat",			VK_FORMAT_R16G16B16A16_SFLOAT,		VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "b10g11r11_ufloat",				VK_FORMAT_B10G11R11_UFLOAT_PACK32,	VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "e5b9g9r9_ufloat",				VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,	VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "r8g8b8a8_unorm",					VK_FORMAT_R8G8B8A8_UNORM,			VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "r8g8b8a8_snorm",					VK_FORMAT_R8G8B8A8_SNORM,			VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "r5g6b5_unorm",					VK_FORMAT_R5G6B5_UNORM_PACK16,		VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "r4g4b4a4_unorm",					VK_FORMAT_R4G4B4A4_UNORM_PACK16,	VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "r5g5b5a1_unorm",					VK_FORMAT_R5G5B5A1_UNORM_PACK16,	VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "a8b8g8r8_srgb",					VK_FORMAT_A8B8G8R8_SRGB_PACK32,		VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "a1r5g5b5_unorm",					VK_FORMAT_A1R5G5B5_UNORM_PACK16,	VK_IMAGE_ASPECT_COLOR_BIT,		PROGRAM_2D_FLOAT,	PROGRAM_CUBE_FLOAT,	PROGRAM_2D_ARRAY_FLOAT,	PROGRAM_3D_FLOAT	},
+		{ "s8_uint",						VK_FORMAT_S8_UINT,					VK_IMAGE_ASPECT_STENCIL_BIT,	PROGRAM_2D_UINT,	PROGRAM_CUBE_UINT,	PROGRAM_2D_ARRAY_UINT,	PROGRAM_3D_UINT		},
+		{ "d24_unorm_s8_uint_stencil",		VK_FORMAT_D24_UNORM_S8_UINT,		VK_IMAGE_ASPECT_STENCIL_BIT,	PROGRAM_2D_UINT,	PROGRAM_CUBE_UINT,	PROGRAM_2D_ARRAY_UINT,	PROGRAM_3D_UINT		},
+		{ "d32_sfloat_s8_uint_stencil",		VK_FORMAT_D32_SFLOAT_S8_UINT,		VK_IMAGE_ASPECT_STENCIL_BIT,	PROGRAM_2D_UINT,	PROGRAM_CUBE_UINT,	PROGRAM_2D_ARRAY_UINT,	PROGRAM_3D_UINT		}
 	};
 
 	// 2D texture filtering.
@@ -1029,7 +1123,8 @@
 				testParameters.width		= 64;
 				testParameters.height		= 64;
 
-				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
+				testParameters.aspectMask	= filterableFormatsByType[fmtNdx].aspectMask;
+				testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
 
 				// Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
 				if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
@@ -1063,6 +1158,7 @@
 				testParameters.width		= sizes2D[sizeNdx].width;
 				testParameters.height		= sizes2D[sizeNdx].height;
 
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1098,6 +1194,7 @@
 						testParameters.width		= 63;
 						testParameters.height		= 57;
 
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 						testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 						wrapSGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1147,7 +1244,8 @@
 				testParameters.width		= 64;
 				testParameters.height		= 64;
 
-				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
+				testParameters.aspectMask	= filterableFormatsByType[fmtNdx].aspectMask;
+				testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
 
 				// Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
 				if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
@@ -1181,6 +1279,7 @@
 				testParameters.width		= sizes2D[sizeNdx].width;
 				testParameters.height		= sizes2D[sizeNdx].height;
 
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1225,7 +1324,8 @@
 				testParameters.onlySampleFaceInterior	= false;
 				testParameters.size						= 64;
 
-				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
+				testParameters.aspectMask				= filterableFormatsByType[fmtNdx].aspectMask;
+				testParameters.programs.push_back(filterableFormatsByType[fmtNdx].programCube);
 
 				// Some tests have to be skipped due to the restrictions of the verifiers.
 				if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
@@ -1257,6 +1357,7 @@
 				testParameters.onlySampleFaceInterior	= false;
 				testParameters.size						= sizesCube[sizeNdx].size;
 
+				testParameters.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 				filterGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1291,6 +1392,7 @@
 						testParameters.onlySampleFaceInterior	= false;
 						testParameters.size						= 63;
 
+						testParameters.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
 						testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 						wrapSGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1317,6 +1419,7 @@
 			testParameters.onlySampleFaceInterior	= true;
 			testParameters.size						= 63;
 
+			testParameters.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
 			testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 			onlyFaceInteriorGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1363,7 +1466,8 @@
 				testParameters.height		= 128;
 				testParameters.numLayers	= 8;
 
-				testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
+				testParameters.aspectMask	= filterableFormatsByType[fmtNdx].aspectMask;
+				testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2DArray);
 
 				// Some tests have to be skipped due to the restrictions of the verifiers.
 				if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
@@ -1397,6 +1501,7 @@
 				testParameters.height		= sizes2DArray[sizeNdx].height;
 				testParameters.numLayers	= sizes2DArray[sizeNdx].numLayers;
 
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
 
 				filterGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1431,6 +1536,7 @@
 						testParameters.height		= 107;
 						testParameters.numLayers	= 7;
 
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 						testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
 
 						wrapSGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1483,7 +1589,8 @@
 				testParameters.height		= 64;
 				testParameters.depth		= 64;
 
-				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
+				testParameters.aspectMask	= filterableFormatsByType[fmtNdx].aspectMask;
+				testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program3D);
 
 				// Some tests have to be skipped due to the restrictions of the verifiers.
 				if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
@@ -1518,6 +1625,7 @@
 				testParameters.height		= sizes3D[sizeNdx].height;
 				testParameters.depth		= sizes3D[sizeNdx].depth;
 
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 				filterGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -1557,6 +1665,7 @@
 							testParameters.height		= 57;
 							testParameters.depth		= 67;
 
+							testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 							testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 							wrapTGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureMipmapTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureMipmapTests.cpp
index 511e730..bf637c8 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureMipmapTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureMipmapTests.cpp
@@ -188,7 +188,7 @@
 	}
 
 	// Upload texture data.
-	m_renderer.add2DTexture(m_texture);
+	m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
 }
 
 Texture2DMipmapTestInstance::~Texture2DMipmapTestInstance (void)
@@ -461,7 +461,7 @@
 		}
 	}
 
-	m_renderer.addCubeTexture(m_texture);
+	m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
 }
 
 TextureCubeMipmapTestInstance::~TextureCubeMipmapTestInstance (void)
@@ -691,7 +691,7 @@
 		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
 	}
 
-	m_renderer.add3DTexture(m_texture);
+	m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
 }
 
 Texture3DMipmapTestInstance::~Texture3DMipmapTestInstance (void)
@@ -971,7 +971,7 @@
 		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
 	}
 
-	m_renderer.add2DTexture(m_texture);
+	m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
 }
 
 Texture2DLodControlTestInstance::~Texture2DLodControlTestInstance (void)
@@ -1236,7 +1236,7 @@
 		}
 	}
 
-	m_renderer.addCubeTexture(m_texture);
+	m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
 }
 
 TextureCubeLodControlTestInstance::~TextureCubeLodControlTestInstance (void)
@@ -1489,7 +1489,7 @@
 		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
 	}
 
-	m_renderer.add3DTexture(m_texture);
+	m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
 }
 
 Texture3DLodControlTestInstance::~Texture3DLodControlTestInstance (void)
@@ -1815,9 +1815,10 @@
 						testParameters.minFilter	= minFilterModes[minFilter].mode;
 						testParameters.wrapS		= wrapModes[wrapMode].mode;
 						testParameters.wrapT		= wrapModes[wrapMode].mode;
-						testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA)
+						testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM;
 						testParameters.width		= tex2DSizes[size].width;
 						testParameters.height		= tex2DSizes[size].height;
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 						testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 						std::ostringstream name;
@@ -1846,9 +1847,10 @@
 				testParameters.magFilter	= minFilterModes[minFilter].mode;
 				testParameters.wrapS		= Sampler::REPEAT_GL;
 				testParameters.wrapT		= Sampler::REPEAT_GL;
-				testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA)
+				testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM;
 				testParameters.width		= tex2DSizes[0].width;
 				testParameters.height		= tex2DSizes[0].height;
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT_BIAS);
 
 				std::ostringstream name;
@@ -1865,6 +1867,7 @@
 			{
 				Texture2DMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter	= minFilterModes[minFilter].mode;
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				minLodGroup2D->addChild(new TextureTestCase<Texture2DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1874,7 +1877,8 @@
 			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
 			{
 				Texture2DMipmapTestCaseParameters	testParameters;
-				testParameters.minFilter = minFilterModes[minFilter].mode;
+				testParameters.minFilter	= minFilterModes[minFilter].mode;
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				maxLodGroup2D->addChild(new TextureTestCase<Texture2DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1886,8 +1890,9 @@
 			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
 			{
 				Texture2DMipmapTestCaseParameters	testParameters;
-				testParameters.minFilter = minFilterModes[minFilter].mode;
-				testParameters.minFilterName = minFilterModes[minFilter].name;
+				testParameters.minFilter		= minFilterModes[minFilter].mode;
+				testParameters.minFilterName	= minFilterModes[minFilter].name;
+				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				baseLevelGroup2D->addChild(new TextureTestCase<Texture2DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1897,8 +1902,9 @@
 			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
 			{
 				Texture2DMipmapTestCaseParameters	testParameters;
-				testParameters.minFilter = minFilterModes[minFilter].mode;
-				testParameters.minFilterName = minFilterModes[minFilter].name;
+				testParameters.minFilter		= minFilterModes[minFilter].mode;
+				testParameters.minFilterName	= minFilterModes[minFilter].name;
+				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
 
 				maxLevelGroup2D->addChild(new TextureTestCase<Texture2DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1943,6 +1949,7 @@
 						testParameters.wrapT			= wrapModes[wrapMode].mode;
 						testParameters.format			= VK_FORMAT_R8G8B8A8_UNORM;
 						testParameters.size				= cubeMapSize;
+						testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 
 						if (testParameters.coordType == COORDTYPE_BASIC_BIAS)
 							testParameters.programs.push_back(PROGRAM_CUBE_FLOAT_BIAS);
@@ -1969,6 +1976,7 @@
 			{
 				TextureCubeMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter	= minFilterModes[minFilter].mode;
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 				minLodGroupCube->addChild(new TextureTestCase<TextureCubeMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1979,6 +1987,7 @@
 			{
 				TextureCubeMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter	= minFilterModes[minFilter].mode;
+				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 				maxLodGroupCube->addChild(new TextureTestCase<TextureCubeMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -1990,8 +1999,9 @@
 			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
 			{
 				TextureCubeMipmapTestCaseParameters	testParameters;
-				testParameters.minFilter = minFilterModes[minFilter].mode;
-				testParameters.minFilterName = minFilterModes[minFilter].name;
+				testParameters.minFilter		= minFilterModes[minFilter].mode;
+				testParameters.minFilterName	= minFilterModes[minFilter].name;
+				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 				baseLevelGroupCube->addChild(new TextureTestCase<TextureCubeBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2001,8 +2011,9 @@
 			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
 			{
 				TextureCubeMipmapTestCaseParameters	testParameters;
-				testParameters.minFilter = minFilterModes[minFilter].mode;
-				testParameters.minFilterName = minFilterModes[minFilter].name;
+				testParameters.minFilter		= minFilterModes[minFilter].mode;
+				testParameters.minFilterName	= minFilterModes[minFilter].name;
+				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
 
 				maxLevelGroupCube->addChild(new TextureTestCase<TextureCubeMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2047,6 +2058,7 @@
 					testParameters.wrapS			= wrapModes[wrapMode].mode;
 					testParameters.wrapT			= wrapModes[wrapMode].mode;
 					testParameters.format			= VK_FORMAT_R8G8B8A8_UNORM;
+					testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 					testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 					for (int size = 0; size < sizeEnd; size++)
@@ -2084,7 +2096,7 @@
 				testParameters.width				= tex3DSizes[0].width;
 				testParameters.height				= tex3DSizes[0].height;
 				testParameters.depth				= tex3DSizes[0].depth;
-
+				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT_BIAS);
 
 				biasGroup3D->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2098,6 +2110,7 @@
 			{
 				Texture3DMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter			= minFilterModes[minFilter].mode;
+				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 				minLodGroup3D->addChild(new TextureTestCase<Texture3DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2108,6 +2121,7 @@
 			{
 				Texture3DMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter			= minFilterModes[minFilter].mode;
+				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 				maxLodGroup3D->addChild(new TextureTestCase<Texture3DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2121,6 +2135,7 @@
 				Texture3DMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter			= minFilterModes[minFilter].mode;
 				testParameters.minFilterName		= minFilterModes[minFilter].name;
+				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 				baseLevelGroup3D->addChild(new TextureTestCase<Texture3DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
@@ -2132,6 +2147,7 @@
 				Texture3DMipmapTestCaseParameters	testParameters;
 				testParameters.minFilter			= minFilterModes[minFilter].mode;
 				testParameters.minFilterName		= minFilterModes[minFilter].name;
+				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
 				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
 
 				maxLevelGroup3D->addChild(new TextureTestCase<Texture3DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureShadowTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureShadowTests.cpp
index 0a1fe4b..764167c 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureShadowTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureShadowTests.cpp
@@ -264,7 +264,7 @@
 	// Upload.
 	for (std::vector<TestTexture2DSp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
 	{
-		m_renderer.add2DTexture(*i, m_testParameters.backingMode);
+		m_renderer.add2DTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
 	}
 
 	// Compute cases.
@@ -486,7 +486,7 @@
 	// Upload.
 	for (vector<TestTextureCubeSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
 	{
-		m_renderer.addCubeTexture(*i, m_testParameters.backingMode);
+		m_renderer.addCubeTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
 	}
 
 	// Compute cases
@@ -691,7 +691,7 @@
 	// Upload.
 	for (std::vector<TestTexture2DArraySp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
 	{
-		m_renderer.add2DArrayTexture(*i, m_testParameters.backingMode);
+		m_renderer.add2DArrayTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
 	}
 
 	// Compute cases.
@@ -898,7 +898,7 @@
 						testParameters.wrapT		= Sampler::REPEAT_GL;
 						testParameters.width		= 32;
 						testParameters.height		= 64;
-
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_DEPTH_BIT;
 						testParameters.programs.push_back(PROGRAM_2D_SHADOW);
 
 						filterGroup->addChild(new TextureTestCase<Texture2DShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
@@ -937,6 +937,7 @@
 						testParameters.wrapS		= Sampler::REPEAT_GL;
 						testParameters.wrapT		= Sampler::REPEAT_GL;
 						testParameters.size			= 32;
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_DEPTH_BIT;
 
 						testParameters.programs.push_back(PROGRAM_CUBE_SHADOW);
 
@@ -978,6 +979,7 @@
 						testParameters.width		= 32;
 						testParameters.height		= 64;
 						testParameters.numLayers	= 8;
+						testParameters.aspectMask	= VK_IMAGE_ASPECT_DEPTH_BIT;
 
 						testParameters.programs.push_back(PROGRAM_2D_ARRAY_SHADOW);
 
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureSwizzleTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureSwizzleTests.cpp
index 488fdb8..e437873 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureSwizzleTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureSwizzleTests.cpp
@@ -124,7 +124,7 @@
 								: new pipeline::TestTexture2D(m_format, testParameters.width, testParameters.height)))
 	, m_renderer			(context, testParameters.sampleCount, testParameters.width, testParameters.height, testParameters.componentMapping)
 {
-	m_renderer.add2DTexture(m_texture, testParameters.backingMode);
+	m_renderer.add2DTexture(m_texture, testParameters.aspectMask, testParameters.backingMode);
 }
 
 tcu::TestStatus Swizzle2DTestInstance::iterate (void)
@@ -479,6 +479,7 @@
 		testParameters.height			= sizes2D[sizeNdx].height;
 		testParameters.minFilter		= tcu::Sampler::NEAREST;
 		testParameters.magFilter		= tcu::Sampler::NEAREST;
+		testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 		testParameters.programs.push_back(formats2D[formatNdx].program);
 
 		groupCompMap->addChild(new SwizzleTestCase<Swizzle2DTestInstance>(testCtx, caseName.c_str(), caseDesc.c_str(), testParameters));
@@ -507,6 +508,7 @@
 		testParameters.height			= sizes2D[sizeNdx].height;
 		testParameters.minFilter		= tcu::Sampler::NEAREST;
 		testParameters.magFilter		= tcu::Sampler::NEAREST;
+		testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
 		testParameters.programs.push_back(formats2D[formatNdx].program);
 
 		groupTexCoord->addChild(new SwizzleTestCase<Swizzle2DTestInstance>(testCtx, caseName.c_str(), caseDesc.c_str(), testParameters));
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp
index 27487df..edefe46 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp
@@ -308,16 +308,25 @@
 {
 }
 
-TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type, const TextureBinding::ImageBackingMode backingMode, const VkComponentMapping componentMapping)
+TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type, const vk::VkImageAspectFlags aspectMask, const TextureBinding::ImageBackingMode backingMode, const VkComponentMapping componentMapping)
 	: m_context				(context)
 	, m_type				(type)
 	, m_backingMode			(backingMode)
 	, m_textureData			(textureData)
+	, m_aspectMask			(aspectMask)
 	, m_componentMapping	(componentMapping)
 {
 	updateTextureData(m_textureData, m_type);
 }
 
+VkImageAspectFlags	guessAspectMask(const vk::VkFormat format)
+{
+	tcu::TextureFormat			textureFormat		= mapVkFormat(format);
+	const bool					isShadowTexture		= tcu::hasDepthComponent(textureFormat.order);
+	const bool					isStencilTexture	= tcu::hasStencilComponent(textureFormat.order);
+	return isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : isStencilTexture ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
+}
+
 void TextureBinding::updateTextureData (const TestTextureSp& textureData, const TextureBinding::Type textureType)
 {
 	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
@@ -434,8 +443,7 @@
 	const VkDevice								vkDevice				= m_context.getDevice();
 	const vk::VkImageViewType					imageViewType			= textureTypeToImageViewType(m_type);
 	const vk::VkFormat							format					= m_textureData->isCompressed() ? mapCompressedTextureFormat(m_textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(m_textureData->getTextureFormat());
-	const bool									isShadowTexture			= tcu::hasDepthComponent(m_textureData->getTextureFormat().order);
-	const VkImageAspectFlags					aspectMask				= isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
+	const VkImageAspectFlags					aspectMask				= ( m_aspectMask != VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM ) ? m_aspectMask : guessAspectMask(format);
 	const deUint32								layerCount				= m_textureData->getArraySize();
 	const vk::VkImageViewCreateInfo				viewParams				=
 	{
@@ -842,24 +850,24 @@
 	submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
 }
 
-void TextureRenderer::add2DTexture (const TestTexture2DSp& texture, TextureBinding::ImageBackingMode backingMode)
+void TextureRenderer::add2DTexture (const TestTexture2DSp& texture, const vk::VkImageAspectFlags& aspectMask, TextureBinding::ImageBackingMode backingMode)
 {
-	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D, backingMode, m_componentMapping)));
+	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D, aspectMask, backingMode, m_componentMapping)));
 }
 
-void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture, TextureBinding::ImageBackingMode backingMode)
+void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture, const vk::VkImageAspectFlags& aspectMask, TextureBinding::ImageBackingMode backingMode)
 {
-	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP, backingMode, m_componentMapping)));
+	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP, aspectMask, backingMode, m_componentMapping)));
 }
 
-void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture, TextureBinding::ImageBackingMode backingMode)
+void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture, const vk::VkImageAspectFlags& aspectMask, TextureBinding::ImageBackingMode backingMode)
 {
-	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY, backingMode, m_componentMapping)));
+	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY, aspectMask, backingMode, m_componentMapping)));
 }
 
-void TextureRenderer::add3DTexture (const TestTexture3DSp& texture, TextureBinding::ImageBackingMode backingMode)
+void TextureRenderer::add3DTexture (const TestTexture3DSp& texture, const vk::VkImageAspectFlags& aspectMask, TextureBinding::ImageBackingMode backingMode)
 {
-	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D, backingMode, m_componentMapping)));
+	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D, aspectMask, backingMode, m_componentMapping)));
 }
 
 const pipeline::TestTexture2D& TextureRenderer::get2DTexture (int textureIndex) const
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.hpp b/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.hpp
index 3fcfa79..840773c 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.hpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.hpp
@@ -144,8 +144,9 @@
 	};
 													TextureBinding				(Context& context);
 													TextureBinding				(Context& context, const TestTextureSp& textureData, const Type type,
-																				 const ImageBackingMode backingMode = IMAGE_BACKING_MODE_REGULAR,
-																				 const vk::VkComponentMapping componentMapping = vk::makeComponentMappingRGBA());
+																				 const vk::VkImageAspectFlags aspectMask,
+																				 const ImageBackingMode backingMode				= IMAGE_BACKING_MODE_REGULAR,
+																				 const vk::VkComponentMapping componentMapping	= vk::makeComponentMappingRGBA());
 	vk::VkImage										getImage					(void) { return *m_textureImage; }
 	vk::VkImageView									getImageView				(void) { return *m_textureImageView; }
 	Type											getType						(void) { return m_type; }
@@ -166,6 +167,7 @@
 	de::MovePtr<vk::Allocation>						m_textureImageMemory;
 	vk::Move<vk::VkImageView>						m_textureImageView;
 	std::vector<de::SharedPtr<vk::Allocation> >		m_allocations;
+	vk::VkImageAspectFlags							m_aspectMask;
 	vk::VkComponentMapping							m_componentMapping;
 };
 
@@ -188,18 +190,22 @@
 
 	void								clearImage					(vk::VkImage image);
 	void								add2DTexture				(const TestTexture2DSp& texture,
+																	 const vk::VkImageAspectFlags& aspectMask,
 																	 TextureBinding::ImageBackingMode backingMode = TextureBinding::IMAGE_BACKING_MODE_REGULAR);
 	const pipeline::TestTexture2D&		get2DTexture				(int textureIndex) const;
 
 	void								addCubeTexture				(const TestTextureCubeSp& texture,
+																	 const vk::VkImageAspectFlags& aspectMask,
 																	 TextureBinding::ImageBackingMode backingMode = TextureBinding::IMAGE_BACKING_MODE_REGULAR);
 	const pipeline::TestTextureCube&	getCubeTexture				(int textureIndex) const;
 
 	void								add2DArrayTexture			(const TestTexture2DArraySp& texture,
+																	 const vk::VkImageAspectFlags& aspectMask,
 																	 TextureBinding::ImageBackingMode backingMode = TextureBinding::IMAGE_BACKING_MODE_REGULAR);
 	const pipeline::TestTexture2DArray&	get2DArrayTexture			(int textureIndex) const;
 
 	void								add3DTexture				(const TestTexture3DSp& texture,
+																	 const vk::VkImageAspectFlags& aspectMask,
 																	 TextureBinding::ImageBackingMode backingMode = TextureBinding::IMAGE_BACKING_MODE_REGULAR);
 	const pipeline::TestTexture3D&		get3DTexture				(int textureIndex) const;
 
@@ -314,6 +320,7 @@
 	std::vector<util::Program>	programs;
 
 	deBool						unnormal;
+	vk::VkImageAspectFlags		aspectMask;
 };
 
 struct Texture2DTestCaseParameters : public TextureCommonTestCaseParameters
diff --git a/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackFuzzLayoutCase.cpp b/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackFuzzLayoutCase.cpp
index 8e67dc5..f0f617d 100644
--- a/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackFuzzLayoutCase.cpp
+++ b/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackFuzzLayoutCase.cpp
@@ -1657,7 +1657,7 @@
 	const deUint32											componentsRequired			= m_locationsRequired * componentsPerLocation;
 	const InstanceInterface&								vki							= m_context.getInstanceInterface();
 	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
-	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
+	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
 	const VkPhysicalDeviceLimits							limits						= getPhysicalDeviceProperties(vki, physDevice).limits;
 	VkPhysicalDeviceTransformFeedbackPropertiesEXT			transformFeedbackProperties;
 	VkPhysicalDeviceProperties2								deviceProperties2;
diff --git a/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp b/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp
index 649733a..8bdcf96 100644
--- a/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp
+++ b/external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp
@@ -390,7 +390,7 @@
 	, m_parameters		(parameters)
 	, m_rnd				(0)
 {
-	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
+	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
 	VkPhysicalDeviceProperties2								deviceProperties2;
 
 	if (transformFeedbackFeatures.transformFeedback == DE_FALSE)
@@ -911,7 +911,7 @@
 	const InstanceInterface&								vki							= m_context.getInstanceInterface();
 	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
 	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
-	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
+	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
 	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
 	const deUint32											streamsRequired				= m_parameters.streamId + 1;
 	const deUint32											tfBuffersSupported			= m_transformFeedbackProperties.maxTransformFeedbackBuffers;
@@ -1045,7 +1045,7 @@
 	const InstanceInterface&								vki							= m_context.getInstanceInterface();
 	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
 	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
-	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
+	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
 	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
 	const deUint32											streamsRequired				= m_parameters.streamId + 1;
 	const bool												geomPointSizeRequired		= m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE;
@@ -1467,7 +1467,7 @@
 	const InstanceInterface&								vki							= m_context.getInstanceInterface();
 	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
 	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
-	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
+	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
 	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
 	const deUint32											streamsRequired				= m_parameters.streamId + 1;
 
@@ -1607,7 +1607,7 @@
 	endCommandBuffer(vk, *cmdBuffer);
 
 	if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
-		vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
+		vk.resetQueryPool(device, *queryPool, queryIndex, queryCountersNumber);
 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 
 	{
@@ -1666,7 +1666,7 @@
 			queryResults->elements32[2] = 1u;	// Availability bit
 		}
 
-		vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
+		vk.resetQueryPool(device, *queryPool, queryIndex, queryCountersNumber);
 
 		vk::VkResult	res						= vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataAvailSize, queryData.data(), queryDataAvailSize, (vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | queryExtraFlags));
 		const deUint64	numPrimitivesWritten	= (m_parameters.query64bits ? queryResults->elements64[0] : queryResults->elements32[0]);
diff --git a/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp b/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp
index cfb2f2c..d4b080b 100644
--- a/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp
+++ b/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp
@@ -58,20 +58,21 @@
 												BufferMode			bufferMode,
 												deUint32			features,
 												deUint32			seed)
-	: UniformBlockCase		(testCtx, name, description, bufferMode, LOAD_FULL_MATRIX, (features & FEATURE_OUT_OF_ORDER_OFFSETS) != 0u)
-	, m_features			(features)
-	, m_maxVertexBlocks		((features & FEATURE_VERTEX_BLOCKS)		? 4 : 0)
-	, m_maxFragmentBlocks	((features & FEATURE_FRAGMENT_BLOCKS)	? 4 : 0)
-	, m_maxSharedBlocks		((features & FEATURE_SHARED_BLOCKS)		? 4 : 0)
-	, m_maxInstances		((features & FEATURE_INSTANCE_ARRAYS)	? 3 : 0)
-	, m_maxArrayLength		((features & FEATURE_ARRAYS)			? 8 : 0)
-	, m_maxStructDepth		((features & FEATURE_STRUCTS)			? 2 : 0)
-	, m_maxBlockMembers		(5)
-	, m_maxStructMembers	(4)
-	, m_seed				(seed)
-	, m_blockNdx			(1)
-	, m_uniformNdx			(1)
-	, m_structNdx			(1)
+	: UniformBlockCase						(testCtx, name, description, bufferMode, LOAD_FULL_MATRIX, (features & FEATURE_OUT_OF_ORDER_OFFSETS) != 0u)
+	, m_features							(features)
+	, m_maxVertexBlocks						((features & FEATURE_VERTEX_BLOCKS)		? 4 : 0)
+	, m_maxFragmentBlocks					((features & FEATURE_FRAGMENT_BLOCKS)	? 4 : 0)
+	, m_maxSharedBlocks						((features & FEATURE_SHARED_BLOCKS)		? 4 : 0)
+	, m_maxInstances						((features & FEATURE_INSTANCE_ARRAYS)	? 3 : 0)
+	, m_maxArrayLength						((features & FEATURE_ARRAYS)			? 8 : 0)
+	, m_maxStructDepth						((features & FEATURE_STRUCTS)			? 2 : 0)
+	, m_maxBlockMembers						(5)
+	, m_maxStructMembers					(4)
+	, m_seed								(seed)
+	, m_blockNdx							(1)
+	, m_uniformNdx							(1)
+	, m_structNdx							(1)
+	, m_availableDescriptorUniformBuffers	(12)
 {
 	de::Random rnd(m_seed);
 
@@ -79,6 +80,12 @@
 	int numVtxBlocks	= m_maxVertexBlocks-numShared	> 0	? rnd.getInt(1, m_maxVertexBlocks - numShared)	: 0;
 	int	numFragBlocks	= m_maxFragmentBlocks-numShared	> 0 ? rnd.getInt(1, m_maxFragmentBlocks - numShared): 0;
 
+	// calculate how many additional descriptors we can use for arrays
+	// this is needed for descriptor_indexing testing as we need to take in to account
+	// maxPerStageDescriptorUniformBuffers limit and we can't query it as we need to
+	// generate shaders before Context is created; minimal value of this limit is 12
+	m_availableDescriptorUniformBuffers -= numVtxBlocks + numFragBlocks;
+
 	for (int ndx = 0; ndx < numShared; ndx++)
 		generateBlock(rnd, DECLARE_VERTEX | DECLARE_FRAGMENT);
 
@@ -100,6 +107,18 @@
 	int				numInstances		= (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
 	int				numUniforms			= rnd.getInt(1, m_maxBlockMembers);
 
+	if (m_features & FEATURE_DESCRIPTOR_INDEXING)
+	{
+		// generate arrays only when we are within the limit
+		if (m_availableDescriptorUniformBuffers > 3)
+			numInstances = rnd.getInt(2, 4);
+		else if (m_availableDescriptorUniformBuffers > 1)
+			numInstances = m_availableDescriptorUniformBuffers;
+		else
+			numInstances = 0;
+		m_availableDescriptorUniformBuffers -= numInstances;
+	}
+
 	if (numInstances > 0)
 		block.setArraySize(numInstances);
 
@@ -125,6 +144,9 @@
 	if (m_features & FEATURE_8BIT_STORAGE)
 		layoutFlags |= LAYOUT_8BIT_STORAGE;
 
+	if (m_features & FEATURE_DESCRIPTOR_INDEXING)
+		layoutFlags |= LAYOUT_DESCRIPTOR_INDEXING;
+
 	layoutFlags |= rnd.choose<deUint32>(layoutFlagCandidates.begin(), layoutFlagCandidates.end());
 
 	if (m_features & FEATURE_MATRIX_LAYOUT)
diff --git a/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.hpp b/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.hpp
index 10b52f3..6ecc730 100644
--- a/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.hpp
+++ b/external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.hpp
@@ -59,6 +59,7 @@
 	FEATURE_8BIT_STORAGE			= (1<<19),
 	FEATURE_STD430_LAYOUT			= (1<<20),
 	FEATURE_SCALAR_LAYOUT			= (1<<21),
+	FEATURE_DESCRIPTOR_INDEXING		= (1<<22),
 };
 
 class RandomUniformBlockCase : public UniformBlockCase
@@ -90,6 +91,7 @@
 	int						m_blockNdx;
 	int						m_uniformNdx;
 	int						m_structNdx;
+	int						m_availableDescriptorUniformBuffers;
 };
 
 } // ubo
diff --git a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp
index 7c3c117..70adcd6 100644
--- a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp
+++ b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp
@@ -1187,7 +1187,12 @@
 	{
 		src << " " << block.getInstanceName();
 		if (block.isArray())
-			src << "[" << block.getArraySize() << "]";
+		{
+			if (block.getFlags() & LAYOUT_DESCRIPTOR_INDEXING)
+				src << "[]";
+			else
+				src << "[" << block.getArraySize() << "]";
+		}
 	}
 	else
 		DE_ASSERT(!block.isArray());
@@ -1547,7 +1552,15 @@
 
 		for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
 		{
-			std::string		instancePostfix		= isArray ? std::string("[") + de::toString(instanceNdx) + "]" : std::string("");
+			std::string instancePostfix = "";
+			if (isArray)
+			{
+				std::string indexStr = de::toString(instanceNdx);
+				if (interface.usesBlockLayout(LAYOUT_DESCRIPTOR_INDEXING))
+					indexStr = std::string("nonuniformEXT(") + indexStr + ")";
+				instancePostfix = std::string("[") + indexStr + "]";
+			}
+
 			std::string		blockInstanceName	= block.getBlockName() + instancePostfix;
 			std::string		srcPrefix			= hasInstanceName ? block.getInstanceName() + instancePostfix + "." : std::string("");
 			int				blockLayoutNdx		= layout.getBlockLayoutIndex(blockNdx, instanceNdx);
@@ -1575,6 +1588,7 @@
 	src << "#extension GL_EXT_shader_16bit_storage : enable\n";
 	src << "#extension GL_EXT_shader_8bit_storage : enable\n";
 	src << "#extension GL_EXT_scalar_block_layout : enable\n";
+	src << "#extension GL_EXT_nonuniform_qualifier : enable\n";
 
 	src << "layout(location = 0) in highp vec4 a_position;\n";
 	src << "layout(location = 0) out mediump float v_vtxResult;\n";
@@ -1618,6 +1632,7 @@
 	src << "#extension GL_EXT_shader_16bit_storage : enable\n";
 	src << "#extension GL_EXT_shader_8bit_storage : enable\n";
 	src << "#extension GL_EXT_scalar_block_layout : enable\n";
+	src << "#extension GL_EXT_nonuniform_qualifier : enable\n";
 
 	src << "layout(location = 0) in mediump float v_vtxResult;\n";
 	src << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
@@ -2222,6 +2237,8 @@
 		TCU_THROW(NotSupportedError, "std430 not supported");
 	if (!context.getScalarBlockLayoutFeatures().scalarBlockLayout && usesBlockLayout(LAYOUT_SCALAR))
 		TCU_THROW(NotSupportedError, "scalarBlockLayout not supported");
+	if (!context.getDescriptorIndexingFeatures().shaderUniformBufferArrayNonUniformIndexing && usesBlockLayout(LAYOUT_DESCRIPTOR_INDEXING))
+		TCU_THROW(NotSupportedError, "Descriptor indexing over uniform buffer not supported");
 
 	return new UniformBlockCaseInstance(context, m_bufferMode, m_uniformLayout, m_blockPointers);
 }
diff --git a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.hpp b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.hpp
index 4685bdc..158b5a8 100644
--- a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.hpp
+++ b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.hpp
@@ -65,6 +65,8 @@
 
 	LAYOUT_16BIT_STORAGE= (1<<15),  //!< Support VK_KHR_16bit_storage extension
 	LAYOUT_8BIT_STORAGE	= (1<<16),  //!< Support VK_KHR_8bit_storage extension
+
+	LAYOUT_DESCRIPTOR_INDEXING = (1 << 17),  //!< Support VK_KHR_descriptor_indexing extension
 };
 
 enum MatrixLoadFlags
diff --git a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp
index 2d2d7a3..0737037 100644
--- a/external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp
+++ b/external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp
@@ -881,14 +881,15 @@
 
 	// ubo.random
 	{
-		const deUint32	allShaders		= FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
-		const deUint32	allLayouts		= FEATURE_STD140_LAYOUT;
-		const deUint32	allBasicTypes	= FEATURE_VECTORS|FEATURE_MATRICES;
-		const deUint32	unused			= FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
-		const deUint32	matFlags		= FEATURE_MATRIX_LAYOUT;
-		const deUint32	allFeatures		= ~FEATURE_OUT_OF_ORDER_OFFSETS & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE
-										  & ~FEATURE_STD430_LAYOUT & ~FEATURE_SCALAR_LAYOUT;  // OOO offsets handled in a dedicated case group
-		const deUint32	allScalar		= ~allLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE;
+		const deUint32	allShaders			= FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
+		const deUint32	allLayouts			= FEATURE_STD140_LAYOUT;
+		const deUint32	allBasicTypes		= FEATURE_VECTORS|FEATURE_MATRICES;
+		const deUint32	unused				= FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
+		const deUint32	matFlags			= FEATURE_MATRIX_LAYOUT;
+		const deUint32	allFeatures			= ~FEATURE_OUT_OF_ORDER_OFFSETS & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE
+											  & ~FEATURE_STD430_LAYOUT & ~FEATURE_SCALAR_LAYOUT & ~FEATURE_DESCRIPTOR_INDEXING;  // OOO offsets handled in a dedicated case group
+		const deUint32	allScalar			= ~allLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE & ~FEATURE_DESCRIPTOR_INDEXING;
+		const deUint32	descriptorIndexing	= FEATURE_STD140_LAYOUT | FEATURE_STD430_LAYOUT | FEATURE_SCALAR_LAYOUT | FEATURE_DESCRIPTOR_INDEXING | allShaders | allBasicTypes | unused | matFlags;
 
 		tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
 		addChild(randomGroup);
@@ -927,6 +928,7 @@
 
 			createRandomCaseGroup(group, m_testCtx, "all_out_of_order_offsets",	"All random features, out of order member offsets",		UniformBlockCase::BUFFERMODE_PER_BLOCK,	use8BitStorage|use16BitStorage|allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS,	50, 300);
 			createRandomCaseGroup(group, m_testCtx, "scalar",					"VK_EXT_scalar_block_layout",				UniformBlockCase::BUFFERMODE_SINGLE,	use8BitStorage|use16BitStorage|allScalar, 100, deInt32Hash(313));
+			createRandomCaseGroup(group, m_testCtx, "descriptor_indexing",		"VK_EXT_descriptor_indexing",				UniformBlockCase::BUFFERMODE_SINGLE,	use8BitStorage|use16BitStorage|descriptorIndexing, 50, 123);
 		}
 	}
 }
diff --git a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp
index 602269e..b38f655 100644
--- a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp
+++ b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp
@@ -73,6 +73,7 @@
 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
 	, m_win32Handle				(DE_NULL)
 	, m_androidHardwareBuffer	(DE_NULL)
+	, m_hostPtr					(DE_NULL)
 {
 }
 
@@ -81,6 +82,7 @@
 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
 	, m_win32Handle				(DE_NULL)
 	, m_androidHardwareBuffer	(DE_NULL)
+	, m_hostPtr					(DE_NULL)
 {
 	if (other.m_fd >= 0)
 	{
@@ -140,6 +142,7 @@
 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
 	, m_win32Handle				(DE_NULL)
 	, m_androidHardwareBuffer	(DE_NULL)
+	, m_hostPtr					(DE_NULL)
 {
 }
 
@@ -148,6 +151,7 @@
 	, m_win32HandleType			(handleType)
 	, m_win32Handle				(handle)
 	, m_androidHardwareBuffer	(DE_NULL)
+	, m_hostPtr					(DE_NULL)
 {
 }
 
@@ -156,6 +160,7 @@
 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
 	, m_win32Handle				(DE_NULL)
 	, m_androidHardwareBuffer	(buffer)
+	, m_hostPtr					(DE_NULL)
 {
 }
 
@@ -208,6 +213,7 @@
 	m_win32Handle			= vk::pt::Win32Handle(DE_NULL);
 	m_win32HandleType		= WIN32HANDLETYPE_LAST;
 	m_androidHardwareBuffer	= vk::pt::AndroidHardwareBufferPtr(DE_NULL);
+	m_hostPtr				= DE_NULL;
 }
 
 NativeHandle& NativeHandle::operator= (int fd)
@@ -236,17 +242,27 @@
 	m_win32Handle		= handle;
 }
 
+void NativeHandle::setHostPtr(void* hostPtr)
+{
+	reset();
+
+	m_hostPtr = hostPtr;
+}
+
 void NativeHandle::disown (void)
 {
 	m_fd = -1;
 	m_win32Handle = vk::pt::Win32Handle(DE_NULL);
 	m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
+	m_hostPtr = DE_NULL;
 }
 
 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
 {
 	DE_ASSERT(m_fd == -1);
 	DE_ASSERT(!m_androidHardwareBuffer.internal);
+	DE_ASSERT(m_hostPtr == DE_NULL);
+
 	return m_win32Handle;
 }
 
@@ -254,17 +270,25 @@
 {
 	DE_ASSERT(!m_win32Handle.internal);
 	DE_ASSERT(!m_androidHardwareBuffer.internal);
+	DE_ASSERT(m_hostPtr == DE_NULL);
 	return m_fd;
 }
 
-
 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
 {
 	DE_ASSERT(m_fd == -1);
 	DE_ASSERT(!m_win32Handle.internal);
+	DE_ASSERT(m_hostPtr == DE_NULL);
 	return m_androidHardwareBuffer;
 }
 
+void* NativeHandle::getHostPtr(void) const
+{
+	DE_ASSERT(m_fd == -1);
+	DE_ASSERT(!m_win32Handle.internal);
+	return m_hostPtr;
+}
+
 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
 {
 	switch (type)
@@ -343,6 +367,9 @@
 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
 			return "dma_buf";
 
+		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
+			return "host_allocation";
+
 		default:
 			DE_FATAL("Unknown external memory type");
 			return DE_NULL;
@@ -668,7 +695,7 @@
 			flags,
 			externalType,
 			handle.getWin32Handle(),
-			DE_NULL
+			(vk::pt::Win32LPCWSTR)DE_NULL
 		};
 
 		VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
@@ -714,12 +741,12 @@
 
 vk::Move<vk::VkSemaphore> createExportableSemaphoreType (const vk::DeviceInterface&					vkd,
 														 vk::VkDevice								device,
-														 vk::VkSemaphoreTypeKHR						semaphoreType,
+														 vk::VkSemaphoreType						semaphoreType,
 														 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
 {
-	const vk::VkSemaphoreTypeCreateInfoKHR		semaphoreTypeCreateInfo	=
+	const vk::VkSemaphoreTypeCreateInfo		semaphoreTypeCreateInfo	=
 	{
-		vk::VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR,
+		vk::VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
 		DE_NULL,
 		semaphoreType,
 		0,
@@ -851,7 +878,7 @@
 			flags,
 			externalType,
 			handle.getWin32Handle(),
-			DE_NULL
+			(vk::pt::Win32LPCWSTR)DE_NULL
 		};
 
 		VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
@@ -1038,7 +1065,7 @@
 			DE_NULL,
 			externalType,
 			handle.getWin32Handle(),
-			DE_NULL
+			(vk::pt::Win32LPCWSTR)DE_NULL
 		};
 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
 		{
@@ -1134,6 +1161,35 @@
 
 		return memory;
 	}
+	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT)
+	{
+		DE_ASSERT(memoryTypeIndex != ~0U);
+
+		const vk::VkImportMemoryHostPointerInfoEXT	importInfo		=
+		{
+			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
+			DE_NULL,
+			externalType,
+			handle.getHostPtr()
+		};
+		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
+		{
+			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+			&importInfo,
+			image,
+			buffer,
+		};
+		const vk::VkMemoryAllocateInfo					info =
+		{
+			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
+			requirements.size,
+			memoryTypeIndex
+		};
+		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
+
+		return memory;
+	}
 	else
 	{
 		DE_FATAL("Unknown external memory type");
@@ -1563,5 +1619,25 @@
 	return DE_NULL;
 }
 
+vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
+																								  vk::VkPhysicalDevice			physicalDevice)
+{
+	vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalProps =
+	{
+		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
+		DE_NULL,
+		0u,
+	};
+
+	vk::VkPhysicalDeviceProperties2 props2;
+	deMemset(&props2, 0, sizeof(props2));
+	props2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+	props2.pNext = &externalProps;
+
+	vki.getPhysicalDeviceProperties2(physicalDevice, &props2);
+
+	return externalProps;
+}
+
 } // ExternalMemoryUtil
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.hpp b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.hpp
index 3dc9be5..aa7c8f0 100644
--- a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.hpp
+++ b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.hpp
@@ -26,6 +26,9 @@
 #include "vkPlatform.hpp"
 #include "vkRefUtil.hpp"
 
+#include "deMemory.h"
+#include "deInt32.h"
+
 namespace vkt
 {
 namespace ExternalMemoryUtil
@@ -53,8 +56,9 @@
 	NativeHandle&						operator=					(vk::pt::AndroidHardwareBufferPtr buffer);
 
 	void								setWin32Handle				(Win32HandleType type, vk::pt::Win32Handle handle);
-
 	vk::pt::Win32Handle					getWin32Handle				(void) const;
+	void								setHostPtr					(void* hostPtr);
+	void*								getHostPtr					(void) const;
 	int									getFd						(void) const;
 	vk::pt::AndroidHardwareBufferPtr	getAndroidHardwareBuffer	(void) const;
 	void								disown						(void);
@@ -65,6 +69,7 @@
 	Win32HandleType						m_win32HandleType;
 	vk::pt::Win32Handle					m_win32Handle;
 	vk::pt::AndroidHardwareBufferPtr	m_androidHardwareBuffer;
+	void*								m_hostPtr;
 
 	// Disabled
 	NativeHandle&						operator=					(const NativeHandle&);
@@ -166,6 +171,26 @@
 	TRANSFERENCE_REFERENCE
 };
 
+struct ExternalHostMemory
+{
+	ExternalHostMemory(vk::VkDeviceSize aSize, vk::VkDeviceSize aAlignment)
+		: size(deAlignSize(static_cast<size_t>(aSize), static_cast<size_t>(aAlignment)))
+	{
+		data = deAlignedMalloc(this->size, static_cast<size_t>(aAlignment));
+	}
+
+	~ExternalHostMemory()
+	{
+		if (data != DE_NULL)
+		{
+			deAlignedFree(data);
+		}
+	}
+
+	size_t	size;
+	void*	data;
+};
+
 bool							isSupportedPermanence				(vk::VkExternalSemaphoreHandleTypeFlagBits	type,
 																	 Permanence									permanence);
 Transference					getHandelTypeTransferences			(vk::VkExternalSemaphoreHandleTypeFlagBits	type);
@@ -191,7 +216,7 @@
 
 vk::Move<vk::VkSemaphore>		createExportableSemaphoreType		(const vk::DeviceInterface&					vkd,
 																	 vk::VkDevice								device,
-																	 vk::VkSemaphoreTypeKHR						semaphoreType,
+																	 vk::VkSemaphoreType						semaphoreType,
 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
 
 int								getSemaphoreFd						(const vk::DeviceInterface&					vkd,
@@ -325,6 +350,9 @@
 																	 deUint32									mipLevels = 1u,
 																	 deUint32									arrayLayers = 1u);
 
+vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
+																								  vk::VkPhysicalDevice			physicalDevice);
+
 } // ExternalMemoryUtil
 } // vkt
 
diff --git a/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp b/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
index f93bb00..5ff16ca 100644
--- a/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
+++ b/external/vulkancts/modules/vulkan/vktBuildPrograms.cpp
@@ -583,14 +583,15 @@
 	{
 		{ "1.0",	VK_MAKE_VERSION(1, 0, 0)	},
 		{ "1.1",	VK_MAKE_VERSION(1, 1, 0)	},
+		{ "1.2",	VK_MAKE_VERSION(1, 2, 0)	},
 	};
 
-	DE_STATIC_ASSERT(vk::SPIRV_VERSION_1_4 + 1 == vk::SPIRV_VERSION_LAST);
+	DE_STATIC_ASSERT(vk::SPIRV_VERSION_1_5 + 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")
+		<< Option<opt::VulkanVersion>("t", "target-vulkan-version", "Target Vulkan version", s_vulkanVersion, "1.2")
 		<< Option<opt::ShaderCache>("s", "shadercache", "Enable or disable shader cache", s_enableNames, "enable")
 		<< Option<opt::ShaderCacheFilename>("r", "shadercache-filename", "Write shader cache to given file", "shadercache.bin")
 		<< Option<opt::ShaderCacheTruncate>("x", "shadercache-truncate", "Truncate shader cache before running", s_enableNames, "enable")
@@ -653,7 +654,7 @@
 
 		if (cmdLine.hasOption<opt::SpirvOptimize>())
 		{
-            deqpArgv.push_back("--deqp-optimize-spirv");
+			deqpArgv.push_back("--deqp-optimize-spirv");
 			if (cmdLine.getOption<opt::SpirvOptimize>())
 				deqpArgv.push_back("enable");
 			 else
diff --git a/external/vulkancts/modules/vulkan/vktCustomInstancesDevices.cpp b/external/vulkancts/modules/vulkan/vktCustomInstancesDevices.cpp
index 5d44b8e..0daf4bd 100644
--- a/external/vulkancts/modules/vulkan/vktCustomInstancesDevices.cpp
+++ b/external/vulkancts/modules/vulkan/vktCustomInstancesDevices.cpp
@@ -45,17 +45,18 @@
 
 vector<const char*> getValidationLayers (const vector<vk::VkLayerProperties>& supportedLayers)
 {
-	static const char*	s_magicLayer		= "VK_LAYER_LUNARG_standard_validation";
+	static const char*	s_magicLayer		= "VK_LAYER_KHRONOS_validation";
 	static const char*	s_defaultLayers[]	=
 	{
-		"VK_LAYER_GOOGLE_threading",
-		"VK_LAYER_LUNARG_parameter_validation",
+		"VK_LAYER_LUNARG_standard_validation",		// Deprecated by at least Vulkan SDK 1.1.121.
+		"VK_LAYER_GOOGLE_threading",				// Deprecated by at least Vulkan SDK 1.1.121.
+		"VK_LAYER_LUNARG_parameter_validation",		// Deprecated by at least Vulkan SDK 1.1.121.
 		"VK_LAYER_LUNARG_device_limits",
-		"VK_LAYER_LUNARG_object_tracker",
+		"VK_LAYER_LUNARG_object_tracker",			// Deprecated by at least Vulkan SDK 1.1.121.
 		"VK_LAYER_LUNARG_image",
-		"VK_LAYER_LUNARG_core_validation",
+		"VK_LAYER_LUNARG_core_validation",			// Deprecated by at least Vulkan SDK 1.1.121.
 		"VK_LAYER_LUNARG_swapchain",
-		"VK_LAYER_GOOGLE_unique_objects"
+		"VK_LAYER_GOOGLE_unique_objects"			// Deprecated by at least Vulkan SDK 1.1.121.
 	};
 
 	vector<const char*>	enabledLayers;
@@ -226,9 +227,13 @@
 	const std::vector<vk::VkExtensionProperties>	availableExtensions	= vk::enumerateInstanceExtensionProperties(vkp, DE_NULL);
 	vector<string>									extensionPtrs;
 
+	vector<string> availableExtensionNames;
+	for (const auto& ext : availableExtensions)
+		availableExtensionNames.push_back(ext.extensionName);
+
 	for (const auto& ext : extensions)
 	{
-		if (!context.isInstanceFunctionalitySupported(ext))
+		if (!vk::isInstanceExtensionSupported(apiVersion, availableExtensionNames, ext))
 			TCU_THROW(NotSupportedError, ext + " is not supported");
 
 		if (!vk::isCoreInstanceExtension(apiVersion, ext))
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.cpp b/external/vulkancts/modules/vulkan/vktTestCase.cpp
index 7207afa..935afa5 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.cpp
@@ -32,6 +32,7 @@
 #include "vkPlatform.hpp"
 #include "vkDebugReportUtil.hpp"
 #include "vkDeviceFeatures.hpp"
+#include "vkDeviceProperties.hpp"
 
 #include "tcuCommandLine.hpp"
 #include "tcuTestLog.hpp"
@@ -64,7 +65,10 @@
 		"VK_KHX_",
 		"VK_NV_cooperative_matrix",
 		"VK_NV_shading_rate_image",
-		"VK_NV_ray_tracing"
+		"VK_NV_ray_tracing",
+		"VK_AMD_mixed_attachment_samples",
+		"VK_AMD_shader_fragment_mask",
+		"VK_AMD_buffer_marker",
 	};
 
 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
@@ -275,21 +279,28 @@
 
 	VkPhysicalDevice												getPhysicalDevice						(void) const { return m_physicalDevice;									}
 	deUint32														getDeviceVersion						(void) const { return m_deviceVersion;									}
+
+	bool															isDeviceFeatureInitialized				(VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);		}
 	const VkPhysicalDeviceFeatures&									getDeviceFeatures						(void) const { return m_deviceFeatures.getCoreFeatures2().features;		}
 	const VkPhysicalDeviceFeatures2&								getDeviceFeatures2						(void) const { return m_deviceFeatures.getCoreFeatures2();				}
+	const VkPhysicalDeviceVulkan11Features&							getVulkan11Features						(void) const { return m_deviceFeatures.getVulkan11Features(); }
+	const VkPhysicalDeviceVulkan12Features&							getVulkan12Features						(void) const { return m_deviceFeatures.getVulkan12Features(); }
 
 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
 
-	VkDevice														getDevice								(void) const { return *m_device;					}
-	const DeviceInterface&											getDeviceInterface						(void) const { return m_deviceInterface;			}
-	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties;			}
-	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;			}
+	bool															isDevicePropertyInitialized				(VkStructureType sType) const { return m_devicePropertiesFull.isDevicePropertyInitialized(sType);	}
+	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties;									}
+	const VkPhysicalDeviceProperties2&								getDeviceProperties2					(void) const { return m_devicePropertiesFull.getCoreProperties2();			}
 
-	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;				}
+#include "vkDevicePropertiesForDefaultDeviceDefs.inl"
 
-	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;	}
+	VkDevice														getDevice								(void) const { return *m_device;											}
+	const DeviceInterface&											getDeviceInterface						(void) const { return m_deviceInterface;									}
+	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;									}
+	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;										}
+	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;							}
 	VkQueue															getUniversalQueue						(void) const;
-	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;		}
+	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;								}
 	VkQueue															getSparseQueue							(void) const;
 
 private:
@@ -314,10 +325,10 @@
 	const deUint32						m_universalQueueFamilyIndex;
 	const deUint32						m_sparseQueueFamilyIndex;
 	const VkPhysicalDeviceProperties	m_deviceProperties;
+	const DeviceProperties				m_devicePropertiesFull;
 
 	const Unique<VkDevice>				m_device;
 	const DeviceDriver					m_deviceInterface;
-
 };
 
 static deUint32 sanitizeApiVersion(deUint32 v)
@@ -344,6 +355,7 @@
 	, m_universalQueueFamilyIndex		(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
 	, m_sparseQueueFamilyIndex			(m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
 	, m_deviceProperties				(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
+	, m_devicePropertiesFull			(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
 	, m_device							(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
 	, m_deviceInterface					(vkPlatform, *m_instance, *m_device)
 {
@@ -400,24 +412,67 @@
 }
 
 deUint32								Context::getMaximumFrameworkVulkanVersion	(void) const { return m_device->getMaximumFrameworkVulkanVersion();		}
-deUint32								Context::getAvailableInstanceVersion		(void) const { return m_device->getAvailableInstanceVersion();			}
-const vector<string>&					Context::getInstanceExtensions				(void) const { return m_device->getInstanceExtensions();				}
-vk::VkInstance							Context::getInstance						(void) const { return m_device->getInstance();							}
-const vk::InstanceInterface&			Context::getInstanceInterface				(void) const { return m_device->getInstanceInterface();					}
-vk::VkPhysicalDevice					Context::getPhysicalDevice					(void) const { return m_device->getPhysicalDevice();					}
-deUint32								Context::getDeviceVersion					(void) const { return m_device->getDeviceVersion();						}
-const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures					(void) const { return m_device->getDeviceFeatures();					}
-const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2					(void) const { return m_device->getDeviceFeatures2();					}
+deUint32								Context::getAvailableInstanceVersion		(void) const { return m_device->getAvailableInstanceVersion();	}
+const vector<string>&					Context::getInstanceExtensions				(void) const { return m_device->getInstanceExtensions();		}
+vk::VkInstance							Context::getInstance						(void) const { return m_device->getInstance();					}
+const vk::InstanceInterface&			Context::getInstanceInterface				(void) const { return m_device->getInstanceInterface();			}
+vk::VkPhysicalDevice					Context::getPhysicalDevice					(void) const { return m_device->getPhysicalDevice();			}
+deUint32								Context::getDeviceVersion					(void) const { return m_device->getDeviceVersion();				}
+const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures					(void) const { return m_device->getDeviceFeatures();			}
+const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2					(void) const { return m_device->getDeviceFeatures2();			}
 
 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
 {
 	// check if extension was promoted to core
+	deUint32 apiVersion = getUsedApiVersion();
 	if (isCoreDeviceExtension(getUsedApiVersion(), extension))
+	{
+		// all folowing checks are for vk12 and can be skipped for previous versions
+		if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
+			return true;
+
+		// handle promoted functionality that was provided under feature bit
+		const auto& vk11Features = m_device->getVulkan11Features();
+		if (extension == "VK_KHR_multiview")
+			return !!vk11Features.multiview;
+		if (extension == "VK_KHR_variable_pointers")
+			return !!vk11Features.variablePointersStorageBuffer;
+		if (extension == "VK_KHR_sampler_ycbcr_conversion")
+			return !!vk11Features.samplerYcbcrConversion;
+		if (extension == "VK_KHR_shader_draw_parameters")
+			return !!vk11Features.shaderDrawParameters;
+
+		const auto& vk12Features = m_device->getVulkan12Features();
+		if (extension == "VK_KHR_timeline_semaphore")
+			return !!vk12Features.timelineSemaphore;
+		if (extension == "VK_KHR_buffer_device_address")
+			return !!vk12Features.bufferDeviceAddress;
+		if (extension == "VK_EXT_descriptor_indexing")
+			return !!vk12Features.descriptorIndexing;
+		if (extension == "VK_KHR_draw_indirect_count")
+			return !!vk12Features.drawIndirectCount;
+		if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
+			return !!vk12Features.samplerMirrorClampToEdge;
+		if (extension == "VK_EXT_sampler_filter_minmax")
+			return !!vk12Features.samplerFilterMinmax;
+		if (extension == "VK_EXT_shader_viewport_index_layer")
+			return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
+
+		// no feature flags to check
 		return true;
+	}
 
 	// check if extension is on the lits of extensions for current device
 	const auto& extensions = getDeviceExtensions();
-	return de::contains(extensions.begin(), extensions.end(), extension);
+	if (de::contains(extensions.begin(), extensions.end(), extension))
+	{
+		if (extension == "VK_KHR_timeline_semaphore")
+			return !!getTimelineSemaphoreFeatures().timelineSemaphore;
+
+		return true;
+	}
+
+	return false;
 }
 
 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
@@ -430,24 +485,32 @@
 
 #include "vkDeviceFeaturesForContextDefs.inl"
 
-const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();					}
-const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();					}
-vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();							}
-const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();					}
-deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();			}
-vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();					}
-deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();			}
-vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();						}
-vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;										}
-deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();					}
-bool									Context::contextSupports					(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
-																								{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
-bool									Context::contextSupports					(const ApiVersion version) const
-																								{ return m_device->getUsedApiVersion() >= pack(version); }
-bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
-																								{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
+const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();			}
+const vk::VkPhysicalDeviceProperties2&	Context::getDeviceProperties2				(void) const { return m_device->getDeviceProperties2();			}
 
-bool Context::requireDeviceFunctionality (const std::string& required)
+#include "vkDevicePropertiesForContextDefs.inl"
+
+const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();			}
+vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();					}
+const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();			}
+deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();	}
+vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();			}
+deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();	}
+vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();				}
+vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;								}
+deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();			}
+bool									Context::contextSupports					(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
+																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
+bool									Context::contextSupports					(const ApiVersion version) const
+																							{ return m_device->getUsedApiVersion() >= pack(version); }
+bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
+																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
+bool									Context::isDeviceFeatureInitialized			(vk::VkStructureType sType) const
+																							{ return m_device->isDeviceFeatureInitialized(sType);	}
+bool									Context::isDevicePropertyInitialized		(vk::VkStructureType sType) const
+																							{ return m_device->isDevicePropertyInitialized(sType);	}
+
+bool Context::requireDeviceFunctionality (const std::string& required) const
 {
 	if (!isDeviceFunctionalitySupported(required))
 		TCU_THROW(NotSupportedError, required + " is not supported");
@@ -455,7 +518,7 @@
 	return true;
 }
 
-bool Context::requireInstanceFunctionality (const std::string& required)
+bool Context::requireInstanceFunctionality (const std::string& required) const
 {
 	if (!isInstanceFunctionalitySupported(required))
 		TCU_THROW(NotSupportedError, required + " is not supported");
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.hpp b/external/vulkancts/modules/vulkan/vktTestCase.hpp
index 69d5c61..7553b2a 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.hpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.hpp
@@ -72,6 +72,7 @@
 	const vk::InstanceInterface&				getInstanceInterface				(void) const;
 	vk::VkPhysicalDevice						getPhysicalDevice					(void) const;
 	deUint32									getDeviceVersion					(void) const;
+	bool										isDeviceFeatureInitialized			(vk::VkStructureType sType) const;
 	const vk::VkPhysicalDeviceFeatures&			getDeviceFeatures					(void) const;
 	const vk::VkPhysicalDeviceFeatures2&		getDeviceFeatures2					(void) const;
 
@@ -80,7 +81,12 @@
 
 #include "vkDeviceFeaturesForContextDecl.inl"
 
+	bool										isDevicePropertyInitialized			(vk::VkStructureType sType) const;
 	const vk::VkPhysicalDeviceProperties&		getDeviceProperties					(void) const;
+	const vk::VkPhysicalDeviceProperties2&		getDeviceProperties2				(void) const;
+
+#include "vkDevicePropertiesForContextDecl.inl"
+
 	const std::vector<std::string>&				getDeviceExtensions					(void) const;
 	vk::VkDevice								getDevice							(void) const;
 	const vk::DeviceInterface&					getDeviceInterface					(void) const;
@@ -93,17 +99,17 @@
 	bool										contextSupports						(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const;
 	bool										contextSupports						(const vk::ApiVersion version) const;
 	bool										contextSupports						(const deUint32 requiredApiVersionBits) const;
-	bool										requireDeviceFunctionality			(const std::string& required);
-	bool										requireInstanceFunctionality		(const std::string& required);
+	bool										requireDeviceFunctionality			(const std::string& required) const;
+	bool										requireInstanceFunctionality		(const std::string& required) const;
 	bool										requireDeviceCoreFeature			(const DeviceCoreFeature requiredDeviceCoreFeature);
 
 	void*										getInstanceProcAddr					();
 
+	bool										isBufferDeviceAddressSupported						(void) const;
+
 	bool										resultSetOnValidation			() const		{ return m_resultSetOnValidation;	}
 	void										resultSetOnValidation			(bool value)	{ m_resultSetOnValidation = value;	}
 
-	bool										isBufferDeviceAddressSupported						(void) const;
-
 protected:
 	tcu::TestContext&							m_testCtx;
 	const vk::PlatformInterface&				m_platformInterface;
diff --git a/external/vulkancts/modules/vulkan/vktTestPackage.cpp b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
index 78e074b..f89cd3c 100644
--- a/external/vulkancts/modules/vulkan/vktTestPackage.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
@@ -90,6 +90,7 @@
 #include "vktMemoryModelTests.hpp"
 #include "vktAmberExampleTests.hpp"
 #include "vktAmberGraphicsFuzzTests.hpp"
+#include "vktImagelessFramebufferTests.hpp"
 #include "vktTransformFeedbackTests.hpp"
 #include "vktDescriptorIndexingTests.hpp"
 #include "vktImagelessFramebufferTests.hpp"
@@ -494,9 +495,9 @@
 	addChild(conditional::createTests			(m_testCtx));
 	addChild(cts_amber::createExampleTests		(m_testCtx));
 	addChild(cts_amber::createGraphicsFuzzTests	(m_testCtx));
+	addChild(imageless::createTests				(m_testCtx));
 	addChild(TransformFeedback::createTests		(m_testCtx));
 	addChild(DescriptorIndexing::createTests	(m_testCtx));
-	addChild(imageless::createTests				(m_testCtx));
 	addChild(FragmentShaderInterlock::createTests(m_testCtx));
 }
 
diff --git a/external/vulkancts/modules/vulkan/wsi/CMakeLists.txt b/external/vulkancts/modules/vulkan/wsi/CMakeLists.txt
index 2e66ff6..11bab22 100644
--- a/external/vulkancts/modules/vulkan/wsi/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/wsi/CMakeLists.txt
@@ -11,6 +11,8 @@
 	vktWsiSwapchainTests.hpp
 	vktWsiIncrementalPresentTests.cpp
 	vktWsiIncrementalPresentTests.hpp
+	vktWsiDisplayControlTests.cpp
+	vktWsiDisplayControlTests.hpp
 	vktWsiDisplayTimingTests.cpp
 	vktWsiDisplayTimingTests.hpp
 	vktWsiSharedPresentableImageTests.cpp
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp
index 2ff94a3..13bc5e4 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp
@@ -174,39 +174,6 @@
 	return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
 }
 
-deUint32 getNumQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
-{
-	deUint32	numFamilies		= 0;
-
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
-
-	return numFamilies;
-}
-
-vector<deUint32> getSupportedQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
-{
-	const deUint32		numTotalFamilyIndices	= getNumQueueFamilyIndices(vki, physicalDevice);
-	vector<deUint32>	supportedFamilyIndices;
-
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
-}
-
 struct InstanceHelper
 {
 	const vector<VkExtensionProperties>	supportedExtensions;
@@ -392,366 +359,6 @@
 	return parameters;
 }
 
-typedef de::SharedPtr<Unique<VkImageView> >		ImageViewSp;
-typedef de::SharedPtr<Unique<VkFramebuffer> >	FramebufferSp;
-
-class TriangleRenderer
-{
-public:
-									TriangleRenderer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 Allocator&					allocator,
-														 const BinaryCollection&	binaryRegistry,
-														 const vector<VkImage>		swapchainImages,
-														 const VkFormat				framebufferFormat,
-														 const UVec2&				renderSize);
-									~TriangleRenderer	(void);
-
-	void							recordFrame			(VkCommandBuffer			cmdBuffer,
-														 deUint32					imageNdx,
-														 deUint32					frameNdx) const;
-
-	static void						getPrograms			(SourceCollections& dst);
-
-private:
-	static Move<VkRenderPass>		createRenderPass	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkFormat				colorAttachmentFormat);
-	static Move<VkPipelineLayout>	createPipelineLayout(const DeviceInterface&		vkd,
-														 VkDevice					device);
-	static Move<VkPipeline>			createPipeline		(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkPipelineLayout		pipelineLayout,
-														 const BinaryCollection&	binaryCollection,
-														 const UVec2&				renderSize);
-
-	static Move<VkImageView>		createAttachmentView(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkImage				image,
-														 const VkFormat				format);
-	static Move<VkFramebuffer>		createFramebuffer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkImageView			colorAttachment,
-														 const UVec2&				renderSize);
-
-	static Move<VkBuffer>			createBuffer		(const DeviceInterface&		vkd,
-														 VkDevice					device,
-														 VkDeviceSize				size,
-														 VkBufferUsageFlags			usage);
-
-	const DeviceInterface&			m_vkd;
-
-	const vector<VkImage>			m_swapchainImages;
-	const tcu::UVec2				m_renderSize;
-
-	const Unique<VkRenderPass>		m_renderPass;
-	const Unique<VkPipelineLayout>	m_pipelineLayout;
-	const Unique<VkPipeline>		m_pipeline;
-
-	const Unique<VkBuffer>			m_vertexBuffer;
-	const UniquePtr<Allocation>		m_vertexBufferMemory;
-
-	vector<ImageViewSp>				m_attachmentViews;
-	vector<FramebufferSp>			m_framebuffers;
-};
-
-Move<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface&	vkd,
-													   const VkDevice			device,
-													   const VkFormat			colorAttachmentFormat)
-{
-	const VkAttachmentDescription	colorAttDesc		=
-	{
-		(VkAttachmentDescriptionFlags)0,
-		colorAttachmentFormat,
-		VK_SAMPLE_COUNT_1_BIT,
-		VK_ATTACHMENT_LOAD_OP_CLEAR,
-		VK_ATTACHMENT_STORE_OP_STORE,
-		VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-		VK_ATTACHMENT_STORE_OP_DONT_CARE,
-		VK_IMAGE_LAYOUT_UNDEFINED,
-		VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-	};
-	const VkAttachmentReference		colorAttRef			=
-	{
-		0u,
-		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-	};
-	const VkSubpassDescription		subpassDesc			=
-	{
-		(VkSubpassDescriptionFlags)0u,
-		VK_PIPELINE_BIND_POINT_GRAPHICS,
-		0u,							// inputAttachmentCount
-		DE_NULL,					// pInputAttachments
-		1u,							// colorAttachmentCount
-		&colorAttRef,				// pColorAttachments
-		DE_NULL,					// pResolveAttachments
-		DE_NULL,					// depthStencilAttachment
-		0u,							// preserveAttachmentCount
-		DE_NULL,					// pPreserveAttachments
-	};
-	const VkSubpassDependency		dependencies[]		=
-	{
-		{
-			VK_SUBPASS_EXTERNAL,	// srcSubpass
-			0u,						// dstSubpass
-			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-			VK_ACCESS_MEMORY_READ_BIT,
-			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
-			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
-			VK_DEPENDENCY_BY_REGION_BIT
-		},
-		{
-			0u,						// srcSubpass
-			VK_SUBPASS_EXTERNAL,	// dstSubpass
-			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
-			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
-			VK_ACCESS_MEMORY_READ_BIT,
-			VK_DEPENDENCY_BY_REGION_BIT
-		},
-	};
-	const VkRenderPassCreateInfo	renderPassParams	=
-	{
-		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-		DE_NULL,
-		(VkRenderPassCreateFlags)0,
-		1u,
-		&colorAttDesc,
-		1u,
-		&subpassDesc,
-		DE_LENGTH_OF_ARRAY(dependencies),
-		dependencies,
-	};
-
-	return vk::createRenderPass(vkd, device, &renderPassParams);
-}
-
-Move<VkPipelineLayout> TriangleRenderer::createPipelineLayout (const DeviceInterface&	vkd,
-															   const VkDevice			device)
-{
-	const VkPushConstantRange						pushConstantRange		=
-	{
-		VK_SHADER_STAGE_VERTEX_BIT,
-		0u,											// offset
-		(deUint32)sizeof(deUint32),					// size
-	};
-	const VkPipelineLayoutCreateInfo				pipelineLayoutParams	=
-	{
-		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-		DE_NULL,
-		(vk::VkPipelineLayoutCreateFlags)0,
-		0u,											// setLayoutCount
-		DE_NULL,									// pSetLayouts
-		1u,
-		&pushConstantRange,
-	};
-
-	return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
-}
-
-Move<VkPipeline> TriangleRenderer::createPipeline (const DeviceInterface&	vkd,
-												   const VkDevice			device,
-												   const VkRenderPass		renderPass,
-												   const VkPipelineLayout	pipelineLayout,
-												   const BinaryCollection&	binaryCollection,
-												   const UVec2&				renderSize)
-{
-	// \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
-	//		 and can be deleted immediately following that call.
-	const Unique<VkShaderModule>					vertShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
-	const Unique<VkShaderModule>					fragShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
-	const std::vector<VkViewport>					viewports				(1, makeViewport(renderSize));
-	const std::vector<VkRect2D>						scissors				(1, makeRect2D(renderSize));
-
-	return vk::makeGraphicsPipeline(vkd,				// const DeviceInterface&            vk
-									device,				// const VkDevice                    device
-									pipelineLayout,		// const VkPipelineLayout            pipelineLayout
-									*vertShaderModule,	// const VkShaderModule              vertexShaderModule
-									DE_NULL,			// const VkShaderModule              tessellationControlShaderModule
-									DE_NULL,			// const VkShaderModule              tessellationEvalShaderModule
-									DE_NULL,			// const VkShaderModule              geometryShaderModule
-									*fragShaderModule,	// const VkShaderModule              fragmentShaderModule
-									renderPass,			// const VkRenderPass                renderPass
-									viewports,			// const std::vector<VkViewport>&    viewports
-									scissors);			// const std::vector<VkRect2D>&      scissors
-}
-
-Move<VkImageView> TriangleRenderer::createAttachmentView (const DeviceInterface&	vkd,
-														  const VkDevice			device,
-														  const VkImage				image,
-														  const VkFormat			format)
-{
-	const VkImageViewCreateInfo		viewParams	=
-	{
-		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-		DE_NULL,
-		(VkImageViewCreateFlags)0,
-		image,
-		VK_IMAGE_VIEW_TYPE_2D,
-		format,
-		vk::makeComponentMappingRGBA(),
-		{
-			VK_IMAGE_ASPECT_COLOR_BIT,
-			0u,						// baseMipLevel
-			1u,						// levelCount
-			0u,						// baseArrayLayer
-			1u,						// layerCount
-		},
-	};
-
-	return vk::createImageView(vkd, device, &viewParams);
-}
-
-Move<VkFramebuffer> TriangleRenderer::createFramebuffer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkImageView			colorAttachment,
-														 const UVec2&				renderSize)
-{
-	const VkFramebufferCreateInfo	framebufferParams	=
-	{
-		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-		DE_NULL,
-		(VkFramebufferCreateFlags)0,
-		renderPass,
-		1u,
-		&colorAttachment,
-		renderSize.x(),
-		renderSize.y(),
-		1u,							// layers
-	};
-
-	return vk::createFramebuffer(vkd, device, &framebufferParams);
-}
-
-Move<VkBuffer> TriangleRenderer::createBuffer (const DeviceInterface&	vkd,
-											   VkDevice					device,
-											   VkDeviceSize				size,
-											   VkBufferUsageFlags		usage)
-{
-	const VkBufferCreateInfo	bufferParams	=
-	{
-		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
-		DE_NULL,
-		(VkBufferCreateFlags)0,
-		size,
-		usage,
-		VK_SHARING_MODE_EXCLUSIVE,
-		0,
-		DE_NULL
-	};
-
-	return vk::createBuffer(vkd, device, &bufferParams);
-}
-
-TriangleRenderer::TriangleRenderer (const DeviceInterface&	vkd,
-									const VkDevice			device,
-									Allocator&				allocator,
-									const BinaryCollection&	binaryRegistry,
-									const vector<VkImage>	swapchainImages,
-									const VkFormat			framebufferFormat,
-									const UVec2&			renderSize)
-	: m_vkd					(vkd)
-	, m_swapchainImages		(swapchainImages)
-	, m_renderSize			(renderSize)
-	, m_renderPass			(createRenderPass(vkd, device, framebufferFormat))
-	, m_pipelineLayout		(createPipelineLayout(vkd, device))
-	, m_pipeline			(createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
-	, m_vertexBuffer		(createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
-	, m_vertexBufferMemory	(allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
-							 MemoryRequirement::HostVisible))
-{
-	m_attachmentViews.resize(swapchainImages.size());
-	m_framebuffers.resize(swapchainImages.size());
-
-	for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
-	{
-		m_attachmentViews[imageNdx]	= ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
-		m_framebuffers[imageNdx]	= FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
-	}
-
-	VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
-
-	{
-		const VkMappedMemoryRange	memRange	=
-		{
-			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
-			DE_NULL,
-			m_vertexBufferMemory->getMemory(),
-			m_vertexBufferMemory->getOffset(),
-			VK_WHOLE_SIZE
-		};
-		const tcu::Vec4				vertices[]	=
-		{
-			tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
-			tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
-			tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
-		};
-		DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
-
-		deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
-		VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
-	}
-}
-
-TriangleRenderer::~TriangleRenderer (void)
-{
-}
-
-void TriangleRenderer::recordFrame (VkCommandBuffer	cmdBuffer,
-									deUint32		imageNdx,
-									deUint32		frameNdx) const
-{
-	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
-
-	beginCommandBuffer(m_vkd, cmdBuffer, 0u);
-
-	beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
-
-	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
-
-	{
-		const VkDeviceSize bindingOffset = 0;
-		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
-	}
-
-	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
-	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
-	endRenderPass(m_vkd, cmdBuffer);
-
-	endCommandBuffer(m_vkd, cmdBuffer);
-}
-
-void TriangleRenderer::getPrograms (SourceCollections& dst)
-{
-	dst.glslSources.add("tri-vert") << glu::VertexSource(
-		"#version 310 es\n"
-		"layout(location = 0) in highp vec4 a_position;\n"
-		"layout(push_constant) uniform FrameData\n"
-		"{\n"
-		"    highp uint frameNdx;\n"
-		"} frameData;\n"
-		"void main (void)\n"
-		"{\n"
-		"    highp float angle = float(frameData.frameNdx) / 100.0;\n"
-		"    highp float c     = cos(angle);\n"
-		"    highp float s     = sin(angle);\n"
-		"    highp mat4  t     = mat4( c, -s,  0,  0,\n"
-		"                              s,  c,  0,  0,\n"
-		"                              0,  0,  1,  0,\n"
-		"                              0,  0,  0,  1);\n"
-		"    gl_Position = t * a_position;\n"
-		"}\n");
-	dst.glslSources.add("tri-frag") << glu::FragmentSource(
-		"#version 310 es\n"
-		"layout(location = 0) out lowp vec4 o_color;\n"
-		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
-}
-
 typedef de::SharedPtr<Unique<VkCommandBuffer> >	CommandBufferSp;
 typedef de::SharedPtr<Unique<VkFence> >			FenceSp;
 typedef de::SharedPtr<Unique<VkSemaphore> >		SemaphoreSp;
@@ -846,10 +453,12 @@
 	if (checkHdr && !isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_hdr_metadata")))
 		TCU_THROW(NotSupportedError, "Extension VK_EXT_hdr_metadata not supported");
 
-	const TriangleRenderer			renderer					(vkd,
+	const WsiTriangleRenderer		renderer					(vkd,
 																 device,
 																 allocator,
 																 context.getBinaryCollection(),
+																 false,
+																 swapchainImages,
 																 swapchainImages,
 																 swapchainInfo.imageFormat,
 																 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
@@ -1012,7 +621,7 @@
 
 void getBasicRenderPrograms (SourceCollections& dst, Type)
 {
-	TriangleRenderer::getPrograms(dst);
+	WsiTriangleRenderer::getPrograms(dst);
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.cpp
new file mode 100644
index 0000000..39e66c0
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.cpp
@@ -0,0 +1,1093 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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.
+ *
+ *//*!
+ * \brief VK_EXT_display_control tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vkRefUtil.hpp"
+#include "vkWsiPlatform.hpp"
+#include "vkWsiUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkDeviceUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkWsiUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+
+#include "vktWsiDisplayControlTests.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktCustomInstancesDevices.hpp"
+
+#include "tcuPlatform.hpp"
+#include "tcuResultCollector.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuCommandLine.hpp"
+
+#include "deClock.h"
+
+#include <vector>
+#include <string>
+
+using std::vector;
+using std::string;
+
+using tcu::Maybe;
+using tcu::UVec2;
+using tcu::TestLog;
+
+namespace vkt
+{
+namespace wsi
+{
+namespace
+{
+
+using namespace vk;
+using namespace vk::wsi;
+
+typedef vector<VkExtensionProperties> Extensions;
+
+CustomInstance createInstance (Context& context)
+{
+	vector<string> extensions =
+	{
+		"VK_KHR_surface",
+		"VK_KHR_display",
+		"VK_EXT_display_surface_counter",
+	};
+
+	return vkt::createCustomInstanceWithExtensions(context, extensions);
+}
+
+deUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
+{
+	deUint32 numTotalFamilyIndices;
+	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, DE_NULL);
+
+	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
+	{
+		if (wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) == VK_TRUE)
+			return queueFamilyNdx;
+	}
+
+	TCU_THROW(NotSupportedError, "Device doesn't support presentation");
+	return 0;
+}
+
+Move<VkDevice> createDevice (const PlatformInterface&		vkp,
+							 const VkInstance				instance,
+							 const InstanceInterface&		vki,
+							 VkPhysicalDevice				physicalDevice,
+							 const Extensions&				supportedExtensions,
+							 const deUint32					queueFamilyIndex,
+							 bool							validationEnabled,
+							 const VkAllocationCallbacks*	pAllocator = DE_NULL)
+{
+	const float queuePriorities[] = { 1.0f };
+	const VkDeviceQueueCreateInfo queueInfos[] =
+	{
+		{
+			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+			DE_NULL,
+			(VkDeviceQueueCreateFlags)0,
+			queueFamilyIndex,
+			DE_LENGTH_OF_ARRAY(queuePriorities),
+			&queuePriorities[0]
+		}
+	};
+
+	VkPhysicalDeviceFeatures features;
+	deMemset(&features, 0, sizeof(features));
+
+	const char* extensions[] =
+	{
+		"VK_KHR_swapchain",
+		"VK_EXT_display_control"
+	};
+
+	const VkDeviceCreateInfo deviceParams =
+	{
+		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+		DE_NULL,
+		(VkDeviceCreateFlags)0,
+		DE_LENGTH_OF_ARRAY(queueInfos),
+		&queueInfos[0],
+		0u,
+		DE_NULL,
+		DE_LENGTH_OF_ARRAY(extensions),
+		&extensions[0],
+		&features
+	};
+
+	for (auto ext: extensions)
+	{
+		if (!isExtensionSupported(supportedExtensions, RequiredExtension(ext)))
+			TCU_THROW(NotSupportedError, (string(ext) + " is not supported").c_str());
+	}
+
+	return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
+}
+
+VkDisplayKHR getDisplayAndDisplayPlane(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *pPlaneIndex)
+{
+	deUint32 countDisplays = 0;
+	VkResult result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countDisplays, DE_NULL);
+	if (result != VK_SUCCESS)
+		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");
+
+	if (countDisplays == 0)
+		TCU_THROW(NotSupportedError, "No displays available");
+
+	deUint32 countDisplayPlanes = 0;
+	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &countDisplayPlanes, DE_NULL);
+	if (result != VK_SUCCESS || !countDisplayPlanes)
+		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");
+
+	for (deUint32 p = 0; p < countDisplayPlanes; p++)
+	{
+		deUint32 count = 0u;
+		result = vki.getDisplayPlaneSupportedDisplaysKHR(physicalDevice, p, &count, DE_NULL);
+		if (result != VK_SUCCESS)
+			TCU_FAIL("GetDisplayPlaneSupportedDisplaysKHR failed");
+
+		// No displays that can make use of this plane are available.
+		if (!count)
+			continue;
+
+		std::vector<VkDisplayKHR> displays(count);
+		result = vki.getDisplayPlaneSupportedDisplaysKHR(physicalDevice, p, &count, &displays[0]);
+		if (result != VK_SUCCESS)
+			TCU_FAIL("GetDisplayPlaneSupportedDisplaysKHR failed");
+
+		// return first plane with an available display
+		*pPlaneIndex = p;
+		return displays[0];
+	}
+
+	TCU_FAIL("No intersection between displays and display planes");
+
+	// Unreachable.
+	return DE_NULL;
+}
+
+VkSurfaceKHR createSurface(const InstanceInterface& vki, VkInstance instance, VkPhysicalDevice physicalDevice, VkDisplayKHR display, deUint32 planeIndex)
+{
+	// get number of display modes for this display
+	deUint32 displayModesCount = 0;
+	VkResult result = vki.getDisplayModePropertiesKHR(physicalDevice, display, &displayModesCount, DE_NULL);
+	if (result != VK_SUCCESS)
+		TCU_FAIL("GetDisplayModePropertiesKHR failed");
+
+	// get first display mode of this display
+	std::vector<vk::VkDisplayModePropertiesKHR> modeProperties(displayModesCount);
+	result = vki.getDisplayModePropertiesKHR(physicalDevice, display, &displayModesCount, &modeProperties[0]);
+	if (result != VK_SUCCESS)
+		TCU_FAIL("GetDisplayModePropertiesKHR failed");
+	VkDisplayModeKHR displayMode = modeProperties[0].displayMode;
+
+	// get capabielieties for first plane of this display
+	VkDisplayPlaneCapabilitiesKHR planeCapabilities;
+	result = vki.getDisplayPlaneCapabilitiesKHR(physicalDevice, displayMode, planeIndex, &planeCapabilities);
+	if (result != VK_SUCCESS)
+		TCU_FAIL("GetDisplayPlaneCapabilitiesKHR failed");
+
+	// get plane properties count
+	deUint32 planePropertiesCount = 0;
+	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &planePropertiesCount, DE_NULL);
+	if (result != VK_SUCCESS || !planePropertiesCount)
+		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");
+
+	// get plane properties
+	std::vector <VkDisplayPlanePropertiesKHR> planeProperties(planePropertiesCount);
+	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &planePropertiesCount, &planeProperties[0]);
+	if (result != VK_SUCCESS)
+		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");
+
+	// define surface create info
+	const VkDisplaySurfaceCreateInfoKHR createInfo =
+	{
+		VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,	// VkStructureType					sType
+		DE_NULL,											// const void*						pNext
+		0,													// VkDisplaySurfaceCreateFlagsKHR	flags
+		displayMode,										// VkDisplayModeKHR					displayMode
+		planeIndex,											// uint32_t							planeIndex
+		planeProperties[planeIndex].currentStackIndex,		// uint32_t							planeStackIndex
+		VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,				// VkSurfaceTransformFlagBitsKHR	transform
+		1.0f,												// float							globalAlpha
+		VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR,				// VkDisplayPlaneAlphaFlagBitsKHR	alphaMode
+		{													// VkExtent2D						imageExtent
+			planeCapabilities.minDstExtent.width,
+			planeCapabilities.minDstExtent.height
+		}
+	};
+
+	VkSurfaceKHR surface = DE_NULL;
+	result = vki.createDisplayPlaneSurfaceKHR(instance, &createInfo, DE_NULL, &surface);
+	if (result != VK_SUCCESS)
+		TCU_FAIL("CreateDisplayPlaneSurfaceKHR failed");
+
+	if (surface == DE_NULL)
+		TCU_FAIL("Invalid surface handle returned");
+
+	return surface;
+}
+
+void initSemaphores (const DeviceInterface&		vkd,
+					 VkDevice					device,
+					 std::vector<VkSemaphore>&	semaphores)
+{
+	for (VkSemaphore& semaphore : semaphores)
+		semaphore = createSemaphore(vkd, device).disown();
+}
+
+void deinitSemaphores (const DeviceInterface&	vkd,
+					 VkDevice					device,
+					 std::vector<VkSemaphore>&	semaphores)
+{
+	for (VkSemaphore& semaphore : semaphores)
+	{
+		if (semaphore == (VkSemaphore)0)
+			continue;
+
+		vkd.destroySemaphore(device, semaphore, DE_NULL);
+		semaphore = (VkSemaphore)0;
+	}
+
+	semaphores.clear();
+}
+
+void initFences (const DeviceInterface&	vkd,
+				 VkDevice				device,
+				 std::vector<VkFence>&	fences)
+{
+	for (VkFence& fence : fences)
+		fence = createFence(vkd, device).disown();
+}
+
+void deinitFences (const DeviceInterface&	vkd,
+				   VkDevice					device,
+				   std::vector<VkFence>&	fences)
+{
+	for (VkFence& fence : fences)
+	{
+		if (fence == (VkFence)0)
+			continue;
+
+		vkd.destroyFence(device, fence, DE_NULL);
+		fence = (VkFence)0;
+	}
+
+	fences.clear();
+}
+
+Move<VkCommandBuffer> createCommandBuffer (const DeviceInterface&	vkd,
+										   VkDevice					device,
+										   VkCommandPool			commandPool,
+										   VkRenderPass				renderPass,
+										   VkImage					image,
+										   VkFramebuffer			framebuffer,
+										   VkPipeline				pipeline,
+										   deUint32					imageWidth,
+										   deUint32					imageHeight)
+{
+	const VkCommandBufferAllocateInfo allocateInfo =
+	{
+		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+		DE_NULL,
+
+		commandPool,
+		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+		1
+	};
+
+	VkImageMemoryBarrier imageBarrier =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
+		DE_NULL,									// const void*				pNext;
+		0u,											// VkAccessFlags			srcAccessMask;
+		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
+		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
+		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
+		image,										// VkImage					image;
+		{											// VkImageSubresourceRange	subresourceRange;
+			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags		aspectMask;
+			0u,										// deUint32					baseMipLevel;
+			1u,										// deUint32					mipLevels;
+			0u,										// deUint32					baseArraySlice;
+			1u										// deUint32					arraySize;
+		}
+	};
+
+	Move<VkCommandBuffer>	commandBuffer	(allocateCommandBuffer(vkd, device, &allocateInfo));
+	beginCommandBuffer(vkd, *commandBuffer, 0u);
+
+	vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+		(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
+
+	beginRenderPass(vkd, *commandBuffer, renderPass, framebuffer, makeRect2D(0, 0, imageWidth, imageHeight), tcu::Vec4(0.25f, 0.5f, 0.75f, 1.0f));
+
+	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+	vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
+
+	endRenderPass(vkd, *commandBuffer);
+
+	endCommandBuffer(vkd, *commandBuffer);
+	return commandBuffer;
+}
+
+void deinitCommandBuffers (const DeviceInterface&			vkd,
+						   VkDevice							device,
+						   VkCommandPool					commandPool,
+						   std::vector<VkCommandBuffer>&	commandBuffers)
+{
+	for (size_t ndx = 0; ndx < commandBuffers.size(); ndx++)
+	{
+		if (commandBuffers[ndx] != (VkCommandBuffer)0)
+			vkd.freeCommandBuffers(device, commandPool, 1u,  &commandBuffers[ndx]);
+
+		commandBuffers[ndx] = (VkCommandBuffer)0;
+	}
+
+	commandBuffers.clear();
+}
+
+Move<VkCommandPool> createCommandPool (const DeviceInterface&	vkd,
+									   VkDevice					device,
+									   deUint32					queueFamilyIndex)
+{
+	const VkCommandPoolCreateInfo createInfo =
+	{
+		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+		DE_NULL,
+		0u,
+		queueFamilyIndex
+	};
+
+	return createCommandPool(vkd, device, &createInfo);
+}
+
+void initFramebuffers (const DeviceInterface&		vkd,
+					   VkDevice						device,
+					   VkRenderPass					renderPass,
+					   std::vector<VkImageView>		imageViews,
+					   deUint32						width,
+					   deUint32						height,
+					   std::vector<VkFramebuffer>&	framebuffers)
+{
+	DE_ASSERT(framebuffers.size() == imageViews.size());
+
+	for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
+	{
+		const VkFramebufferCreateInfo createInfo =
+		{
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+			DE_NULL,
+
+			0u,
+			renderPass,
+			1u,
+			&imageViews[ndx],
+			width,
+			height,
+			1u
+		};
+
+		framebuffers[ndx] = createFramebuffer(vkd, device, &createInfo).disown();
+	}
+}
+
+void deinitFramebuffers (const DeviceInterface&			vkd,
+						 VkDevice						device,
+						 std::vector<VkFramebuffer>&	framebuffers)
+{
+	for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
+	{
+		if (framebuffers[ndx] != (VkFramebuffer)0)
+			vkd.destroyFramebuffer(device, framebuffers[ndx], DE_NULL);
+
+		framebuffers[ndx] = (VkFramebuffer)0;
+	}
+
+	framebuffers.clear();
+}
+
+Move<VkImageView> createImageView (const DeviceInterface&	vkd,
+								   VkDevice					device,
+								   VkImage					image,
+								   VkFormat					format)
+{
+	const VkImageViewCreateInfo	createInfo =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+		DE_NULL,
+
+		0u,
+		image,
+		VK_IMAGE_VIEW_TYPE_2D,
+		format,
+		makeComponentMappingRGBA(),
+		{
+			VK_IMAGE_ASPECT_COLOR_BIT,
+			0u,
+			1u,
+			0u,
+			1u
+		}
+	};
+
+	return createImageView(vkd, device, &createInfo, DE_NULL);
+}
+
+void initImageViews (const DeviceInterface&			vkd,
+					 VkDevice						device,
+					 const std::vector<VkImage>&	images,
+					 VkFormat						format,
+					 std::vector<VkImageView>&		imageViews)
+{
+	DE_ASSERT(images.size() == imageViews.size());
+
+	for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
+		imageViews[ndx] = createImageView(vkd, device, images[ndx], format).disown();
+}
+
+void deinitImageViews (const DeviceInterface&		vkd,
+					   VkDevice						device,
+					   std::vector<VkImageView>&	imageViews)
+{
+	for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
+	{
+		if (imageViews[ndx] != (VkImageView)0)
+			vkd.destroyImageView(device, imageViews[ndx], DE_NULL);
+
+		imageViews[ndx] = (VkImageView)0;
+	}
+
+	imageViews.clear();
+}
+
+Move<VkPipeline> createPipeline (const DeviceInterface&	vkd,
+								 VkDevice				device,
+								 VkRenderPass			renderPass,
+								 VkPipelineLayout		layout,
+								 VkShaderModule			vertexShaderModule,
+								 VkShaderModule			fragmentShaderModule,
+								 deUint32				width,
+								 deUint32				height)
+{
+	const VkPipelineVertexInputStateCreateInfo	vertexInputState	=
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+		DE_NULL,
+		0u,
+		0u,
+		DE_NULL,
+		0u,
+		DE_NULL
+	};
+	const std::vector<VkViewport>	viewports	(1, makeViewport(tcu::UVec2(width, height)));
+	const std::vector<VkRect2D>		scissors	(1, makeRect2D(tcu::UVec2(width, height)));
+
+	return makeGraphicsPipeline(vkd,										// const DeviceInterface&                        vk
+								device,										// const VkDevice                                device
+								layout,										// const VkPipelineLayout                        pipelineLayout
+								vertexShaderModule,							// const VkShaderModule                          vertexShaderModule
+								DE_NULL,									// const VkShaderModule                          tessellationControlShaderModule
+								DE_NULL,									// const VkShaderModule                          tessellationEvalShaderModule
+								DE_NULL,									// const VkShaderModule                          geometryShaderModule
+								fragmentShaderModule,						// const VkShaderModule                          fragmentShaderModule
+								renderPass,									// const VkRenderPass                            renderPass
+								viewports,									// const std::vector<VkViewport>&                viewports
+								scissors,									// const std::vector<VkRect2D>&                  scissors
+								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,		// const VkPrimitiveTopology                     topology
+								0u,											// const deUint32                                subpass
+								0u,											// const deUint32                                patchControlPoints
+								&vertexInputState);							// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
+}
+
+Move<VkPipelineLayout> createPipelineLayout (const DeviceInterface&	vkd,
+												   VkDevice			device)
+{
+	const VkPipelineLayoutCreateInfo createInfo	=
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+		DE_NULL,
+		0u,
+		0u,
+		DE_NULL,
+		0u,
+		DE_NULL,
+	};
+
+	return createPipelineLayout(vkd, device, &createInfo);
+}
+
+VkSwapchainCreateInfoKHR createSwapchainConfig (VkSurfaceKHR						surface,
+												deUint32							queueFamilyIndex,
+												const VkSurfaceCapabilities2EXT&	properties,
+												const vector<VkSurfaceFormatKHR>&	formats,
+												const vector<VkPresentModeKHR>&		presentModes,
+												VkPresentModeKHR					presentMode)
+{
+	if ((properties.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) == 0)
+		TCU_THROW(NotSupportedError, "vblank counter not supported");
+
+	const deUint32				imageLayers		= 1u;
+	const VkImageUsageFlags		imageUsage		= properties.supportedUsageFlags;
+	const VkBool32				clipped			= VK_FALSE;
+
+	const deUint32				imageWidth		= (properties.currentExtent.width != 0xFFFFFFFFu)
+													? properties.currentExtent.width
+													: de::min(1024u, properties.minImageExtent.width + ((properties.maxImageExtent.width - properties.minImageExtent.width) / 2));
+	const deUint32				imageHeight		= (properties.currentExtent.height != 0xFFFFFFFFu)
+													? properties.currentExtent.height
+													: de::min(1024u, properties.minImageExtent.height + ((properties.maxImageExtent.height - properties.minImageExtent.height) / 2));
+	const VkExtent2D			imageSize		= { imageWidth, imageHeight };
+
+	if (std::find(presentModes.begin(), presentModes.end(), presentMode) == presentModes.end())
+		TCU_THROW(NotSupportedError, "Present mode not supported");
+
+	// Pick the first supported transform, alpha, and format:
+	VkSurfaceTransformFlagsKHR transform;
+	for (transform = 1u; transform <= properties.supportedTransforms; transform = transform << 1u)
+	{
+		if ((properties.supportedTransforms & transform) != 0)
+			break;
+	}
+
+	VkCompositeAlphaFlagsKHR alpha;
+	for (alpha = 1u; alpha <= properties.supportedCompositeAlpha; alpha = alpha << 1u)
+	{
+		if ((alpha & properties.supportedCompositeAlpha) != 0)
+			break;
+	}
+
+	{
+		VkSwapchainCounterCreateInfoEXT swapchainCounterInfo =
+		{
+			VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT,
+			DE_NULL,
+			VK_SURFACE_COUNTER_VBLANK_EXT
+		};
+
+		const VkSurfaceTransformFlagBitsKHR	preTransform	= (VkSurfaceTransformFlagBitsKHR)transform;
+		const VkCompositeAlphaFlagBitsKHR	compositeAlpha	= (VkCompositeAlphaFlagBitsKHR)alpha;
+		const VkFormat						imageFormat		= formats[0].format;
+		const VkColorSpaceKHR				imageColorSpace	= formats[0].colorSpace;
+		const VkSwapchainCreateInfoKHR		createInfo		=
+		{
+			VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+			&swapchainCounterInfo,
+			0u,
+			surface,
+			properties.minImageCount,
+			imageFormat,
+			imageColorSpace,
+			imageSize,
+			imageLayers,
+			imageUsage,
+			VK_SHARING_MODE_EXCLUSIVE,
+			1u,
+			&queueFamilyIndex,
+			preTransform,
+			compositeAlpha,
+			presentMode,
+			clipped,
+			(VkSwapchainKHR)0
+		};
+
+		return createInfo;
+	}
+}
+
+class SwapchainCounterTestInstance : public TestInstance
+{
+public:
+						SwapchainCounterTestInstance	(Context& context);
+						~SwapchainCounterTestInstance	(void);
+
+	tcu::TestStatus		iterate							(void);
+
+private:
+	void				initSwapchainResources			(void);
+	void				deinitSwapchainResources		(void);
+	void				render							(void);
+
+private:
+	const PlatformInterface&			m_vkp;
+	const CustomInstance				m_instance;
+	const InstanceDriver&				m_vki;
+	const VkPhysicalDevice				m_physicalDevice;
+	deUint32							m_planeIndex;
+	const VkDisplayKHR					m_display;
+	const VkSurfaceKHR					m_surface;
+
+	const deUint32						m_queueFamilyIndex;
+	const Extensions					m_deviceExtensions;
+	const Unique<VkDevice>				m_device;
+	const DeviceDriver					m_vkd;
+	const VkQueue						m_queue;
+
+	const Unique<VkCommandPool>			m_commandPool;
+	const Unique<VkShaderModule>		m_vertexShaderModule;
+	const Unique<VkShaderModule>		m_fragmentShaderModule;
+	const Unique<VkPipelineLayout>		m_pipelineLayout;
+
+	const VkSurfaceCapabilities2EXT		m_surfaceProperties;
+	const vector<VkSurfaceFormatKHR>	m_surfaceFormats;
+	const vector<VkPresentModeKHR>		m_presentModes;
+
+	tcu::ResultCollector				m_resultCollector;
+
+	Move<VkSwapchainKHR>				m_swapchain;
+	std::vector<VkImage>				m_swapchainImages;
+
+	Move<VkRenderPass>					m_renderPass;
+	Move<VkPipeline>					m_pipeline;
+
+	std::vector<VkImageView>			m_swapchainImageViews;
+	std::vector<VkFramebuffer>			m_framebuffers;
+	std::vector<VkCommandBuffer>		m_commandBuffers;
+	std::vector<VkSemaphore>			m_acquireSemaphores;
+	std::vector<VkSemaphore>			m_renderSemaphores;
+	std::vector<VkFence>				m_fences;
+
+	VkSwapchainCreateInfoKHR			m_swapchainConfig;
+
+	const size_t						m_frameCount;
+	size_t								m_frameNdx;
+
+	const size_t						m_maxOutOfDateCount;
+	size_t								m_outOfDateCount;
+};
+
+SwapchainCounterTestInstance::SwapchainCounterTestInstance (Context& context)
+	: TestInstance				(context)
+	, m_vkp						(context.getPlatformInterface())
+	, m_instance				(createInstance(context))
+	, m_vki						(m_instance.getDriver())
+	, m_physicalDevice			(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
+	, m_planeIndex				(0)
+	, m_display					(getDisplayAndDisplayPlane(m_vki, m_physicalDevice, &m_planeIndex))
+	, m_surface					(createSurface(m_vki, m_instance, m_physicalDevice, m_display, m_planeIndex))
+
+	, m_queueFamilyIndex		(chooseQueueFamilyIndex(m_vki, m_physicalDevice, m_surface))
+	, m_deviceExtensions		(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+	, m_device					(createDevice(m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, context.getTestContext().getCommandLine().isValidationEnabled()))
+	, m_vkd						(m_vkp, m_instance, *m_device)
+	, m_queue					(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+
+	, m_commandPool				(createCommandPool(m_vkd, *m_device, m_queueFamilyIndex))
+	, m_vertexShaderModule		(createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-vert"), 0u))
+	, m_fragmentShaderModule	(createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-frag"), 0u))
+	, m_pipelineLayout			(createPipelineLayout(m_vkd, *m_device))
+
+	, m_surfaceProperties		(wsi::getPhysicalDeviceSurfaceCapabilities2EXT(m_vki, m_physicalDevice, m_surface))
+	, m_surfaceFormats			(wsi::getPhysicalDeviceSurfaceFormats(m_vki, m_physicalDevice, m_surface))
+	, m_presentModes			(wsi::getPhysicalDeviceSurfacePresentModes(m_vki, m_physicalDevice, m_surface))
+
+	, m_swapchainConfig			(createSwapchainConfig(m_surface, m_queueFamilyIndex, m_surfaceProperties, m_surfaceFormats, m_presentModes, VK_PRESENT_MODE_FIFO_KHR))
+
+	, m_frameCount				(20u)
+	, m_frameNdx				(0u)
+
+	, m_maxOutOfDateCount		(10u)
+	, m_outOfDateCount			(0u)
+{
+}
+
+SwapchainCounterTestInstance::~SwapchainCounterTestInstance (void)
+{
+	deinitSwapchainResources();
+
+	m_vki.destroySurfaceKHR(m_instance, m_surface, DE_NULL);
+}
+
+void SwapchainCounterTestInstance::initSwapchainResources (void)
+{
+	const deUint32		imageWidth	= m_swapchainConfig.imageExtent.width;
+	const deUint32		imageHeight	= m_swapchainConfig.imageExtent.height;
+	const VkFormat		imageFormat	= m_swapchainConfig.imageFormat;
+
+	m_swapchain			= createSwapchainKHR(m_vkd, *m_device, &m_swapchainConfig);
+	m_swapchainImages	= wsi::getSwapchainImages(m_vkd, *m_device, *m_swapchain);
+
+	m_renderPass		= makeRenderPass(m_vkd, *m_device, imageFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
+	m_pipeline			= createPipeline(m_vkd, *m_device, *m_renderPass, *m_pipelineLayout, *m_vertexShaderModule, *m_fragmentShaderModule, imageWidth, imageHeight);
+
+	const size_t swapchainImagesCount	= m_swapchainImages.size();
+	const size_t fenceCount				= swapchainImagesCount * 2;
+
+	m_swapchainImageViews	= std::vector<VkImageView>(swapchainImagesCount, (VkImageView)0);
+	m_framebuffers			= std::vector<VkFramebuffer>(swapchainImagesCount, (VkFramebuffer)0);
+	m_acquireSemaphores		= std::vector<VkSemaphore>(swapchainImagesCount+1, (VkSemaphore)0);
+	m_renderSemaphores		= std::vector<VkSemaphore>(swapchainImagesCount+1, (VkSemaphore)0);
+
+	m_fences				= std::vector<VkFence>(fenceCount, (VkFence)0);
+	m_commandBuffers		= std::vector<VkCommandBuffer>(fenceCount, (VkCommandBuffer)0);
+
+	initImageViews(m_vkd, *m_device, m_swapchainImages, imageFormat, m_swapchainImageViews);
+	initFramebuffers(m_vkd, *m_device, *m_renderPass, m_swapchainImageViews, imageWidth, imageHeight, m_framebuffers);
+	initSemaphores(m_vkd, *m_device, m_acquireSemaphores);
+	initSemaphores(m_vkd, *m_device, m_renderSemaphores);
+
+	initFences(m_vkd, *m_device, m_fences);
+}
+
+void SwapchainCounterTestInstance::deinitSwapchainResources (void)
+{
+	VK_CHECK(m_vkd.queueWaitIdle(m_queue));
+
+	deinitSemaphores(m_vkd, *m_device, m_acquireSemaphores);
+	deinitSemaphores(m_vkd, *m_device, m_renderSemaphores);
+	deinitFences(m_vkd, *m_device, m_fences);
+	deinitCommandBuffers(m_vkd, *m_device, *m_commandPool, m_commandBuffers);
+	deinitFramebuffers(m_vkd, *m_device, m_framebuffers);
+	deinitImageViews(m_vkd, *m_device, m_swapchainImageViews);
+
+	m_swapchainImages.clear();
+
+	m_swapchain		= Move<VkSwapchainKHR>();
+	m_renderPass	= Move<VkRenderPass>();
+	m_pipeline		= Move<VkPipeline>();
+}
+
+void SwapchainCounterTestInstance::render (void)
+{
+	const deUint64		foreverNs		= ~0x0ull;
+	VkCommandBuffer&	commandBuffer	= m_commandBuffers[m_frameNdx % m_commandBuffers.size()];
+	const VkFence		fence			= m_fences[m_frameNdx % m_fences.size()];
+	const deUint32		width			= m_swapchainConfig.imageExtent.width;
+	const deUint32		height			= m_swapchainConfig.imageExtent.height;
+
+	if (m_frameNdx >= m_fences.size())
+		VK_CHECK(m_vkd.waitForFences(*m_device, 1u, &fence, VK_TRUE, foreverNs));
+	VK_CHECK(m_vkd.resetFences(*m_device, 1u, &fence));
+
+	VkSemaphore currentAcquireSemaphore	= m_acquireSemaphores[m_frameNdx % m_acquireSemaphores.size()];
+	VkSemaphore currentRenderSemaphore	= m_renderSemaphores[m_frameNdx % m_renderSemaphores.size()];
+
+	// Acquire next image
+	deUint32 imageIndex;
+	VK_CHECK(m_vkd.acquireNextImageKHR(*m_device, *m_swapchain, foreverNs, currentAcquireSemaphore, (VkFence)0, &imageIndex));
+
+	// Create command buffer
+	commandBuffer = createCommandBuffer(m_vkd, *m_device, *m_commandPool, *m_renderPass, m_swapchainImages[imageIndex],
+										m_framebuffers[imageIndex], *m_pipeline, width, height).disown();
+
+	// Submit command buffer
+	{
+		const VkPipelineStageFlags	dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+		const VkSubmitInfo			submitInfo =
+		{
+			VK_STRUCTURE_TYPE_SUBMIT_INFO,
+			DE_NULL,
+			1u,
+			&currentAcquireSemaphore,
+			&dstStageMask,
+			1u,
+			&commandBuffer,
+			1u,
+			&currentRenderSemaphore
+		};
+
+		VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submitInfo, fence));
+	}
+
+	VkResult result;
+	const VkPresentInfoKHR presentInfo =
+	{
+		VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+		DE_NULL,
+		1u,
+		&currentRenderSemaphore,
+		1u,
+		&*m_swapchain,
+		&imageIndex,
+		&result
+	};
+
+	VK_CHECK_WSI(m_vkd.queuePresentKHR(m_queue, &presentInfo));
+	VK_CHECK_WSI(result);
+
+	// verify counter on last frame - we know that we must have presented as meny frames
+	// as we rendered minus the number of images in swapchain - that may not have been presented yet
+	if (m_frameNdx >= m_frameCount)
+	{
+		deUint64 counter = 0;
+		m_vkd.getSwapchainCounterEXT(*m_device, *m_swapchain, VK_SURFACE_COUNTER_VBLANK_EXT, &counter);
+		if ((counter < (m_frameCount - m_swapchainImages.size())) || (counter > m_frameCount))
+		{
+			deinitSwapchainResources();
+			m_resultCollector.fail("Invalid surface counter value");
+		}
+	}
+}
+
+tcu::TestStatus SwapchainCounterTestInstance::iterate (void)
+{
+	try
+	{
+		// Initialize swapchain specific resources
+		if (m_frameNdx == 0)
+			initSwapchainResources();
+
+		// Render frame
+		render();
+	}
+	catch (const Error& error)
+	{
+		if (error.getError() == VK_ERROR_OUT_OF_DATE_KHR)
+		{
+			if (m_outOfDateCount < m_maxOutOfDateCount)
+			{
+				m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx
+					<< ": Swapchain out of date. Recreating resources." << TestLog::EndMessage;
+				deinitSwapchainResources();
+				m_outOfDateCount++;
+				m_frameNdx = 0;
+
+				return tcu::TestStatus::incomplete();
+			}
+
+			m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx
+				<< ": Swapchain out of date." << TestLog::EndMessage;
+			return tcu::TestStatus::fail("Received too many VK_ERROR_OUT_OF_DATE_KHR errors.");
+		}
+
+		deinitSwapchainResources();
+		return tcu::TestStatus::fail(error.what());
+	}
+
+	m_frameNdx++;
+	if (m_frameNdx < m_frameCount)
+		return tcu::TestStatus::incomplete();
+
+	deinitSwapchainResources();
+	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
+}
+
+class SwapchainCounterTestCase : public TestCase
+{
+public:
+
+	SwapchainCounterTestCase(tcu::TestContext& context, const char* name);
+	~SwapchainCounterTestCase() = default;
+
+	void					initPrograms(SourceCollections& programCollection) const;
+	virtual TestInstance*	createInstance(Context& context) const;
+	virtual void			checkSupport(Context& context) const;
+};
+
+SwapchainCounterTestCase::SwapchainCounterTestCase(tcu::TestContext& context, const char* name)
+	: vkt::TestCase(context, name, name)
+{
+}
+
+void SwapchainCounterTestCase::initPrograms(SourceCollections& dst) const
+{
+	dst.glslSources.add("quad-vert") << glu::VertexSource(
+		"#version 450\n"
+		"out gl_PerVertex {\n"
+		"    vec4 gl_Position;\n"
+		"};\n"
+		"highp float;\n"
+		"void main (void) {\n"
+		"    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
+		"                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
+		"}\n");
+	dst.glslSources.add("quad-frag") << glu::FragmentSource(
+		"#version 450\n"
+		"layout(location = 0) out highp vec4 o_color;\n"
+		"void main (void)\n"
+		"{\n"
+		"    o_color = vec4(1.0, 0.5, 0.0, 1.0);\n"
+		"}\n");
+}
+
+TestInstance* SwapchainCounterTestCase::createInstance(Context& context) const
+{
+	return new SwapchainCounterTestInstance(context);
+}
+
+void SwapchainCounterTestCase::checkSupport(Context& context) const
+{
+	context.requireInstanceFunctionality("VK_KHR_display");
+	context.requireDeviceFunctionality("VK_EXT_display_control");
+}
+
+void getDisplays(Context& context, std::vector<VkDisplayKHR>& availableDisplays)
+{
+	// get number of displays
+	deUint32					countReported		= 0u;
+	VkPhysicalDevice			physicalDevice		= context.getPhysicalDevice();
+	const InstanceInterface&	vki					= context.getInstanceInterface();
+
+	VkResult result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countReported, DE_NULL);
+	if (result != VK_SUCCESS)
+		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");
+
+	if (countReported == 0)
+		TCU_THROW(NotSupportedError, "No displays available");
+
+	// get display properties
+	std::vector<VkDisplayPropertiesKHR> displaysProperties(countReported);
+	result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countReported, &displaysProperties[0]);
+
+	if (result != VK_SUCCESS)
+		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");
+
+	availableDisplays.clear();
+	for (const auto& dp : displaysProperties)
+		availableDisplays.push_back(dp.display);
+}
+
+tcu::TestStatus testDisplayPowerControl(Context& context)
+{
+	// make sure VK_EXT_display_control is available
+	context.requireDeviceFunctionality("VK_EXT_display_control");
+
+	// get all connected displays
+	std::vector<VkDisplayKHR> availableDisplays;
+	getDisplays(context, availableDisplays);
+
+	struct PowerStateData
+	{
+		VkDisplayPowerStateEXT	state;
+		deUint32				waitMs;
+	};
+	vector<PowerStateData> powerStateDataVect =
+	{
+		{ VK_DISPLAY_POWER_STATE_ON_EXT,		1000 },
+		{ VK_DISPLAY_POWER_STATE_SUSPEND_EXT,	1000 },
+		{ VK_DISPLAY_POWER_STATE_OFF_EXT,		1000 },
+		{ VK_DISPLAY_POWER_STATE_ON_EXT,		1000 },
+	};
+
+	// iterate over all displays
+	VkDevice						device	= context.getDevice();
+	const vk::DeviceInterface&		vkd		= context.getDeviceInterface();
+	for (const auto& display : availableDisplays)
+	{
+		// iterate over tested sequence of power states
+		for (const auto& psd : powerStateDataVect)
+		{
+			VkDisplayPowerInfoEXT displayPowerInfo =
+			{
+				VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT,
+				DE_NULL,
+				psd.state
+			};
+
+			VkResult result = vkd.displayPowerControlEXT(device, display, &displayPowerInfo);
+			if (result != VK_SUCCESS)
+				tcu::TestStatus::fail(std::string("vkDisplayPowerControlEXT returned invalid result for ") + de::toString(psd.state));
+
+			deSleep(psd.waitMs);
+		}
+	}
+
+	return tcu::TestStatus::pass("pass");
+}
+
+tcu::TestStatus testDisplayEvent(Context& context)
+{
+	// make sure VK_EXT_display_control is available
+	context.requireDeviceFunctionality("VK_EXT_display_control");
+
+	// get all connected displays
+	std::vector<vk::VkDisplayKHR> availableDisplays;
+	getDisplays(context, availableDisplays);
+
+	VkDevice				device	= context.getDevice();
+	const DeviceInterface&	vkd		= context.getDeviceInterface();
+	std::vector<VkFence>	fences	= std::vector<VkFence>(availableDisplays.size(), (VkFence)0);
+
+	// create fence for each display
+	initFences(vkd, device, fences);
+
+	// iterate over all displays
+	for (size_t i = 0 ; i < availableDisplays.size() ; ++i)
+	{
+		VkDisplayEventInfoEXT displayEventInfo =
+		{
+			VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT,
+			DE_NULL,
+			VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT
+		};
+
+		VkFence&		fence		= fences[i];
+		VkDisplayKHR&	display		= availableDisplays[i];
+		VkResult		result		= vkd.registerDisplayEventEXT(device, display, &displayEventInfo, DE_NULL, &fence);
+		if (result != VK_SUCCESS)
+			tcu::TestStatus::fail(std::string("vkRegisterDisplayEventEXT returned invalid result"));
+	}
+
+	// deinit fence
+	deinitFences (vkd, device, fences);
+
+	return tcu::TestStatus::pass("pass");
+}
+
+tcu::TestStatus testDeviceEvent(Context& context)
+{
+	// make sure VK_EXT_display_control is available
+	context.requireDeviceFunctionality("VK_EXT_display_control");
+
+	VkDevice				device = context.getDevice();
+	const DeviceInterface&	vkd = context.getDeviceInterface();
+	std::vector<VkFence>	fences = std::vector<VkFence>(1, (VkFence)0);
+
+	// create fence
+	initFences(vkd, device, fences);
+
+	vk::VkDeviceEventInfoEXT deviceEventInfo =
+	{
+		VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT,
+		DE_NULL,
+		VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT
+	};
+
+	VkResult result = vkd.registerDeviceEventEXT(device, &deviceEventInfo, DE_NULL, &fences[0]);
+	if (result != VK_SUCCESS)
+		tcu::TestStatus::fail(std::string("vkRegisterDeviceEventEXT returned invalid result"));
+
+	// deinit fence
+	deinitFences(vkd, device, fences);
+
+	return tcu::TestStatus::pass("pass");
+}
+
+} // anonymous
+
+void createDisplayControlTests (tcu::TestCaseGroup* testGroup)
+{
+	testGroup->addChild(new SwapchainCounterTestCase(testGroup->getTestContext(), "swapchain_counter"));
+	addFunctionCase(testGroup, "display_power_control",		"Test display power control",	testDisplayPowerControl);
+	addFunctionCase(testGroup, "register_display_event",	"Test register display event",	testDisplayEvent);
+	addFunctionCase(testGroup, "register_device_event",		"Test register device event",	testDeviceEvent);
+}
+
+} // wsi
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.hpp b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.hpp
new file mode 100644
index 0000000..ac4673d
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTWSIDISPLAYCONTROLTESTS_HPP
+#define _VKTWSIDISPLAYCONTROLTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 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.
+ *
+ *//*!
+ * \brief VK_EXT_display_control tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+#include "vkDefs.hpp"
+
+namespace vkt
+{
+namespace wsi
+{
+
+void createDisplayControlTests (tcu::TestCaseGroup* testGroup);
+
+} // wsi
+} // vkt
+
+#endif // _VKTWSIDISPLAYCONTROLTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp
index 0c6a0f1..e59bef6 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp
@@ -28,6 +28,8 @@
 #include "vkStrUtil.hpp"
 #include "vkPrograms.hpp"
 #include "vkRef.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkWsiUtil.hpp"
 
 #include "tcuDefs.hpp"
 #include "tcuTestLog.hpp"
@@ -40,6 +42,8 @@
 #include <set>
 #include <map>
 #include <limits>
+#include <sstream>
+#include <stdexcept>
 
 namespace vkt
 {
@@ -65,6 +69,7 @@
 	DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,
 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,
 	DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,
+	DISPLAY_TEST_INDEX_SURFACE_COUNTERS,
 	DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,
 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,
 	DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,
@@ -197,7 +202,15 @@
 	tcu::TestStatus				testGetDisplayModePropertiesKHR					(void);
 	tcu::TestStatus				testCreateDisplayModeKHR						(void);
 	tcu::TestStatus				testGetDisplayPlaneCapabilitiesKHR				(void);
-	tcu::TestStatus				testCreateDisplayPlaneSurfaceKHR				(void);
+
+	enum SurfaceTestKind
+	{
+		SURFACE_CREATE = 0,
+		SURFACE_COUNTERS,
+		SURFACE_TEST_KIND_MAX_ENUM
+	};
+
+	tcu::TestStatus				testDisplaySurface								(SurfaceTestKind testKind);
 
 	// VK_KHR_get_display_properties2 extension tests
 	tcu::TestStatus				testGetPhysicalDeviceDisplayProperties2KHR		(void);
@@ -276,7 +289,8 @@
 		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE:						return testGetDisplayModePropertiesKHR();					break;
 		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE:					return testCreateDisplayModeKHR();							break;
 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES:			return testGetDisplayPlaneCapabilitiesKHR();				break;
-		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE:			return testCreateDisplayPlaneSurfaceKHR();					break;
+		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE:			return testDisplaySurface(SURFACE_CREATE);					break;
+		case DISPLAY_TEST_INDEX_SURFACE_COUNTERS:						return testDisplaySurface(SURFACE_COUNTERS);				break;
 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:				return testGetPhysicalDeviceDisplayProperties2KHR();		break;
 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:					return testGetPhysicalDeviceDisplayPlaneProperties2KHR();	break;
 		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:						return testGetDisplayModeProperties2KHR();					break;
@@ -1515,14 +1529,25 @@
 	return tcu::TestStatus::pass("pass");
 }
 
+namespace
+{
+	struct SurfaceCountersError : public std::runtime_error
+	{
+		SurfaceCountersError(const std::string& what_) : std::runtime_error(what_) {}
+	};
+}
+
 /*--------------------------------------------------------------------*//*!
- * \brief Create display plane surface coverage test
+ * \brief Test display surface creation or counters.
+ *
+ * In the counter variant, it needs VK_EXT_display_surface_counter
+ * and checks the available surface counters.
  *
  * Throws an exception on fail.
  *
  * \return tcu::TestStatus::pass on success
  *//*--------------------------------------------------------------------*/
-tcu::TestStatus	DisplayCoverageTestInstance::testCreateDisplayPlaneSurfaceKHR (void)
+tcu::TestStatus	DisplayCoverageTestInstance::testDisplaySurface (SurfaceTestKind testKind)
 {
 	deUint32									planeCountReported	=	0u;
 	deUint32									planeCountTested	=	0u;
@@ -1531,6 +1556,13 @@
 	bool										testPerformed		=	false;
 	DisplayVector								displaysVector;
 	VkResult									result;
+	std::string									surfaceCountersErr;
+
+	DE_ASSERT(testKind >= 0 && testKind < SURFACE_TEST_KIND_MAX_ENUM);
+
+	// Check the needed extension.
+	if (testKind == SURFACE_COUNTERS && (!isInstanceExtensionSupported(m_context.getUsedApiVersion(), m_context.getInstanceExtensions(), "VK_EXT_display_surface_counter")))
+		TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
 
 	// Get displays
 	if (!getDisplays(displaysVector))
@@ -1661,6 +1693,39 @@
 							if (surface == DE_NULL)
 								TCU_FAIL("Invalid surface handle returned");
 
+							if (testKind == SURFACE_COUNTERS)
+							{
+								// Check surface counters.
+								try
+								{
+									const vk::VkSurfaceCapabilities2EXT	capsExt = vk::wsi::getPhysicalDeviceSurfaceCapabilities2EXT	(m_vki, m_physicalDevice, surface);
+									const vk::VkSurfaceCapabilitiesKHR	capsKhr = vk::wsi::getPhysicalDeviceSurfaceCapabilities		(m_vki, m_physicalDevice, surface);
+
+									if (!vk::wsi::sameSurfaceCapabilities(capsKhr, capsExt))
+									{
+										throw SurfaceCountersError("KHR and EXT surface capabilities do not match");
+									}
+
+									for (deUint32 i = 0; i < sizeof(capsExt.supportedSurfaceCounters) * 8; ++i)
+									{
+										deUint32 mask = (1<<i);
+										if (capsExt.supportedSurfaceCounters & mask)
+										{
+											if (mask != static_cast<deUint32>(VK_SURFACE_COUNTER_VBLANK_EXT))
+											{
+												std::ostringstream msg;
+												msg << "Invalid bit set in supportedSurfaceCounters: 0x" << std::hex << mask;
+												throw SurfaceCountersError(msg.str());
+											}
+										}
+									}
+								}
+								catch(const SurfaceCountersError& err)
+								{
+									surfaceCountersErr = err.what();
+								}
+							}
+
 							m_vki.destroySurfaceKHR(	instance,	// VkInstance							instance
 														surface,	// VkSurfaceKHR*						pSurface
 														DE_NULL);	// const VkAllocationCallbacks*			pAllocator
@@ -1676,7 +1741,7 @@
 	if (!testPerformed)
 		TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test");
 
-	return tcu::TestStatus::pass("pass");
+	return ((surfaceCountersErr.empty()) ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail(surfaceCountersErr));
 }
 
 /*--------------------------------------------------------------------*//*!
@@ -2230,6 +2295,7 @@
 	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,					"create_display_mode",					"Create display mode coverage test");
 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,		"get_display_plane_capabilities",		"Display-plane capabilities coverage test");
 	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,			"create_display_plane_surface",			"Create display plane surface coverage test");
+	addTest(group, DISPLAY_TEST_INDEX_SURFACE_COUNTERS,						"surface_counters",						"Display plane surface counters test");
 
 	// VK_KHR_get_display_properties2 extension tests
 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,				"get_display_properties2",				"Display enumeration coverage test using VK_KHR_get_display_properties2");
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp
index ccc02a2..c0ca113 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp
@@ -99,39 +99,6 @@
 	return features;
 }
 
-deUint32 getNumQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice)
-{
-	deUint32	numFamilies		= 0;
-
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
-
-	return numFamilies;
-}
-
-vector<deUint32> getSupportedQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const deUint32		numTotalFamilyIndices	= getNumQueueFamilyIndices(vki, physicalDevice);
-	vector<deUint32>	supportedFamilyIndices;
-
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (vk::wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) == VK_TRUE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
-}
-
 vk::Move<vk::VkDevice> createDeviceWithWsi (const vk::PlatformInterface&		vkp,
 											const vk::VkInstance				instance,
 											const vk::InstanceInterface&		vki,
@@ -728,7 +695,7 @@
 	, m_nativeWindow			(createWindow(*m_nativeDisplay, tcu::nothing<UVec2>()))
 	, m_surface					(vk::wsi::createSurface(m_vki, m_instance, testConfig.wsiType, *m_nativeDisplay, *m_nativeWindow))
 
-	, m_queueFamilyIndex		(chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
+	, m_queueFamilyIndex		(vk::wsi::chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
 	, m_deviceExtensions		(vk::enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
 	, m_device					(createDeviceWithWsi(m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, testConfig.useDisplayTiming, context.getTestContext().getCommandLine().isValidationEnabled()))
 	, m_vkd						(m_vkp, m_instance, *m_device)
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp
index aec9154..75a885e 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp
@@ -101,39 +101,6 @@
 	return features;
 }
 
-deUint32 getNumQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice)
-{
-	deUint32	numFamilies		= 0;
-
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
-
-	return numFamilies;
-}
-
-vector<deUint32> getSupportedQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const deUint32		numTotalFamilyIndices	= getNumQueueFamilyIndices(vki, physicalDevice);
-	vector<deUint32>	supportedFamilyIndices;
-
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (vk::wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
-}
-
 vk::Move<vk::VkDevice> createDeviceWithWsi (const vk::PlatformInterface&		vkp,
 											vk::VkInstance						instance,
 											const vk::InstanceInterface&		vki,
@@ -839,7 +806,7 @@
 	, m_nativeWindow			(createWindow(*m_nativeDisplay, tcu::nothing<UVec2>()))
 	, m_surface					(vk::wsi::createSurface(m_vki, m_instance, testConfig.wsiType, *m_nativeDisplay, *m_nativeWindow))
 
-	, m_queueFamilyIndex		(chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
+	, m_queueFamilyIndex		(vk::wsi::chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
 	, m_deviceExtensions		(vk::enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
 	, m_device					(createDeviceWithWsi(m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, testConfig.useIncrementalPresent, context.getTestContext().getCommandLine().isValidationEnabled()))
 	, m_vkd						(m_vkp, m_instance, *m_device)
@@ -1010,7 +977,7 @@
 			(deUint32)rects.size(),
 			rects.empty() ? DE_NULL : &rects[0]
 		};
-		const vk::VkPresentRegionsKHR	regionInfo	=
+		const vk::VkPresentRegionsKHR regionInfo =
 		{
 			vk::VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR,
 			DE_NULL,
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiSharedPresentableImageTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiSharedPresentableImageTests.cpp
index 48e990b..ea660ab 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiSharedPresentableImageTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiSharedPresentableImageTests.cpp
@@ -108,39 +108,6 @@
 	return features;
 }
 
-deUint32 getNumQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice)
-{
-	deUint32	numFamilies		= 0;
-
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
-
-	return numFamilies;
-}
-
-vector<deUint32> getSupportedQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const deUint32		numTotalFamilyIndices	= getNumQueueFamilyIndices(vki, physicalDevice);
-	vector<deUint32>	supportedFamilyIndices;
-
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (vk::wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
-}
-
 vk::Move<vk::VkDevice> createDeviceWithWsi (const vk::PlatformInterface&		vkp,
 											vk::VkInstance						instance,
 											const vk::InstanceInterface&		vki,
@@ -751,7 +718,7 @@
 	, m_nativeWindow			(createWindow(*m_nativeDisplay, tcu::nothing<UVec2>()))
 	, m_surface					(vk::wsi::createSurface(m_vki, m_instance, testConfig.wsiType, *m_nativeDisplay, *m_nativeWindow))
 
-	, m_queueFamilyIndex		(chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
+	, m_queueFamilyIndex		(vk::wsi::chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
 	, m_deviceExtensions		(vk::enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
 	, m_device					(createDeviceWithWsi(m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, testConfig.useSharedPresentableImage, context.getTestContext().getCommandLine().isValidationEnabled()))
 	, m_vkd						(m_vkp, m_instance, *m_device)
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
index cbcaf76..0fb68d2 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
@@ -182,16 +182,13 @@
 	extensions.push_back(getExtensionName(wsiType));
 
 	vector<string>	instanceExtensions;
-
-	for (vector<string>::const_iterator extensionName = extensions.begin();
-		 extensionName != extensions.end();
-		 ++extensionName)
+	for (const auto& ext : extensions)
 	{
-		if (!context.isInstanceFunctionalitySupported(*extensionName))
-			TCU_THROW(NotSupportedError, (*extensionName + " is not supported").c_str());
+		if (!context.isInstanceFunctionalitySupported(ext))
+			TCU_THROW(NotSupportedError, (ext + " is not supported").c_str());
 
-		if (!isCoreInstanceExtension(version, *extensionName))
-			instanceExtensions.push_back(*extensionName);
+		if (!isCoreInstanceExtension(version, ext))
+			instanceExtensions.push_back(ext);
 	}
 
 	return vkt::createCustomInstanceWithExtensions(context, instanceExtensions, pAllocator);
@@ -283,6 +280,33 @@
 	return tcu::TestStatus::pass("Creating surface succeeded");
 }
 
+tcu::TestStatus querySurfaceCounterTest (Context& context, Type wsiType)
+{
+	const InstanceHelper			instHelper		(context, wsiType);
+	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
+	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const vk::InstanceInterface&	vki				= context.getInstanceInterface();
+	const vk::VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
+
+	if (!isInstanceExtensionSupported(context.getUsedApiVersion(), context.getInstanceExtensions(), "VK_EXT_display_surface_counter"))
+		TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
+
+	const vk::VkSurfaceCapabilities2EXT	capsExt = getPhysicalDeviceSurfaceCapabilities2EXT	(vki, physicalDevice, surface.get());
+	const vk::VkSurfaceCapabilitiesKHR	capsKhr = getPhysicalDeviceSurfaceCapabilities		(vki, physicalDevice, surface.get());
+
+	if (!sameSurfaceCapabilities(capsKhr, capsExt))
+	{
+		return tcu::TestStatus::fail("KHR and EXT surface capabilities do not match");
+	}
+
+	if (capsExt.supportedSurfaceCounters != 0)
+	{
+		return tcu::TestStatus::fail("supportedSurfaceCounters nonzero (" + de::toString(capsExt.supportedSurfaceCounters) + ") for non-display surface");
+	}
+
+	return tcu::TestStatus::pass("Pass");
+}
+
 tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
 {
 	AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
@@ -416,6 +440,39 @@
 	return tcu::TestStatus(results.getResult(), results.getMessage());
 }
 
+tcu::TestStatus queryPresentationSupportTest(Context& context, Type wsiType)
+{
+	tcu::TestLog&					log						= context.getTestContext().getLog();
+	tcu::ResultCollector			results					(log);
+
+	const InstanceHelper			instHelper				(context, wsiType);
+	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
+	const Unique<VkSurfaceKHR>		surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
+
+	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
+	{
+		const VkPhysicalDevice		physicalDevice		= physicalDevices[deviceNdx];
+		const deUint32				numQueueFamilies	= getNumQueueFamilies(instHelper.vki, physicalDevice);
+
+		for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
+		{
+			VkBool32	isPresentationSupported	= getPhysicalDevicePresentationSupport(instHelper.vki, physicalDevice, queueFamilyNdx, wsiType, *native.display);
+			VkBool32	isSurfaceSupported		= getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
+
+			log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": presentation "
+									<< (isPresentationSupported == VK_FALSE ? "NOT " : "") << "supported. Surface "
+									<< (isSurfaceSupported == VK_FALSE ? "NOT " : "") << "supported."
+				<< TestLog::EndMessage;
+
+			if (isPresentationSupported != isSurfaceSupported)
+				results.fail("Presentation support is different from surface support");
+		}
+	}
+
+	return tcu::TestStatus(results.getResult(), results.getMessage());
+}
+
 bool isSupportedByAnyQueue (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
 {
 	const deUint32	numQueueFamilies	= getNumQueueFamilies(vki, physicalDevice);
@@ -1242,9 +1299,11 @@
 	addFunctionCase(testGroup, "create_custom_allocator",				"Create surface with custom allocator",						createSurfaceCustomAllocatorTest,			wsiType);
 	addFunctionCase(testGroup, "create_simulate_oom",					"Create surface with simulating OOM",						createSurfaceSimulateOOMTest,				wsiType);
 	addFunctionCase(testGroup, "query_support",							"Query surface support",									querySurfaceSupportTest,					wsiType);
+	addFunctionCase(testGroup, "query_presentation_support",			"Query native presentation support",						queryPresentationSupportTest,				wsiType);
 	addFunctionCase(testGroup, "query_capabilities",					"Query surface capabilities",								querySurfaceCapabilitiesTest,				wsiType);
 	addFunctionCase(testGroup, "query_capabilities2",					"Query extended surface capabilities",						querySurfaceCapabilities2Test,				wsiType);
 	addFunctionCase(testGroup, "query_protected_capabilities",			"Query protected surface capabilities",						querySurfaceProtectedCapabilitiesTest,		wsiType);
+	addFunctionCase(testGroup, "query_surface_counters",				"Query and check available surface counters",				querySurfaceCounterTest,					wsiType);
 	addFunctionCase(testGroup, "query_formats",							"Query surface formats",									querySurfaceFormatsTest,					wsiType);
 	addFunctionCase(testGroup, "query_formats2",						"Query extended surface formats",							querySurfaceFormats2Test,					wsiType);
 	addFunctionCase(testGroup, "query_present_modes",					"Query surface present modes",								querySurfacePresentModesTest,				wsiType);
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
index 46f7558..0ea042c 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
@@ -42,7 +42,6 @@
 #include "vkAllocationCallbackUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkObjUtil.hpp"
-#include "vkBarrierUtil.hpp"
 
 #include "tcuCommandLine.hpp"
 #include "tcuTestLog.hpp"
@@ -132,22 +131,28 @@
 									const InstanceInterface&		vki,
 									VkPhysicalDevice				physicalDevice,
 									const Extensions&				supportedExtensions,
-									const deUint32					queueFamilyIndex,
+									const vector<deUint32>&			queueFamilyIndices,
 									bool							validationEnabled,
 									const VkAllocationCallbacks*	pAllocator = DE_NULL)
 {
 	const float						queuePriorities[]	= { 1.0f };
-	const VkDeviceQueueCreateInfo	queueInfos[]		=
+
+	vector<VkDeviceQueueCreateInfo>	queueInfos;
+	for (const auto familyIndex : queueFamilyIndices)
 	{
+		const VkDeviceQueueCreateInfo info =
 		{
 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
-			DE_NULL,
+			nullptr,
 			(VkDeviceQueueCreateFlags)0,
-			queueFamilyIndex,
+			familyIndex,
 			DE_LENGTH_OF_ARRAY(queuePriorities),
-			&queuePriorities[0]
-		}
-	};
+			&queuePriorities[0],
+		};
+
+		queueInfos.push_back(info);
+	}
+
 	const VkPhysicalDeviceFeatures	features		= getDeviceFeaturesForWsi();
 	const char* const				extensions[]	= { "VK_KHR_swapchain" };
 
@@ -156,8 +161,8 @@
 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
 		DE_NULL,
 		(VkDeviceCreateFlags)0,
-		DE_LENGTH_OF_ARRAY(queueInfos),
-		&queueInfos[0],
+		static_cast<deUint32>(queueInfos.size()),
+		queueInfos.data(),
 		0u,									// enabledLayerCount
 		DE_NULL,							// ppEnabledLayerNames
 		DE_LENGTH_OF_ARRAY(extensions),		// enabledExtensionCount
@@ -174,32 +179,16 @@
 	return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
 }
 
-vector<deUint32> getSupportedQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
+Move<VkDevice> createDeviceWithWsi (const PlatformInterface&		vkp,
+									VkInstance						instance,
+									const InstanceInterface&		vki,
+									VkPhysicalDevice				physicalDevice,
+									const Extensions&				supportedExtensions,
+									const deUint32					queueFamilyIndex,
+									bool							validationEnabled,
+									const VkAllocationCallbacks*	pAllocator = DE_NULL)
 {
-	deUint32 numTotalFamilyIndices;
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, DE_NULL);
-
-	vector<VkQueueFamilyProperties> queueFamilyProperties(numTotalFamilyIndices);
-	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, &queueFamilyProperties[0]);
-
-	vector<deUint32>	supportedFamilyIndices;
-	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
-	{
-		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
-			supportedFamilyIndices.push_back(queueFamilyNdx);
-	}
-
-	return supportedFamilyIndices;
-}
-
-deUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
-{
-	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
-
-	if (supportedFamilyIndices.empty())
-		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
-
-	return supportedFamilyIndices[0];
+	return createDeviceWithWsi(vkp, instance, vki, physicalDevice, supportedExtensions, vector<deUint32>(1u, queueFamilyIndex), validationEnabled, pAllocator);
 }
 
 struct InstanceHelper
@@ -242,7 +231,7 @@
 	DeviceHelper (Context&						context,
 				  const InstanceInterface&		vki,
 				  VkInstance					instance,
-				  VkSurfaceKHR					surface,
+				  const vector<VkSurfaceKHR>&	surface,
 				  const VkAllocationCallbacks*	pAllocator = DE_NULL)
 		: physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
 		, queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, surface))
@@ -258,6 +247,54 @@
 		, queue				(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
 	{
 	}
+
+	// Single-surface shortcut.
+	DeviceHelper (Context&						context,
+				  const InstanceInterface&		vki,
+				  VkInstance					instance,
+				  VkSurfaceKHR					surface,
+				  const VkAllocationCallbacks*	pAllocator = DE_NULL)
+		: DeviceHelper(context, vki, instance, vector<VkSurfaceKHR>(1u, surface), pAllocator)
+	{
+	}
+};
+
+// Similar to the one above with no queues and multiple queue families.
+struct MultiQueueDeviceHelper
+{
+	const VkPhysicalDevice	physicalDevice;
+	const vector<deUint32>	queueFamilyIndices;
+	const Unique<VkDevice>	device;
+	const DeviceDriver		vkd;
+
+	MultiQueueDeviceHelper (Context&						context,
+							const InstanceInterface&		vki,
+							VkInstance						instance,
+							const vector<VkSurfaceKHR>&		surface,
+							const VkAllocationCallbacks*	pAllocator = DE_NULL)
+		: physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
+		, queueFamilyIndices(getCompatibleQueueFamilyIndices(vki, physicalDevice, surface))
+		, device			(createDeviceWithWsi(context.getPlatformInterface(),
+												 context.getInstance(),
+												 vki,
+												 physicalDevice,
+												 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
+												 queueFamilyIndices,
+												 context.getTestContext().getCommandLine().isValidationEnabled(),
+												 pAllocator))
+		, vkd				(context.getPlatformInterface(), context.getInstance(), *device)
+	{
+	}
+
+	// Single-surface shortcut.
+	MultiQueueDeviceHelper (Context&						context,
+							const InstanceInterface&		vki,
+							VkInstance						instance,
+							VkSurfaceKHR					surface,
+							const VkAllocationCallbacks*	pAllocator = DE_NULL)
+		: MultiQueueDeviceHelper(context, vki, instance, vector<VkSurfaceKHR>(1u, surface), pAllocator)
+	{
+	}
 };
 
 MovePtr<Display> createDisplay (const vk::Platform&	platform,
@@ -296,18 +333,42 @@
 	}
 }
 
-struct NativeObjects
+class NativeObjects
 {
-	const UniquePtr<Display>	display;
-	const UniquePtr<Window>		window;
+private:
+	UniquePtr<Display>		display;
+	vector<MovePtr<Window>>	windows;
 
+public:
 	NativeObjects (Context&				context,
 				   const Extensions&	supportedExtensions,
 				   Type					wsiType,
+				   size_t				windowCount = 1u,
 				   const Maybe<UVec2>&	initialWindowSize = tcu::nothing<UVec2>())
 		: display	(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
-		, window	(createWindow(*display, initialWindowSize))
-	{}
+	{
+		DE_ASSERT(windowCount > 0u);
+		for (size_t i = 0; i < windowCount; ++i)
+			windows.emplace_back(createWindow(*display, initialWindowSize));
+	}
+
+	NativeObjects (NativeObjects&& other)
+		: display	(other.display.move())
+		, windows	()
+	{
+		windows.swap(other.windows);
+	}
+
+	Display&	getDisplay	() const
+	{
+		return *display;
+	}
+
+	Window&		getWindow	(size_t index = 0u) const
+	{
+		DE_ASSERT(index < windows.size());
+		return *windows[index];
+	}
 };
 
 enum TestDimension
@@ -488,8 +549,11 @@
 
 		case TEST_DIMENSION_IMAGE_SHARING_MODE:
 		{
+#if 0
+			// Skipping since this matches the base parameters.
 			cases.push_back(baseParameters);
 			cases.back().imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+#endif
 
 			cases.push_back(baseParameters);
 			cases.back().imageSharingMode = VK_SHARING_MODE_CONCURRENT;
@@ -583,8 +647,8 @@
 	tcu::TestLog&							log			= context.getTestContext().getLog();
 	const InstanceHelper					instHelper	(context, params.wsiType);
 	const NativeObjects						native		(context, instHelper.supportedExtensions, params.wsiType);
-	const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki, instHelper.instance, params.wsiType, *native.display, *native.window));
-	const DeviceHelper						devHelper	(context, instHelper.vki, instHelper.instance, *surface);
+	const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki, instHelper.instance, params.wsiType, native.getDisplay(), native.getWindow()));
+	const MultiQueueDeviceHelper			devHelper	(context, instHelper.vki, instHelper.instance, *surface);
 	const vector<VkSwapchainCreateInfoKHR>	cases		(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
 	const VkSurfaceCapabilitiesKHR			capabilities(getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface));
 
@@ -595,9 +659,22 @@
 
 		VkSwapchainCreateInfoKHR	curParams	= cases[caseNdx];
 
+		if (curParams.imageSharingMode == VK_SHARING_MODE_CONCURRENT)
+		{
+			const deUint32 numFamilies = static_cast<deUint32>(devHelper.queueFamilyIndices.size());
+			if (numFamilies < 2u)
+				TCU_THROW(NotSupportedError, "Only " + de::toString(numFamilies) + " queue families available for VK_SHARING_MODE_CONCURRENT");
+			curParams.queueFamilyIndexCount	= numFamilies;
+		}
+		else
+		{
+			// Take only the first queue.
+			if (devHelper.queueFamilyIndices.empty())
+				TCU_THROW(NotSupportedError, "No queue families compatible with the given surface");
+			curParams.queueFamilyIndexCount	= 1u;
+		}
+		curParams.pQueueFamilyIndices	= devHelper.queueFamilyIndices.data();
 		curParams.surface				= *surface;
-		curParams.queueFamilyIndexCount	= 1u;
-		curParams.pQueueFamilyIndices	= &devHelper.queueFamilyIndex;
 
 		log << TestLog::Message << subcase.str() << curParams << TestLog::EndMessage;
 
@@ -681,8 +758,8 @@
 		const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki,
 																			instHelper.instance,
 																			params.wsiType,
-																			*native.display,
-																			*native.window,
+																			native.getDisplay(),
+																			native.getWindow(),
 																			failingAllocator.getCallbacks()));
 		const DeviceHelper						devHelper	(context, instHelper.vki, instHelper.instance, *surface, failingAllocator.getCallbacks());
 		const vector<VkSwapchainCreateInfoKHR>	allCases	(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
@@ -747,12 +824,12 @@
 {
 	const tcu::UVec2			desiredSize			(256, 256);
 	const InstanceHelper		instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
-	const NativeObjects			native				(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
+	const NativeObjects			native				(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
 	const Unique<VkSurfaceKHR>	surface				(createSurface(instHelper.vki,
 																   instHelper.instance,
 																   wsiType,
-																   *native.display,
-																   *native.window));
+																   native.getDisplay(),
+																   native.getWindow()));
 	const DeviceHelper			devHelper			(context, instHelper.vki, instHelper.instance, *surface);
 	const Extensions&			deviceExtensions	= enumerateDeviceExtensionProperties(instHelper.vki, devHelper.physicalDevice, DE_NULL);
 
@@ -937,500 +1014,6 @@
 	return parameters;
 }
 
-typedef de::SharedPtr<Unique<VkImageView> >		ImageViewSp;
-typedef de::SharedPtr<Unique<VkFramebuffer> >	FramebufferSp;
-
-class TriangleRenderer
-{
-public:
-									TriangleRenderer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 Allocator&					allocator,
-														 const BinaryCollection&	binaryRegistry,
-														 bool						explicitLayoutTransitions,
-														 const vector<VkImage>		swapchainImages,
-														 const vector<VkImage>		aliasImages,
-														 const VkFormat				framebufferFormat,
-														 const UVec2&				renderSize);
-									~TriangleRenderer	(void);
-
-	void							recordFrame			(VkCommandBuffer			cmdBuffer,
-														 deUint32					imageNdx,
-														 deUint32					frameNdx) const;
-
-	void							recordDeviceGroupFrame (VkCommandBuffer			cmdBuffer,
-															deUint32				imageNdx,
-															deUint32				firstDeviceID,
-															deUint32				secondDeviceID,
-															deUint32				devicesCount,
-															deUint32				frameNdx) const;
-
-	static void						getPrograms			(SourceCollections& dst);
-
-private:
-	static Move<VkRenderPass>		createRenderPass	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkFormat				colorAttachmentFormat,
-														 const bool					explicitLayoutTransitions);
-	static Move<VkPipelineLayout>	createPipelineLayout(const DeviceInterface&		vkd,
-														 VkDevice					device);
-	static Move<VkPipeline>			createPipeline		(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkPipelineLayout		pipelineLayout,
-														 const BinaryCollection&	binaryCollection,
-														 const UVec2&				renderSize);
-
-	static Move<VkImageView>		createAttachmentView(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkImage				image,
-														 const VkFormat				format);
-	static Move<VkFramebuffer>		createFramebuffer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkImageView			colorAttachment,
-														 const UVec2&				renderSize);
-
-	static Move<VkBuffer>			createBuffer		(const DeviceInterface&		vkd,
-														 VkDevice					device,
-														 VkDeviceSize				size,
-														 VkBufferUsageFlags			usage);
-
-	const DeviceInterface&			m_vkd;
-
-	const bool						m_explicitLayoutTransitions;
-	const vector<VkImage>			m_swapchainImages;
-	const vector<VkImage>			m_aliasImages;
-	const tcu::UVec2				m_renderSize;
-
-	const Unique<VkRenderPass>		m_renderPass;
-	const Unique<VkPipelineLayout>	m_pipelineLayout;
-	const Unique<VkPipeline>		m_pipeline;
-
-	const Unique<VkBuffer>			m_vertexBuffer;
-	const UniquePtr<Allocation>		m_vertexBufferMemory;
-
-	vector<ImageViewSp>				m_attachmentViews;
-	mutable vector<VkImageLayout>	m_attachmentLayouts;
-	vector<FramebufferSp>			m_framebuffers;
-};
-
-Move<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface&	vkd,
-													   const VkDevice			device,
-													   const VkFormat			colorAttachmentFormat,
-													   const bool				explicitLayoutTransitions)
-{
-	const VkAttachmentDescription	colorAttDesc		=
-	{
-		(VkAttachmentDescriptionFlags)0,
-		colorAttachmentFormat,
-		VK_SAMPLE_COUNT_1_BIT,
-		VK_ATTACHMENT_LOAD_OP_CLEAR,
-		VK_ATTACHMENT_STORE_OP_STORE,
-		VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-		VK_ATTACHMENT_STORE_OP_DONT_CARE,
-		(explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-		(explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-	};
-	const VkAttachmentReference		colorAttRef			=
-	{
-		0u,
-		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-	};
-	const VkSubpassDescription		subpassDesc			=
-	{
-		(VkSubpassDescriptionFlags)0u,
-		VK_PIPELINE_BIND_POINT_GRAPHICS,
-		0u,							// inputAttachmentCount
-		DE_NULL,					// pInputAttachments
-		1u,							// colorAttachmentCount
-		&colorAttRef,				// pColorAttachments
-		DE_NULL,					// pResolveAttachments
-		DE_NULL,					// depthStencilAttachment
-		0u,							// preserveAttachmentCount
-		DE_NULL,					// pPreserveAttachments
-	};
-	const VkSubpassDependency		dependencies[]		=
-	{
-		{
-			VK_SUBPASS_EXTERNAL,	// srcSubpass
-			0u,						// dstSubpass
-			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-			VK_ACCESS_MEMORY_READ_BIT,
-			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
-			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
-			VK_DEPENDENCY_BY_REGION_BIT
-		},
-		{
-			0u,						// srcSubpass
-			VK_SUBPASS_EXTERNAL,	// dstSubpass
-			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
-			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
-			VK_ACCESS_MEMORY_READ_BIT,
-			VK_DEPENDENCY_BY_REGION_BIT
-		},
-	};
-	const VkRenderPassCreateInfo	renderPassParams	=
-	{
-		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-		DE_NULL,
-		(VkRenderPassCreateFlags)0,
-		1u,
-		&colorAttDesc,
-		1u,
-		&subpassDesc,
-		DE_LENGTH_OF_ARRAY(dependencies),
-		dependencies,
-	};
-
-	return vk::createRenderPass(vkd, device, &renderPassParams);
-}
-
-Move<VkPipelineLayout> TriangleRenderer::createPipelineLayout (const DeviceInterface&	vkd,
-															   const VkDevice			device)
-{
-	const VkPushConstantRange						pushConstantRange		=
-	{
-		VK_SHADER_STAGE_VERTEX_BIT,
-		0u,											// offset
-		(deUint32)sizeof(deUint32),					// size
-	};
-	const VkPipelineLayoutCreateInfo				pipelineLayoutParams	=
-	{
-		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-		DE_NULL,
-		(vk::VkPipelineLayoutCreateFlags)0,
-		0u,											// setLayoutCount
-		DE_NULL,									// pSetLayouts
-		1u,
-		&pushConstantRange,
-	};
-
-	return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
-}
-
-Move<VkPipeline> TriangleRenderer::createPipeline (const DeviceInterface&	vkd,
-												   const VkDevice			device,
-												   const VkRenderPass		renderPass,
-												   const VkPipelineLayout	pipelineLayout,
-												   const BinaryCollection&	binaryCollection,
-												   const UVec2&				renderSize)
-{
-	// \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
-	//		 and can be deleted immediately following that call.
-	const Unique<VkShaderModule>					vertShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
-	const Unique<VkShaderModule>					fragShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
-	const std::vector<VkViewport>					viewports				(1, makeViewport(renderSize));
-	const std::vector<VkRect2D>						scissors				(1, makeRect2D(renderSize));
-
-	return vk::makeGraphicsPipeline(vkd,				// const DeviceInterface&            vk
-									device,				// const VkDevice                    device
-									pipelineLayout,		// const VkPipelineLayout            pipelineLayout
-									*vertShaderModule,	// const VkShaderModule              vertexShaderModule
-									DE_NULL,			// const VkShaderModule              tessellationControlShaderModule
-									DE_NULL,			// const VkShaderModule              tessellationEvalShaderModule
-									DE_NULL,			// const VkShaderModule              geometryShaderModule
-									*fragShaderModule,	// const VkShaderModule              fragmentShaderModule
-									renderPass,			// const VkRenderPass                renderPass
-									viewports,			// const std::vector<VkViewport>&    viewports
-									scissors);			// const std::vector<VkRect2D>&      scissors
-}
-
-Move<VkImageView> TriangleRenderer::createAttachmentView (const DeviceInterface&	vkd,
-														  const VkDevice			device,
-														  const VkImage				image,
-														  const VkFormat			format)
-{
-	const VkImageViewCreateInfo		viewParams	=
-	{
-		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-		DE_NULL,
-		(VkImageViewCreateFlags)0,
-		image,
-		VK_IMAGE_VIEW_TYPE_2D,
-		format,
-		vk::makeComponentMappingRGBA(),
-		{
-			VK_IMAGE_ASPECT_COLOR_BIT,
-			0u,						// baseMipLevel
-			1u,						// levelCount
-			0u,						// baseArrayLayer
-			1u,						// layerCount
-		},
-	};
-
-	return vk::createImageView(vkd, device, &viewParams);
-}
-
-Move<VkFramebuffer> TriangleRenderer::createFramebuffer	(const DeviceInterface&		vkd,
-														 const VkDevice				device,
-														 const VkRenderPass			renderPass,
-														 const VkImageView			colorAttachment,
-														 const UVec2&				renderSize)
-{
-	const VkFramebufferCreateInfo	framebufferParams	=
-	{
-		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-		DE_NULL,
-		(VkFramebufferCreateFlags)0,
-		renderPass,
-		1u,
-		&colorAttachment,
-		renderSize.x(),
-		renderSize.y(),
-		1u,							// layers
-	};
-
-	return vk::createFramebuffer(vkd, device, &framebufferParams);
-}
-
-Move<VkBuffer> TriangleRenderer::createBuffer (const DeviceInterface&	vkd,
-											   VkDevice					device,
-											   VkDeviceSize				size,
-											   VkBufferUsageFlags		usage)
-{
-	const VkBufferCreateInfo	bufferParams	=
-	{
-		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
-		DE_NULL,
-		(VkBufferCreateFlags)0,
-		size,
-		usage,
-		VK_SHARING_MODE_EXCLUSIVE,
-		0,
-		DE_NULL
-	};
-
-	return vk::createBuffer(vkd, device, &bufferParams);
-}
-
-TriangleRenderer::TriangleRenderer (const DeviceInterface&	vkd,
-									const VkDevice			device,
-									Allocator&				allocator,
-									const BinaryCollection&	binaryRegistry,
-									bool					explicitLayoutTransitions,
-									const vector<VkImage>	swapchainImages,
-									const vector<VkImage>	aliasImages,
-									const VkFormat			framebufferFormat,
-									const UVec2&			renderSize)
-	: m_vkd							(vkd)
-	, m_explicitLayoutTransitions	(explicitLayoutTransitions)
-	, m_swapchainImages				(swapchainImages)
-	, m_aliasImages					(aliasImages)
-	, m_renderSize					(renderSize)
-	, m_renderPass					(createRenderPass(vkd, device, framebufferFormat, m_explicitLayoutTransitions))
-	, m_pipelineLayout				(createPipelineLayout(vkd, device))
-	, m_pipeline					(createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
-	, m_vertexBuffer				(createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
-	, m_vertexBufferMemory			(allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
-									 MemoryRequirement::HostVisible))
-{
-	m_attachmentViews.resize(swapchainImages.size());
-	m_attachmentLayouts.resize(swapchainImages.size());
-	m_framebuffers.resize(swapchainImages.size());
-
-	for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
-	{
-		m_attachmentViews[imageNdx]		= ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
-		m_attachmentLayouts[imageNdx]	= VK_IMAGE_LAYOUT_UNDEFINED;
-		m_framebuffers[imageNdx]		= FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
-	}
-
-	VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
-
-	{
-		const VkMappedMemoryRange	memRange	=
-		{
-			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
-			DE_NULL,
-			m_vertexBufferMemory->getMemory(),
-			m_vertexBufferMemory->getOffset(),
-			VK_WHOLE_SIZE
-		};
-		const tcu::Vec4				vertices[]	=
-		{
-			tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
-			tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
-			tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
-		};
-		DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
-
-		deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
-		VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
-	}
-}
-
-TriangleRenderer::~TriangleRenderer (void)
-{
-}
-
-void TriangleRenderer::recordFrame (VkCommandBuffer	cmdBuffer,
-									deUint32		imageNdx,
-									deUint32		frameNdx) const
-{
-	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
-
-	beginCommandBuffer(m_vkd, cmdBuffer, 0u);
-
-	if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
-	{
-		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
-		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-																		 m_aliasImages[imageNdx], range);
-		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-	}
-
-	beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
-
-	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
-
-	{
-		const VkDeviceSize bindingOffset = 0;
-		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
-	}
-
-	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
-	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
-	endRenderPass(m_vkd, cmdBuffer);
-
-	if (m_explicitLayoutTransitions)
-	{
-		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
-		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
-																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-																		 m_aliasImages[imageNdx], range);
-		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
-	}
-
-	endCommandBuffer(m_vkd, cmdBuffer);
-}
-
-void TriangleRenderer::recordDeviceGroupFrame (VkCommandBuffer	cmdBuffer,
-											   deUint32			firstDeviceID,
-											   deUint32			secondDeviceID,
-											   deUint32			devicesCount,
-											   deUint32			imageNdx,
-											   deUint32			frameNdx) const
-{
-	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
-
-	beginCommandBuffer(m_vkd, cmdBuffer, 0u);
-
-	if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
-	{
-		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
-		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-																		 m_aliasImages[imageNdx], range);
-		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-	}
-
-	// begin renderpass
-	{
-		const VkClearValue clearValue = makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
-
-		VkRect2D zeroRect = { { 0, 0, },{ 0, 0, } };
-		vector<VkRect2D> renderAreas;
-		for (deUint32 i = 0; i < devicesCount; i++)
-			renderAreas.push_back(zeroRect);
-
-		// Render completely if there is only 1 device
-		if (devicesCount == 1u)
-		{
-			renderAreas[0].extent.width = (deInt32)m_renderSize.x();
-			renderAreas[0].extent.height = (deInt32)m_renderSize.y();
-		}
-		else
-		{
-			// Split into 2 vertical halves
-			renderAreas[firstDeviceID].extent.width		= (deInt32)m_renderSize.x() / 2;
-			renderAreas[firstDeviceID].extent.height	= (deInt32)m_renderSize.y();
-			renderAreas[secondDeviceID]					= renderAreas[firstDeviceID];
-			renderAreas[secondDeviceID].offset.x		= (deInt32)m_renderSize.x() / 2;
-		}
-
-		const VkDeviceGroupRenderPassBeginInfo deviceGroupRPBeginInfo =
-		{
-			VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
-			DE_NULL,
-			(deUint32)((1 << devicesCount) - 1),
-			devicesCount,
-			&renderAreas[0]
-		};
-
-		const VkRenderPassBeginInfo passBeginParams =
-		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,						// sType
-			&deviceGroupRPBeginInfo,										// pNext
-			*m_renderPass,													// renderPass
-			curFramebuffer,													// framebuffer
-			{
-				{ 0, 0 },
-				{ m_renderSize.x(), m_renderSize.y() }
-			},																// renderArea
-			1u,																// clearValueCount
-			&clearValue,													// pClearValues
-		};
-		m_vkd.cmdBeginRenderPass(cmdBuffer, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
-	}
-
-	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
-
-	{
-		const VkDeviceSize bindingOffset = 0;
-		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
-	}
-
-	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
-	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
-	endRenderPass(m_vkd, cmdBuffer);
-
-	if (m_explicitLayoutTransitions)
-	{
-		VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
-		const VkImageMemoryBarrier	barrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
-																		 m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-																		 m_aliasImages[imageNdx], range);
-		m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-		m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
-	}
-
-	endCommandBuffer(m_vkd, cmdBuffer);
-}
-
-void TriangleRenderer::getPrograms (SourceCollections& dst)
-{
-	dst.glslSources.add("tri-vert") << glu::VertexSource(
-		"#version 310 es\n"
-		"layout(location = 0) in highp vec4 a_position;\n"
-		"layout(push_constant) uniform FrameData\n"
-		"{\n"
-		"    highp uint frameNdx;\n"
-		"} frameData;\n"
-		"void main (void)\n"
-		"{\n"
-		"    highp float angle = float(frameData.frameNdx) / 100.0;\n"
-		"    highp float c     = cos(angle);\n"
-		"    highp float s     = sin(angle);\n"
-		"    highp mat4  t     = mat4( c, -s,  0,  0,\n"
-		"                              s,  c,  0,  0,\n"
-		"                              0,  0,  1,  0,\n"
-		"                              0,  0,  0,  1);\n"
-		"    gl_Position = t * a_position;\n"
-		"}\n");
-	dst.glslSources.add("tri-frag") << glu::FragmentSource(
-		"#version 310 es\n"
-		"layout(location = 0) out lowp vec4 o_color;\n"
-		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
-}
-
 typedef de::SharedPtr<Unique<VkCommandBuffer> >	CommandBufferSp;
 typedef de::SharedPtr<Unique<VkFence> >			FenceSp;
 typedef de::SharedPtr<Unique<VkSemaphore> >		SemaphoreSp;
@@ -1442,7 +1025,7 @@
 	vector<FenceSp> fences(numFences);
 
 	for (size_t ndx = 0; ndx < numFences; ++ndx)
-		fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device)));
+		fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device, vk::VK_FENCE_CREATE_SIGNALED_BIT)));
 
 	return fences;
 }
@@ -1561,8 +1144,8 @@
 {
 	const tcu::UVec2				desiredSize					(256, 256);
 	const InstanceHelper			instHelper					(context, wsiType);
-	const NativeObjects				native						(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>		surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects				native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>		surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 	const DeviceHelper				devHelper					(context, instHelper.vki, instHelper.instance, *surface);
 	const DeviceInterface&			vkd							= devHelper.vkd;
 	const VkDevice					device						= *devHelper.device;
@@ -1575,7 +1158,7 @@
 	if (!acquireImageWrapper.featureAvailable(context))
 		TCU_THROW(NotSupportedError, "Required extension is not supported");
 
-	const TriangleRenderer			renderer					(vkd,
+	const WsiTriangleRenderer		renderer					(vkd,
 																 device,
 																 allocator,
 																 context.getBinaryCollection(),
@@ -1613,9 +1196,7 @@
 			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
 			deUint32			imageNdx			= ~0u;
 
-			if (frameNdx >= maxQueuedFrames)
-				VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
-
+			VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
 			VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
 
 			{
@@ -1675,6 +1256,254 @@
 	return tcu::TestStatus::pass("Rendering tests succeeded");
 }
 
+class FrameStreamObjects
+{
+public:
+	struct FrameObjects
+	{
+		const vk::VkFence&			renderCompleteFence;
+		const vk::VkSemaphore&		renderCompleteSemaphore;
+		const vk::VkSemaphore&		imageAvailableSemaphore;
+		const vk::VkCommandBuffer&	commandBuffer;
+	};
+
+	FrameStreamObjects (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkCommandPool cmdPool, size_t maxQueuedFrames)
+		: renderingCompleteFences(createFences(vkd, device, maxQueuedFrames))
+		, renderingCompleteSemaphores(createSemaphores(vkd, device, maxQueuedFrames))
+		, imageAvailableSemaphores(createSemaphores(vkd, device, maxQueuedFrames))
+		, commandBuffers(allocateCommandBuffers(vkd, device, cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames))
+		, m_maxQueuedFrames(maxQueuedFrames)
+		, m_nextFrame(0u)
+	{}
+
+	size_t frameNumber (void) const { DE_ASSERT(m_nextFrame > 0u); return m_nextFrame - 1u; }
+
+	FrameObjects newFrame ()
+	{
+		const size_t mod = m_nextFrame % m_maxQueuedFrames;
+		FrameObjects ret =
+		{
+			**renderingCompleteFences[mod],
+			**renderingCompleteSemaphores[mod],
+			**imageAvailableSemaphores[mod],
+			**commandBuffers[mod],
+		};
+		++m_nextFrame;
+		return ret;
+	}
+
+private:
+	const vector<FenceSp>			renderingCompleteFences;
+	const vector<SemaphoreSp>		renderingCompleteSemaphores;
+	const vector<SemaphoreSp>		imageAvailableSemaphores;
+	const vector<CommandBufferSp>	commandBuffers;
+
+	const size_t	m_maxQueuedFrames;
+	size_t			m_nextFrame;
+};
+
+struct MultiSwapchainParams
+{
+	Type	wsiType;
+	size_t	swapchainCount;
+};
+
+struct AccumulatedPresentInfo
+{
+	vector<VkSemaphore>		semaphores;
+	vector<VkSwapchainKHR>	swapchains;
+	vector<deUint32>		imageIndices;
+
+	AccumulatedPresentInfo ()
+		: semaphores(), swapchains(), imageIndices()
+	{
+	}
+
+	void push_back (VkSemaphore sem, VkSwapchainKHR sc, deUint32 index)
+	{
+		semaphores.push_back(sem);
+		swapchains.push_back(sc);
+		imageIndices.push_back(index);
+	}
+
+	void reset ()
+	{
+		semaphores.resize(0);
+		swapchains.resize(0);
+		imageIndices.resize(0);
+	}
+
+	size_t size () const
+	{
+		// Any of the vectors would do.
+		return semaphores.size();
+	}
+};
+
+template <typename AcquireWrapperType>
+tcu::TestStatus multiSwapchainRenderTest (Context& context, MultiSwapchainParams params)
+{
+	DE_ASSERT(params.swapchainCount > 0);
+
+	const tcu::UVec2		desiredSize	(256, 256);
+	const InstanceHelper	instHelper	(context, params.wsiType);
+
+	// Create native window system objects, surfaces and helper surface vector.
+	std::unique_ptr<NativeObjects> native;
+	try
+	{
+		native.reset(new NativeObjects(context, instHelper.supportedExtensions, params.wsiType, params.swapchainCount, tcu::just(desiredSize)));
+	}
+	catch(tcu::ResourceError& err)
+	{
+		std::ostringstream msg;
+		msg << "Unable to create " << params.swapchainCount << " windows";
+		TCU_THROW(NotSupportedError, msg.str());
+	}
+
+	vector<Move<VkSurfaceKHR>>	surface;
+	vector<VkSurfaceKHR>		surfaceKHR;	// The plain Vulkan objects from the vector above.
+
+	for (size_t i = 0; i < params.swapchainCount; ++i)
+	{
+		surface.emplace_back(createSurface(instHelper.vki, instHelper.instance, params.wsiType, native->getDisplay(), native->getWindow(i)));
+		surfaceKHR.push_back(surface.back().get());
+	}
+
+	// Create a device compatible with all surfaces.
+	const DeviceHelper		devHelper	(context, instHelper.vki, instHelper.instance, surfaceKHR);
+	const DeviceInterface&	vkd			= devHelper.vkd;
+	const VkDevice			device		= *devHelper.device;
+	SimpleAllocator			allocator	(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
+
+	// Create several swapchains and images.
+	vector<VkSwapchainCreateInfoKHR>	swapchainInfo;
+	vector<Move<VkSwapchainKHR>>		swapchain;
+	vector<vector<VkImage>>				swapchainImages;
+	vector<AcquireWrapperType>			acquireImageWrapper;
+	for (size_t i = 0; i < params.swapchainCount; ++i)
+	{
+		swapchainInfo.emplace_back(getBasicSwapchainParameters(params.wsiType, instHelper.vki, devHelper.physicalDevice, *surface[i], desiredSize, 2));
+		swapchain.emplace_back(createSwapchainKHR(vkd, device, &swapchainInfo.back()));
+		swapchainImages.emplace_back(getSwapchainImages(vkd, device, swapchain.back().get()));
+		acquireImageWrapper.emplace_back(vkd, device, 1u, swapchain.back().get(), std::numeric_limits<deUint64>::max());
+	}
+
+	// Every acquire wrapper requires the same features, so we only check the first one.
+	if (!acquireImageWrapper.front().featureAvailable(context))
+		TCU_THROW(NotSupportedError, "Required extension is not supported");
+
+	// Renderer per swapchain.
+	vector<WsiTriangleRenderer> renderer;
+	for (size_t i = 0; i < params.swapchainCount; ++i)
+	{
+		renderer.emplace_back(vkd,
+							  device,
+							  allocator,
+							  context.getBinaryCollection(),
+							  false,
+							  swapchainImages[i],
+							  swapchainImages[i],
+							  swapchainInfo[i].imageFormat,
+							  tcu::UVec2(swapchainInfo[i].imageExtent.width, swapchainInfo[i].imageExtent.height));
+	}
+
+	const Unique<VkCommandPool>	commandPool			(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
+	const size_t				maxQueuedFrames		= swapchainImages.front().size()*2;	// Limit in-flight frames.
+
+	vector<FrameStreamObjects>	frameStreamObjects;
+	for (size_t i = 0; i < params.swapchainCount; ++i)
+		frameStreamObjects.emplace_back(vkd, device, commandPool.get(), maxQueuedFrames);
+
+	try
+	{
+		// 3 seconds for 60 Hz screens.
+		const deUint32			kNumFramesToRender		= 60*3*static_cast<deUint32>(params.swapchainCount);
+		AccumulatedPresentInfo	accumulatedPresentInfo;
+
+		for (size_t frameNdx = 0; frameNdx < kNumFramesToRender; ++frameNdx)
+		{
+			size_t		swapchainIndex	= frameNdx % params.swapchainCount;
+			auto&		fsObjects		= frameStreamObjects[swapchainIndex];
+			auto		frameObjects	= fsObjects.newFrame();
+			deUint32	imageNdx		= std::numeric_limits<deUint32>::max();
+
+			VK_CHECK(vkd.waitForFences(device, 1u, &frameObjects.renderCompleteFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
+			VK_CHECK(vkd.resetFences(device, 1u, &frameObjects.renderCompleteFence));
+
+			{
+				const VkResult acquireResult = acquireImageWrapper[swapchainIndex].call(frameObjects.imageAvailableSemaphore, (VkFence)DE_NULL, &imageNdx);
+				if (acquireResult == VK_SUBOPTIMAL_KHR)
+					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
+				else
+					VK_CHECK(acquireResult);
+			}
+
+			TCU_CHECK(static_cast<size_t>(imageNdx) < swapchainImages[swapchainIndex].size());
+
+			{
+				const VkPipelineStageFlags	waitDstStage	= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+				const VkSubmitInfo			submitInfo		=
+				{
+					VK_STRUCTURE_TYPE_SUBMIT_INFO,
+					DE_NULL,
+					1u,
+					&frameObjects.imageAvailableSemaphore,
+					&waitDstStage,
+					1u,
+					&frameObjects.commandBuffer,
+					1u,
+					&frameObjects.renderCompleteSemaphore,
+				};
+
+				renderer[swapchainIndex].recordFrame(frameObjects.commandBuffer, imageNdx, static_cast<deUint32>(frameNdx));
+				VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, frameObjects.renderCompleteFence));
+
+				// Save present information for the current frame.
+				accumulatedPresentInfo.push_back(frameObjects.renderCompleteSemaphore, swapchain[swapchainIndex].get(), imageNdx);
+
+				// Present frames when we have accumulated one frame per swapchain.
+				if (accumulatedPresentInfo.size() == params.swapchainCount)
+				{
+					DE_ASSERT(	accumulatedPresentInfo.semaphores.size() == accumulatedPresentInfo.swapchains.size()	&&
+								accumulatedPresentInfo.semaphores.size() == accumulatedPresentInfo.imageIndices.size()	);
+
+					vector<VkResult> results(params.swapchainCount, VK_ERROR_DEVICE_LOST);
+
+					const VkPresentInfoKHR presentInfo =
+					{
+						VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+						DE_NULL,
+						static_cast<deUint32>(accumulatedPresentInfo.semaphores.size()),
+						accumulatedPresentInfo.semaphores.data(),
+						static_cast<deUint32>(accumulatedPresentInfo.swapchains.size()),
+						accumulatedPresentInfo.swapchains.data(),
+						accumulatedPresentInfo.imageIndices.data(),
+						results.data(),
+					};
+
+					// Check both the global result and the individual results.
+					VK_CHECK_WSI(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
+					for (const auto& result : results)
+						VK_CHECK_WSI(result);
+
+					accumulatedPresentInfo.reset();
+				}
+			}
+		}
+
+		VK_CHECK(vkd.deviceWaitIdle(device));
+	}
+	catch (...)
+	{
+		// Make sure device is idle before destroying resources
+		vkd.deviceWaitIdle(device);
+		throw;
+	}
+
+	return tcu::TestStatus::pass("Rendering tests succeeded");
+}
+
 tcu::TestStatus deviceGroupRenderTest (Context& context, Type wsiType)
 {
 	const InstanceHelper		instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
@@ -1694,8 +1523,8 @@
 	}
 
 	const tcu::UVec2								desiredSize					(256, 256);
-	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 
 	const deUint32									devGroupIdx					= cmdLine.getVKDeviceGroupId() - 1;
 	const deUint32									deviceIdx					= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
@@ -1763,7 +1592,7 @@
 	const Unique<VkSwapchainKHR>	swapchain					(createSwapchainKHR(vkd, *groupDevice, &swapchainInfo));
 	const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, *groupDevice, *swapchain);
 
-	const TriangleRenderer			renderer					(vkd,
+	const WsiTriangleRenderer		renderer					(vkd,
 																 *groupDevice,
 																 allocator,
 																 context.getBinaryCollection(),
@@ -1800,9 +1629,7 @@
 			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
 			deUint32			imageNdx			= ~0u;
 
-			if (frameNdx >= maxQueuedFrames)
-				VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
-
+			VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
 			VK_CHECK(vkd.resetFences(*groupDevice, 1, &imageReadyFence));
 
 			{
@@ -1926,8 +1753,8 @@
 	}
 
 	const tcu::UVec2								desiredSize					(256, 256);
-	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 
 	const deUint32									devGroupIdx					= cmdLine.getVKDeviceGroupId() - 1;
 	const deUint32									deviceIdx					= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
@@ -2035,7 +1862,7 @@
 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
 		&imageSwapchainCreateInfo,
 		VK_IMAGE_CREATE_ALIAS_BIT |
-			VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,	// flags
+		VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,		// flags
 		VK_IMAGE_TYPE_2D,											// imageType
 		formats[0].format,											// format
 		{															// extent
@@ -2064,14 +1891,14 @@
 
 	// Create non-SFR image aliases for image layout transition
 	{
-		vector<VkBindImageMemorySwapchainInfoKHR>	bindImageMemorySwapchainInfo	(numImages);
-		vector<VkBindImageMemoryDeviceGroupInfo	>	bindImageMemoryDeviceGroupInfo	(numImages);
-		vector<VkBindImageMemoryInfo>				bindImageMemoryInfos			(numImages);
+	vector<VkBindImageMemorySwapchainInfoKHR>	bindImageMemorySwapchainInfo	(numImages);
+	vector<VkBindImageMemoryDeviceGroupInfo	>	bindImageMemoryDeviceGroupInfo	(numImages);
+	vector<VkBindImageMemoryInfo>				bindImageMemoryInfos			(numImages);
 
-		for (deUint32 idx = 0; idx < numImages; ++idx)
-		{
-			// Create image
-			images[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
+	for (deUint32 idx = 0; idx < numImages; ++idx)
+	{
+		// Create image
+		images[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
 
 			VkBindImageMemoryInfo bimInfo =
 			{
@@ -2098,51 +1925,51 @@
 			// Create image
 			imagesSfr[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
 
-			VkBindImageMemorySwapchainInfoKHR bimsInfo =
-			{
-				VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
-				DE_NULL,
-				*swapchain,
-				idx
-			};
-			bindImageMemorySwapchainInfo[idx] = bimsInfo;
+		VkBindImageMemorySwapchainInfoKHR bimsInfo =
+		{
+			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
+			DE_NULL,
+			*swapchain,
+			idx
+		};
+		bindImageMemorySwapchainInfo[idx] = bimsInfo;
 
-			// Split into 2 vertical halves
-			// NOTE: the same split has to be done also in TriangleRenderer::recordDeviceGroupFrame
-			const deUint32	halfWidth			= desiredSize.x() / 2;
-			const deUint32	height				= desiredSize.y();
-			const VkRect2D	sfrRects[] =
-			{
-				{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
-				{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	},		// offset, extent
-				{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
-				{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	}		// offset, extent
-			};
+		// Split into 2 vertical halves
+		// NOTE: the same split has to be done also in WsiTriangleRenderer::recordDeviceGroupFrame
+		const deUint32	halfWidth			= desiredSize.x() / 2;
+		const deUint32	height				= desiredSize.y();
+		const VkRect2D	sfrRects[] =
+		{
+			{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
+			{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	},		// offset, extent
+			{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
+			{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	}		// offset, extent
+		};
 
-			VkBindImageMemoryDeviceGroupInfo bimdgInfo =
-			{
-				VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
-				&bindImageMemorySwapchainInfo[idx],
-				DE_LENGTH_OF_ARRAY(deviceIndices),
-				deviceIndices,
-				DE_LENGTH_OF_ARRAY(sfrRects),
-				sfrRects
-			};
-			bindImageMemoryDeviceGroupInfo[idx] = bimdgInfo;
+		VkBindImageMemoryDeviceGroupInfo bimdgInfo =
+		{
+			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
+			&bindImageMemorySwapchainInfo[idx],
+			DE_LENGTH_OF_ARRAY(deviceIndices),
+			deviceIndices,
+			DE_LENGTH_OF_ARRAY(sfrRects),
+			sfrRects
+		};
+		bindImageMemoryDeviceGroupInfo[idx] = bimdgInfo;
 
-			VkBindImageMemoryInfo bimInfo =
-			{
-				VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
-				&bindImageMemoryDeviceGroupInfo[idx],
+		VkBindImageMemoryInfo bimInfo =
+		{
+			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+			&bindImageMemoryDeviceGroupInfo[idx],
 				**imagesSfr[idx],
-				DE_NULL,				// If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
-				0u						// If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
-			};
-			bindImageMemoryInfos[idx]	= bimInfo;
+			DE_NULL,				// If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
+			0u						// If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
+		};
+		bindImageMemoryInfos[idx]	= bimInfo;
 			rawImagesSfr[idx]			= **imagesSfr[idx];
-		}
+	}
 
-		VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
+	VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
 	}
 
 	VkPeerMemoryFeatureFlags peerMemoryFeatures = 0u;
@@ -2150,7 +1977,7 @@
 	bool explicitLayoutTransitions = !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) ||
 									 !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT);
 
-	const TriangleRenderer			renderer					(vkd,
+	const WsiTriangleRenderer			renderer					(vkd,
 																 *groupDevice,
 																 allocator,
 																 context.getBinaryCollection(),
@@ -2187,9 +2014,7 @@
 			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
 			deUint32			imageNdx			= ~0u;
 
-			if (frameNdx >= maxQueuedFrames)
-				VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
-
+			VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
 			VK_CHECK(vkd.resetFences(*groupDevice, 1, &imageReadyFence));
 
 			{
@@ -2306,8 +2131,8 @@
 {
 	const tcu::UVec2				desiredSize			(256, 256);
 	const InstanceHelper			instHelper			(context, wsiType);
-	const NativeObjects				native				(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>		surface				(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects				native				(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>		surface				(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 	const DeviceHelper				devHelper			(context, instHelper.vki, instHelper.instance, *surface);
 	const PlatformProperties&		platformProperties	= getPlatformProperties(wsiType);
 	const VkSurfaceCapabilitiesKHR	capabilities		= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface);
@@ -2334,7 +2159,7 @@
 
 		Move<VkSwapchainKHR>			swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
 		const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, device, *swapchain);
-		const TriangleRenderer			renderer					(vkd,
+		const WsiTriangleRenderer		renderer					(vkd,
 																	device,
 																	allocator,
 																	context.getBinaryCollection(),
@@ -2370,9 +2195,7 @@
 				const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
 				deUint32			imageNdx			= ~0u;
 
-				if (frameNdx >= maxQueuedFrames)
-					VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
-
+				VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
 				VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
 
 				{
@@ -2444,8 +2267,8 @@
 {
 	const tcu::UVec2				desiredSize		(256, 256);
 	const InstanceHelper			instHelper		(context, wsiType);
-	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 	const DeviceHelper				devHelper		(context, instHelper.vki, instHelper.instance, *surface);
 	const VkSwapchainCreateInfoKHR	swapchainInfo	= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
 	const Unique<VkSwapchainKHR>	swapchain		(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));
@@ -2468,8 +2291,8 @@
 {
 	const tcu::UVec2				desiredSize(256, 256);
 	const InstanceHelper			instHelper(context, wsiType);
-	const NativeObjects				native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-	const Unique<VkSurfaceKHR>		surface(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const NativeObjects				native(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+	const Unique<VkSurfaceKHR>		surface(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 	const DeviceHelper				devHelper(context, instHelper.vki, instHelper.instance, *surface);
 	const VkSwapchainCreateInfoKHR	swapchainInfo = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
 	const Unique<VkSwapchainKHR>	swapchain(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));
@@ -2498,7 +2321,7 @@
 {
 	const InstanceHelper		instHelper	(context, wsiType);
 	const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
-	const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+	const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 	const DeviceHelper			devHelper	(context, instHelper.vki, instHelper.instance, *surface);
 	const VkSwapchainKHR		nullHandle	= DE_NULL;
 
@@ -2520,7 +2343,12 @@
 
 void getBasicRenderPrograms (SourceCollections& dst, Type)
 {
-	TriangleRenderer::getPrograms(dst);
+	WsiTriangleRenderer::getPrograms(dst);
+}
+
+void getBasicRenderPrograms (SourceCollections& dst, MultiSwapchainParams)
+{
+	WsiTriangleRenderer::getPrograms(dst);
 }
 
 void populateRenderGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
@@ -2529,6 +2357,14 @@
 	addFunctionCaseWithPrograms(testGroup, "basic2", "Basic Rendering Test using AcquireNextImage2", getBasicRenderPrograms, basicRenderTest<AcquireNextImage2Wrapper>, wsiType);
 	addFunctionCaseWithPrograms(testGroup, "device_group", "Basic Rendering Test using device_group", getBasicRenderPrograms, deviceGroupRenderTest, wsiType);
 	addFunctionCaseWithPrograms(testGroup, "device_group2", "Rendering Test using device_group and VkImageSwapchainCreateInfo", getBasicRenderPrograms, deviceGroupRenderTest2, wsiType);
+
+	const MultiSwapchainParams kTwoSwapchains	{ wsiType, 2u	};
+	const MultiSwapchainParams kTenSwapchains	{ wsiType, 10u	};
+
+	addFunctionCaseWithPrograms(testGroup, "2swapchains", "2 Swapchains Rendering Test", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImageWrapper>, kTwoSwapchains);
+	addFunctionCaseWithPrograms(testGroup, "2swapchains2", "2 Swapchains Rendering Test using AcquireNextImage2", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImage2Wrapper>, kTwoSwapchains);
+	addFunctionCaseWithPrograms(testGroup, "10swapchains", "10 Swapchains Rendering Test", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImageWrapper>, kTenSwapchains);
+	addFunctionCaseWithPrograms(testGroup, "10swapchains2", "10 Swapchains Rendering Test using AcquireNextImage2", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImage2Wrapper>, kTenSwapchains);
 }
 
 void populateGetImagesGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp
index ac05663..2829c0a 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp
@@ -29,6 +29,7 @@
 #include "vktWsiSwapchainTests.hpp"
 #include "vktWsiDisplayTests.hpp"
 #include "vktWsiIncrementalPresentTests.hpp"
+#include "vktWsiDisplayControlTests.hpp"
 #include "vktWsiDisplayTimingTests.hpp"
 #include "vktWsiSharedPresentableImageTests.hpp"
 #include "vktWsiColorSpaceTests.hpp"
@@ -43,12 +44,12 @@
 
 void createTypeSpecificTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
 {
-	addTestGroup(testGroup, "surface",				"VkSurface Tests",				createSurfaceTests,				wsiType);
-	addTestGroup(testGroup, "swapchain",			"VkSwapchain Tests",			createSwapchainTests,			wsiType);
-	addTestGroup(testGroup, "incremental_present",	"Incremental present tests",	createIncrementalPresentTests,	wsiType);
-	addTestGroup(testGroup, "display_timing",		"Display Timing Tests",			createDisplayTimingTests,		wsiType);
+	addTestGroup(testGroup, "surface",					"VkSurface Tests",							createSurfaceTests,					wsiType);
+	addTestGroup(testGroup, "swapchain",				"VkSwapchain Tests",						createSwapchainTests,				wsiType);
+	addTestGroup(testGroup, "incremental_present",		"Incremental present tests",				createIncrementalPresentTests,		wsiType);
+	addTestGroup(testGroup, "display_timing",			"Display Timing Tests",						createDisplayTimingTests,			wsiType);
 	addTestGroup(testGroup, "shared_presentable_image",	"VK_KHR_shared_presentable_image tests",	createSharedPresentableImageTests,	wsiType);
-	addTestGroup(testGroup, "colorspace",	        "ColorSpace tests",	            createColorSpaceTests,	        wsiType);
+	addTestGroup(testGroup, "colorspace",				"ColorSpace tests",							createColorSpaceTests,				wsiType);
 }
 
 void createWsiTests (tcu::TestCaseGroup* apiTests)
@@ -61,6 +62,7 @@
 	}
 
 	addTestGroup(apiTests, "display", "Display coverage tests", createDisplayCoverageTests);
+	addTestGroup(apiTests, "display_control", "Display Control Tests", createDisplayControlTests);
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/ycbcr/CMakeLists.txt b/external/vulkancts/modules/vulkan/ycbcr/CMakeLists.txt
index 6ed0508..583d97e 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/ycbcr/CMakeLists.txt
@@ -21,6 +21,8 @@
 	vktYCbCrUtil.hpp
 	vktYCbCrCopyTests.cpp
 	vktYCbCrCopyTests.hpp
+	vktYCbCrStorageImageWriteTests.cpp
+	vktYCbCrStorageImageWriteTests.hpp
 	)
 
 set(DEQP_VK_YCBCR_LIBS
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrConversionTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrConversionTests.cpp
index 821f4eb..40c0f0f 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrConversionTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrConversionTests.cpp
@@ -81,8 +81,6 @@
 {
 namespace
 {
-typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp;
-typedef de::SharedPtr<vk::Allocation> AllocationSp;
 
 template<typename T>
 inline de::SharedPtr<vk::Unique<T> > makeSharedPtr(vk::Move<T> move)
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp
index 0fea588..98b0642 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp
@@ -59,7 +59,6 @@
 {
 namespace
 {
-typedef de::SharedPtr<vk::Allocation> AllocationSp;
 
 struct ImageConfig
 {
@@ -167,134 +166,6 @@
 	return vk::createImage(vkd, device, &createInfo);
 }
 
-vk::VkFormat getPlaneCompatibleFormat (vk::VkFormat format, deUint32 planeNdx)
-{
-	DE_ASSERT(planeNdx < 3);
-
-	switch (format)
-	{
-		case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
-			return vk::VK_FORMAT_R8_UNORM;
-
-		case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R8_UNORM;
-			else
-				return vk::VK_FORMAT_R8G8_UNORM;
-		}
-
-		case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
-			return vk::VK_FORMAT_R8_UNORM;
-
-		case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R8_UNORM;
-			else
-				return vk::VK_FORMAT_R8G8_UNORM;
-		}
-
-		case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
-			return vk::VK_FORMAT_R8_UNORM;
-
-		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
-			return vk::VK_FORMAT_R10X6_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R10X6_UNORM_PACK16;
-			else
-				return vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
-		}
-
-		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
-			return vk::VK_FORMAT_R10X6_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R10X6_UNORM_PACK16;
-			else
-				return vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
-		}
-
-		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
-			return vk::VK_FORMAT_R10X6_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
-			return vk::VK_FORMAT_R12X4_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R12X4_UNORM_PACK16;
-			else
-				return vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
-		}
-
-		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
-			return vk::VK_FORMAT_R12X4_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R12X4_UNORM_PACK16;
-			else
-				return vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
-		}
-
-		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
-			return vk::VK_FORMAT_R12X4_UNORM_PACK16;
-
-		case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
-			return vk::VK_FORMAT_R16_UNORM;
-
-		case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R16_UNORM;
-			else
-				return vk::VK_FORMAT_R16G16_UNORM;
-		}
-
-		case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
-			return vk::VK_FORMAT_R16_UNORM;
-
-		case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
-		{
-			DE_ASSERT(planeNdx < 2);
-
-			if (planeNdx == 0)
-				return vk::VK_FORMAT_R16_UNORM;
-			else
-				return vk::VK_FORMAT_R16G16_UNORM;
-		}
-
-		case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
-			return vk::VK_FORMAT_R16_UNORM;
-
-		default:
-			DE_ASSERT(planeNdx == 0);
-			return format;
-	}
-}
-
 bool isCompatible (vk::VkFormat	srcFormat,
 				   vk::VkFormat	dstFormat)
 {
@@ -504,25 +375,6 @@
 	}
 }
 
-UVec2 getBlockSize (vk::VkFormat format)
-{
-	switch (format)
-	{
-		case vk::VK_FORMAT_G8B8G8R8_422_UNORM:
-		case vk::VK_FORMAT_B8G8R8G8_422_UNORM:
-		case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
-		case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
-		case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
-		case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
-		case vk::VK_FORMAT_G16B16G16R16_422_UNORM:
-		case vk::VK_FORMAT_B16G16R16G16_422_UNORM:
-			return UVec2(2, 1);
-
-		default:
-			return UVec2(1u, 1u);
-	}
-}
-
 deUint32 getBlockByteSize (vk::VkFormat format)
 {
 	switch (format)
@@ -580,16 +432,6 @@
 	}
 }
 
-UVec2 getPlaneSize (const vk::PlanarFormatDescription&	info,
-					deUint32							planeNdx,
-					const UVec2&						size)
-{
-	if (info.numPlanes > 1)
-		return UVec2(size.x() / info.planes[planeNdx].widthDivisor, size.y() / info.planes[planeNdx].heightDivisor);
-	else
-		return size;
-}
-
 UVec2 randomUVec2 (de::Random&	rng,
 				   const UVec2&	min,
 				   const UVec2&	max)
@@ -618,8 +460,8 @@
 	{
 		for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++)
 		{
-			const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx));
-			const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx));
+			const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcPlaneInfo, srcPlaneNdx));
+			const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstPlaneInfo, dstPlaneNdx));
 
 			if (isCompatible(srcPlaneFormat, dstPlaneFormat))
 				pairs.push_back(std::make_pair(srcPlaneNdx, dstPlaneNdx));
@@ -635,21 +477,21 @@
 		const pair<deUint32, deUint32>	planes			(rng.choose<pair<deUint32, deUint32> >(pairs.begin(), pairs.end()));
 
 		const deUint32					srcPlaneNdx			(planes.first);
-		const vk::VkFormat				srcPlaneFormat		(getPlaneCompatibleFormat(srcFormat, srcPlaneNdx));
-		const UVec2						srcBlockSize		(getBlockSize(srcPlaneFormat));
-		const UVec2						srcPlaneSize		(getPlaneSize(srcPlaneInfo, srcPlaneNdx, srcSize));
-		const UVec2						srcPlaneBlockSize	(srcPlaneSize / srcBlockSize);
+		const vk::VkFormat				srcPlaneFormat		(getPlaneCompatibleFormat(srcPlaneInfo, srcPlaneNdx));
+		const UVec2						srcBlockExtent		(getBlockExtent(srcPlaneFormat));
+		const UVec2						srcPlaneExtent		(getPlaneExtent(srcPlaneInfo, srcSize, srcPlaneNdx, 0));
+		const UVec2						srcPlaneBlockExtent	(srcPlaneExtent / srcBlockExtent);
 
 		const deUint32					dstPlaneNdx			(planes.second);
-		const vk::VkFormat				dstPlaneFormat		(getPlaneCompatibleFormat(dstFormat, dstPlaneNdx));
-		const UVec2						dstBlockSize		(getBlockSize(dstPlaneFormat));
-		const UVec2						dstPlaneSize		(getPlaneSize(dstPlaneInfo, dstPlaneNdx, dstSize));
-		const UVec2						dstPlaneBlockSize	(dstPlaneSize / dstBlockSize);
+		const vk::VkFormat				dstPlaneFormat		(getPlaneCompatibleFormat(dstPlaneInfo, dstPlaneNdx));
+		const UVec2						dstBlockExtent		(getBlockExtent(dstPlaneFormat));
+		const UVec2						dstPlaneExtent		(getPlaneExtent(dstPlaneInfo, dstSize, dstPlaneNdx, 0));
+		const UVec2						dstPlaneBlockExtent	(dstPlaneExtent / dstBlockExtent);
 
-		const UVec2						copyBlockSize		(randomUVec2(rng, UVec2(1u, 1u), tcu::min(srcPlaneBlockSize, dstPlaneBlockSize)));
-		const UVec2						srcOffset			(srcBlockSize * randomUVec2(rng, UVec2(0u, 0u), srcPlaneBlockSize - copyBlockSize));
-		const UVec2						dstOffset			(dstBlockSize * randomUVec2(rng, UVec2(0u, 0u), dstPlaneBlockSize - copyBlockSize));
-		const UVec2						copySize			(copyBlockSize * srcBlockSize);
+		const UVec2						copyBlockExtent		(randomUVec2(rng, UVec2(1u, 1u), tcu::min(srcPlaneBlockExtent, dstPlaneBlockExtent)));
+		const UVec2						srcOffset			(srcBlockExtent * randomUVec2(rng, UVec2(0u, 0u), srcPlaneBlockExtent - copyBlockExtent));
+		const UVec2						dstOffset			(dstBlockExtent * randomUVec2(rng, UVec2(0u, 0u), dstPlaneBlockExtent - copyBlockExtent));
+		const UVec2						copyExtent			(copyBlockExtent * srcBlockExtent);
 		const vk::VkImageCopy			copy				=
 		{
 			// src
@@ -678,8 +520,8 @@
 			},
 			// size
 			{
-				copySize.x(),
-				copySize.y(),
+				copyExtent.x(),
+				copyExtent.y(),
 				1u
 			}
 		};
@@ -842,36 +684,36 @@
 				const deUint32			srcPlaneNdx			(copy.srcSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT
 															? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.srcSubresource.aspectMask)
 															: 0u);
-				const UVec2				srcPlaneSize		(getPlaneSize(srcData.getDescription(), srcPlaneNdx, config.src.size));
+				const UVec2				srcPlaneExtent		(getPlaneExtent(srcData.getDescription(), config.src.size, srcPlaneNdx, 0));
 
 				const vk::VkFormat		srcPlaneFormat		(getPlaneCompatibleFormat(config.src.format, srcPlaneNdx));
-				const UVec2				srcBlockSize		(getBlockSize(srcPlaneFormat));
+				const UVec2				srcBlockExtent		(getBlockExtent(srcPlaneFormat));
 
 				const deUint32			blockSizeBytes		(getBlockByteSize(srcPlaneFormat));
 
-				const UVec2				srcPlaneBlockSize	(srcPlaneSize / srcBlockSize);
-				const UVec2				srcBlockOffset		(copy.srcOffset.x / srcBlockSize.x(), copy.srcOffset.y / srcBlockSize.y());
-				const UVec2				srcBlockPitch		(blockSizeBytes, blockSizeBytes * srcPlaneBlockSize.x());
+				const UVec2				srcPlaneBlockExtent	(srcPlaneExtent / srcBlockExtent);
+				const UVec2				srcBlockOffset		(copy.srcOffset.x / srcBlockExtent.x(), copy.srcOffset.y / srcBlockExtent.y());
+				const UVec2				srcBlockPitch		(blockSizeBytes, blockSizeBytes * srcPlaneBlockExtent.x());
 
 				const deUint32			dstPlaneNdx			(copy.dstSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT
 															? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.dstSubresource.aspectMask)
 															: 0u);
-				const UVec2				dstPlaneSize		(getPlaneSize(dstData.getDescription(), dstPlaneNdx, config.dst.size));
+				const UVec2				dstPlaneExtent		(getPlaneExtent(dstData.getDescription(), config.dst.size, dstPlaneNdx, 0));
 
 				const vk::VkFormat		dstPlaneFormat		(getPlaneCompatibleFormat(config.dst.format, dstPlaneNdx));
-				const UVec2				dstBlockSize		(getBlockSize(dstPlaneFormat));
+				const UVec2				dstBlockExtent		(getBlockExtent(dstPlaneFormat));
 
-				const UVec2				dstPlaneBlockSize	(dstPlaneSize / dstBlockSize);
-				const UVec2				dstBlockOffset		(copy.dstOffset.x / dstBlockSize.x(), copy.dstOffset.y / dstBlockSize.y());
-				const UVec2				dstBlockPitch		(blockSizeBytes, blockSizeBytes * dstPlaneBlockSize.x());
+				const UVec2				dstPlaneBlockExtent	(dstPlaneExtent / dstBlockExtent);
+				const UVec2				dstBlockOffset		(copy.dstOffset.x / dstBlockExtent.x(), copy.dstOffset.y / dstBlockExtent.y());
+				const UVec2				dstBlockPitch		(blockSizeBytes, blockSizeBytes * dstPlaneBlockExtent.x());
 
-				const UVec2				blockSize			(copy.extent.width / srcBlockSize.x(), copy.extent.height / srcBlockSize.y());
+				const UVec2				blockExtent			(copy.extent.width / srcBlockExtent.x(), copy.extent.height / srcBlockExtent.y());
 
 				DE_ASSERT(blockSizeBytes == getBlockByteSize(dstPlaneFormat));
 
-				for (deUint32 y = 0; y < blockSize.y(); y++)
+				for (deUint32 y = 0; y < blockExtent.y(); y++)
 				{
-					const deUint32	size	= blockSize.x() * blockSizeBytes;
+					const deUint32	size	= blockExtent.x() * blockSizeBytes;
 					const deUint32	srcPos	= tcu::dot(srcBlockPitch, UVec2(srcBlockOffset.x(), srcBlockOffset.y() + y));
 					const deUint32	dstPos	= tcu::dot(dstBlockPitch, UVec2(dstBlockOffset.x(), dstBlockOffset.y() + y));
 
@@ -885,7 +727,8 @@
 
 			for (deUint32 planeNdx = 0; planeNdx < result.getDescription().numPlanes; ++planeNdx)
 			{
-				for (size_t byteNdx = 0; byteNdx < result.getPlaneSize(planeNdx); byteNdx++)
+				deUint32 planeSize = vk::getPlaneSizeInBytes(result.getDescription(), result.getSize(), planeNdx, 0u, 1u);
+				for (size_t byteNdx = 0; byteNdx < planeSize; byteNdx++)
 				{
 					const deUint8	res	= ((const deUint8*)result.getPlanePtr(planeNdx))[byteNdx];
 					const deUint8	ref	= ((const deUint8*)reference.getPlanePtr(planeNdx))[byteNdx];
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp
index 3e8b885..319c508 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp
@@ -54,10 +54,6 @@
 namespace
 {
 
-// \todo [2017-05-24 pyry] Extend:
-// * VK_IMAGE_TILING_LINEAR
-// * Other shader types
-
 using namespace vk;
 using namespace shaderexecutor;
 
@@ -70,9 +66,6 @@
 using std::vector;
 using std::string;
 
-typedef de::SharedPtr<Allocation>				AllocationSp;
-typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
-
 Move<VkImage> createTestImage (const DeviceInterface&	vkd,
 							   VkDevice					device,
 							   VkFormat					format,
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrImageQueryTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrImageQueryTests.cpp
index 2365463..b2aa202 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrImageQueryTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrImageQueryTests.cpp
@@ -67,9 +67,6 @@
 using std::vector;
 using std::string;
 
-typedef de::SharedPtr<Allocation>				AllocationSp;
-typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
-
 enum QueryType
 {
 	QUERY_TYPE_IMAGE_SIZE_LOD,			// OpImageQuerySizeLod
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.cpp
new file mode 100644
index 0000000..ec48454
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.cpp
@@ -0,0 +1,718 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 Google 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 Testing compute shader writing to separate planes of a multiplanar format
+ *//*--------------------------------------------------------------------*/
+
+#include "vktYCbCrStorageImageWriteTests.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktYCbCrUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "tcuTexVerifierUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "tcuTestLog.hpp"
+
+namespace vkt
+{
+namespace ycbcr
+{
+namespace
+{
+
+using namespace vk;
+
+struct TestParameters
+{
+	VkFormat			format;
+	tcu::UVec3			size;
+	VkImageCreateFlags	flags;
+
+	TestParameters (VkFormat			format_,
+					const tcu::UVec3&	size_,
+					VkImageCreateFlags	flags_)
+		: format			(format_)
+		, size				(size_)
+		, flags				(flags_)
+	{
+	}
+
+	TestParameters (void)
+		: format			(VK_FORMAT_UNDEFINED)
+		, flags				(0u)
+	{
+	}
+};
+
+void checkSupport (Context& context, const TestParameters params)
+{
+	const bool							disjoint = (params.flags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0;
+	std::vector<std::string>			reqExts;
+
+	if (disjoint)
+	{
+		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_bind_memory2"))
+			reqExts.push_back("VK_KHR_bind_memory2");
+		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_get_memory_requirements2"))
+			reqExts.push_back("VK_KHR_get_memory_requirements2");
+	}
+
+	for ( const auto& extIter : reqExts )
+	{
+		if (!context.isDeviceFunctionalitySupported(extIter))
+			TCU_THROW(NotSupportedError, (extIter + " is not supported").c_str());
+	}
+
+	{
+		const VkFormatProperties	formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
+			context.getPhysicalDevice(),
+			params.format);
+
+		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
+			TCU_THROW(NotSupportedError, "Storage images are not supported for this format");
+
+		if (disjoint && ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
+			TCU_THROW(NotSupportedError, "Disjoint planes are not supported for this format");
+	}
+}
+
+template<typename T>
+inline de::SharedPtr<vk::Unique<T> > makeVkSharedPtr(vk::Move<T> vkMove)
+{
+	return de::SharedPtr<vk::Unique<T> >(new vk::Unique<T>(vkMove));
+}
+
+tcu::UVec3 computeWorkGroupSize(const VkExtent3D& planeExtent)
+{
+	const deUint32		maxComputeWorkGroupInvocations	= 128u;
+	const tcu::UVec3	maxComputeWorkGroupSize			= tcu::UVec3(128u, 128u, 64u);
+
+	const deUint32		xWorkGroupSize					= std::min(std::min(planeExtent.width, maxComputeWorkGroupSize.x()), maxComputeWorkGroupInvocations);
+	const deUint32		yWorkGroupSize					= std::min(std::min(planeExtent.height, maxComputeWorkGroupSize.y()), maxComputeWorkGroupInvocations / xWorkGroupSize);
+	const deUint32		zWorkGroupSize					= std::min(std::min(planeExtent.depth, maxComputeWorkGroupSize.z()), maxComputeWorkGroupInvocations / (xWorkGroupSize*yWorkGroupSize));
+
+	return tcu::UVec3(xWorkGroupSize, yWorkGroupSize, zWorkGroupSize);
+}
+
+Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
+									  const VkDevice				device,
+									  const VkPipelineLayout		pipelineLayout,
+									  const VkShaderModule			shaderModule,
+									  const VkSpecializationInfo*	specializationInfo)
+{
+	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+		DE_NULL,												// const void*							pNext;
+		0u,														// VkPipelineShaderStageCreateFlags		flags;
+		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
+		shaderModule,											// VkShaderModule						module;
+		"main",													// const char*							pName;
+		specializationInfo,										// const VkSpecializationInfo*			pSpecializationInfo;
+	};
+	const VkComputePipelineCreateInfo pipelineCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
+		DE_NULL,											// const void*						pNext;
+		0u,													// VkPipelineCreateFlags			flags;
+		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
+		pipelineLayout,										// VkPipelineLayout					layout;
+		DE_NULL,											// VkPipeline						basePipelineHandle;
+		0,													// deInt32							basePipelineIndex;
+	};
+	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
+}
+
+vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
+{
+	DE_ASSERT(planeNdx < formatInfo.numPlanes);
+	vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
+
+	// redirect result for some of the YCbCr image formats
+	static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
+	{
+		{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
+		{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_G16B16G16R16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B8G8R8G8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
+		{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
+		{ VK_FORMAT_B16G16R16G16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	}
+	};
+	auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
+	if (it != std::end(ycbcrFormats))
+		result = it->second;
+	return result;
+}
+
+tcu::TestStatus testStorageImageWrite (Context& context, TestParameters params)
+{
+	const DeviceInterface&						vkd						= context.getDeviceInterface();
+	const VkDevice								device					= context.getDevice();
+	const deUint32								queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
+	const VkQueue								queue					= context.getUniversalQueue();
+	const PlanarFormatDescription				formatDescription		= getPlanarFormatDescription(params.format);
+
+	VkImageCreateInfo							imageCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+		DE_NULL,
+		params.flags,
+		VK_IMAGE_TYPE_2D,
+		params.format,
+		makeExtent3D(params.size.x(), params.size.y(), params.size.z()),
+		1u,			// mipLevels
+		1u,			// arrayLayers
+		VK_SAMPLE_COUNT_1_BIT,
+		VK_IMAGE_TILING_OPTIMAL,
+		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+		VK_SHARING_MODE_EXCLUSIVE,
+		0u,
+		(const deUint32*)DE_NULL,
+		VK_IMAGE_LAYOUT_UNDEFINED,
+	};
+
+	// check if we need to create VkImageView with different VkFormat than VkImage format
+	VkFormat planeCompatibleFormat0 = getPlaneCompatibleFormatForWriting(formatDescription, 0);
+	if (planeCompatibleFormat0 != getPlaneCompatibleFormat(formatDescription, 0))
+	{
+		imageCreateInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+	}
+
+	const Unique<VkImage>						image					(createImage(vkd, device, &imageCreateInfo));
+	// allocate memory for the whole image, or for each separate plane ( if the params.flags include VK_IMAGE_CREATE_DISJOINT_BIT )
+	const std::vector<AllocationSp>				allocations				(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, params.format, params.flags, MemoryRequirement::Any));
+
+	// Create descriptor set layout
+	const Unique<VkDescriptorSetLayout>			descriptorSetLayout		(DescriptorSetLayoutBuilder()
+		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
+		.build(vkd, device));
+	const Unique<VkPipelineLayout>				pipelineLayout			(makePipelineLayout(vkd, device, *descriptorSetLayout));
+
+	// Create descriptor sets
+	const Unique<VkDescriptorPool>				descriptorPool			(DescriptorPoolBuilder()
+		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u)
+		.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, vk::PlanarFormatDescription::MAX_PLANES));
+
+	// Create command buffer for compute and transfer operations
+	const Unique<VkCommandPool>					commandPool				(makeCommandPool(vkd, device, queueFamilyIndex));
+	const Unique<VkCommandBuffer>				commandBuffer			(allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+	std::vector<de::SharedPtr<vk::Unique<vk::VkShaderModule>>>			shaderModules;
+	std::vector<de::SharedPtr<vk::Unique<vk::VkPipeline>>>				computePipelines;
+	std::vector<de::SharedPtr<vk::Unique<vk::VkDescriptorSet>>>			descriptorSets;
+	std::vector<de::SharedPtr<vk::Unique<vk::VkImageView>>>				imageViews;
+
+	deUint32									imageSizeInBytes		= 0;
+	deUint32									planeOffsets[PlanarFormatDescription::MAX_PLANES];
+	deUint32									planeRowPitches[PlanarFormatDescription::MAX_PLANES];
+	void*										planePointers[PlanarFormatDescription::MAX_PLANES];
+
+	{
+		// Start recording commands
+		beginCommandBuffer(vkd, *commandBuffer);
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			const VkImageAspectFlags		aspect						= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+			const VkImageSubresourceRange	subresourceRange			= makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u);
+			VkFormat						planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+			vk::PlanarFormatDescription		compatibleFormatDescription = (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+			const tcu::UVec3				compatibleShaderGridSize	( params.size.x() / formatDescription.blockWidth, params.size.y() / formatDescription.blockHeight, params.size.z() / 1u);
+			VkExtent3D						shaderExtent				= getPlaneExtent(compatibleFormatDescription, VkExtent3D{ compatibleShaderGridSize.x(), compatibleShaderGridSize.y(), compatibleShaderGridSize.z() }, planeNdx, 0u);
+
+			// Create and bind compute pipeline
+			std::ostringstream shaderName;
+			shaderName << "comp" << planeNdx;
+			auto							shaderModule			= makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(shaderName.str()), DE_NULL));
+			shaderModules.push_back(shaderModule);
+			auto							computePipeline			= makeVkSharedPtr(makeComputePipeline(vkd, device, *pipelineLayout, shaderModule->get(), DE_NULL));
+			computePipelines.push_back(computePipeline);
+			vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->get());
+
+			auto							descriptorSet			= makeVkSharedPtr(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
+			descriptorSets.push_back(descriptorSet);
+
+			auto							imageView				= makeVkSharedPtr(makeImageView(vkd, device, *image, VK_IMAGE_VIEW_TYPE_2D, planeCompatibleFormat, subresourceRange));
+			imageViews.push_back(imageView);
+			const VkDescriptorImageInfo		imageInfo				= makeDescriptorImageInfo(DE_NULL, imageView->get(), VK_IMAGE_LAYOUT_GENERAL);
+
+			DescriptorSetUpdateBuilder()
+				.writeSingle(descriptorSet->get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
+				.update(vkd, device);
+
+			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet->get(), 0u, DE_NULL);
+
+			{
+				const VkImageMemoryBarrier imageLayoutChangeBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, *image, subresourceRange, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED);
+				vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutChangeBarrier);
+			}
+
+			{
+				const tcu::UVec3 workGroupSize = computeWorkGroupSize(shaderExtent);
+
+				const deUint32 xWorkGroupCount = shaderExtent.width / workGroupSize.x() + (shaderExtent.width % workGroupSize.x() ? 1u : 0u);
+				const deUint32 yWorkGroupCount = shaderExtent.height / workGroupSize.y() + (shaderExtent.height % workGroupSize.y() ? 1u : 0u);
+				const deUint32 zWorkGroupCount = shaderExtent.depth / workGroupSize.z() + (shaderExtent.depth % workGroupSize.z() ? 1u : 0u);
+
+				const tcu::UVec3 maxComputeWorkGroupCount = tcu::UVec3(65535u, 65535u, 65535u);
+
+				if (maxComputeWorkGroupCount.x() < xWorkGroupCount ||
+					maxComputeWorkGroupCount.y() < yWorkGroupCount ||
+					maxComputeWorkGroupCount.z() < zWorkGroupCount)
+				{
+					TCU_THROW(NotSupportedError, "Image size is not supported");
+				}
+
+				vkd.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
+			}
+
+			{
+				const VkImageMemoryBarrier imageTransferBarrier = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *image, subresourceRange);
+				vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferBarrier);
+			}
+		}
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			planeOffsets[planeNdx]		= imageSizeInBytes;
+			const deUint32	planeW		= imageCreateInfo.extent.width / (formatDescription.blockWidth * formatDescription.planes[planeNdx].widthDivisor);
+			planeRowPitches[planeNdx]	= formatDescription.planes[planeNdx].elementSizeBytes * planeW;
+			imageSizeInBytes			+= getPlaneSizeInBytes(formatDescription, makeExtent3D( params.size.x(), params.size.y(), params.size.z()) , planeNdx, 0u, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY);
+		}
+
+		const VkBufferCreateInfo		outputBufferCreateInfo	= makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+		const Unique<VkBuffer>			outputBuffer			( createBuffer(vkd, device, &outputBufferCreateInfo) );
+		const de::UniquePtr<Allocation>	outputBufferAlloc		( bindBuffer(vkd, device, context.getDefaultAllocator(), *outputBuffer, MemoryRequirement::HostVisible) );
+		std::vector<VkBufferImageCopy>	bufferImageCopy			( formatDescription.numPlanes );
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+		{
+			const VkImageAspectFlags	aspect = (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
+
+			bufferImageCopy[planeNdx] =
+			{
+				planeOffsets[planeNdx],																								//	VkDeviceSize				bufferOffset;
+				0u,																													//	deUint32					bufferRowLength;
+				0u,																													//	deUint32					bufferImageHeight;
+				makeImageSubresourceLayers(aspect, 0u, 0u, 1u),																		//	VkImageSubresourceLayers	imageSubresource;
+				makeOffset3D(0, 0, 0),																								//	VkOffset3D					imageOffset;
+				getPlaneExtent(formatDescription, makeExtent3D(params.size.x(), params.size.y(), params.size.z()), planeNdx, 0u)	//	VkExtent3D					imageExtent;
+			};
+		}
+		vkd.cmdCopyImageToBuffer(*commandBuffer, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outputBuffer, static_cast<deUint32>(bufferImageCopy.size()), bufferImageCopy.data());
+
+		{
+			const VkBufferMemoryBarrier outputBufferHostReadBarrier = makeBufferMemoryBarrier
+			(
+				VK_ACCESS_TRANSFER_WRITE_BIT,
+				VK_ACCESS_HOST_READ_BIT,
+				*outputBuffer,
+				0u,
+				imageSizeInBytes
+			);
+
+			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferHostReadBarrier, 0u, DE_NULL);
+		}
+
+		// End recording commands
+		endCommandBuffer(vkd, *commandBuffer);
+
+		// Submit commands for execution and wait for completion
+		submitCommandsAndWait(vkd, device, queue, *commandBuffer);
+
+		// Retrieve data from buffer to host memory
+		invalidateAlloc(vkd, device, *outputBufferAlloc);
+		deUint8*					outputData = static_cast<deUint8*>(outputBufferAlloc->getHostPtr());
+
+		for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+			planePointers[planeNdx] = outputData + static_cast<size_t>(planeOffsets[planeNdx]);
+	}
+
+	// write result images to log file
+	for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
+	{
+		if (!formatDescription.hasChannelNdx(channelNdx))
+			continue;
+		deUint32					planeNdx					= formatDescription.channels[channelNdx].planeNdx;
+		vk::VkFormat				planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+		vk::PlanarFormatDescription	compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+		const tcu::UVec3			compatibleShaderGridSize	( params.size.x() / formatDescription.blockWidth, params.size.y() / formatDescription.blockHeight, params.size.z() / 1u );
+		tcu::ConstPixelBufferAccess	pixelBuffer					= vk::getChannelAccess(compatibleFormatDescription, compatibleShaderGridSize, planeRowPitches, (const void* const*)planePointers, channelNdx);
+		std::ostringstream str;
+		str << "image" << channelNdx;
+		context.getTestContext().getLog() << tcu::LogImage(str.str(), str.str(), pixelBuffer);;
+	}
+
+	// verify data
+	const float					epsilon = 1e-5f;
+	for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
+	{
+		if (!formatDescription.hasChannelNdx(channelNdx))
+			continue;
+
+		deUint32							planeNdx					= formatDescription.channels[channelNdx].planeNdx;
+		vk::VkFormat						planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+		vk::PlanarFormatDescription			compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+		const tcu::UVec3					compatibleShaderGridSize	( params.size.x() / formatDescription.blockWidth, params.size.y() / formatDescription.blockHeight, params.size.z() / 1u );
+		VkExtent3D							compatibleImageSize			{ imageCreateInfo.extent.width / formatDescription.blockWidth, imageCreateInfo.extent.height / formatDescription.blockHeight, imageCreateInfo.extent.depth / 1u };
+		tcu::ConstPixelBufferAccess			pixelBuffer					= vk::getChannelAccess(compatibleFormatDescription, compatibleShaderGridSize, planeRowPitches, (const void* const*)planePointers, channelNdx);
+		VkExtent3D							planeExtent					= getPlaneExtent(compatibleFormatDescription, compatibleImageSize, planeNdx, 0u);
+		tcu::IVec3							pixelDivider				= pixelBuffer.getDivider();
+		float								fixedPointError				= tcu::TexVerifierUtil::computeFixedPointError(formatDescription.channels[channelNdx].sizeBits);
+
+		for (deUint32 offsetZ = 0u; offsetZ < planeExtent.depth; ++offsetZ)
+		for (deUint32 offsetY = 0u; offsetY < planeExtent.height; ++offsetY)
+		for (deUint32 offsetX = 0u; offsetX < planeExtent.width; ++offsetX)
+		{
+			deUint32	iReferenceValue;
+			float		fReferenceValue;
+			switch (channelNdx)
+			{
+				case 0:
+					iReferenceValue = offsetX % 127u;
+					fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+					break;
+				case 1:
+					iReferenceValue = offsetY % 127u;
+					fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+					break;
+				case 2:
+					iReferenceValue = offsetZ % 127u;
+					fReferenceValue = static_cast<float>(iReferenceValue) / 127.f;
+					break;
+				case 3:
+					iReferenceValue = 0u;
+					fReferenceValue = 0.f;
+					break;
+				default:	DE_FATAL("Unexpected channel index");	break;
+			}
+			float acceptableError = epsilon;
+
+			switch (formatDescription.channels[channelNdx].type)
+			{
+				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+				{
+					tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), 0);
+
+					if (outputValue.x() != iReferenceValue)
+						return tcu::TestStatus::fail("Failed");
+
+					break;
+				}
+				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+				{
+					acceptableError += fixedPointError;
+					tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), 0);
+
+					if (deAbs(outputValue.x() - fReferenceValue) > acceptableError)
+						return tcu::TestStatus::fail("Failed");
+
+					break;
+				}
+				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+				{
+					const tcu::Vec4 outputValue = pixelBuffer.getPixel(offsetX * pixelDivider.x(), offsetY * pixelDivider.y(), 0);
+
+					if (deAbs( outputValue.x() - fReferenceValue) > acceptableError)
+						return tcu::TestStatus::fail("Failed");
+
+					break;
+				}
+				default:	DE_FATAL("Unexpected channel type");	break;
+			}
+		}
+	}
+	return tcu::TestStatus::pass("Passed");
+}
+
+std::string getShaderImageType (const vk::PlanarFormatDescription& description)
+{
+	std::string	formatPart;
+
+	// all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
+	switch (description.channels[0].type)
+	{
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			formatPart = "i";
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			formatPart = "u";
+			break;
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			break;
+
+		default:
+			DE_FATAL("Unexpected channel type");
+	}
+
+	return formatPart + "image2D";
+}
+
+std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
+{
+	switch (description.channels[0].type)
+	{
+	case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		return "uvec4";
+	case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		return "ivec4";
+	case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+	case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+	case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		return "vec4";
+	default:
+		DE_FATAL("Unexpected channel type");
+		return "";
+	}
+}
+
+std::string getFormatValueString	(const std::vector<std::pair<deUint32, deUint32>>& channelsOnPlane,
+									 const std::vector<std::string>& formatValueStrings)
+{
+	std::string result = "( ";
+	deUint32 i;
+	for (i=0; i<channelsOnPlane.size(); ++i)
+	{
+		result += formatValueStrings[channelsOnPlane[i].first];
+		if (i < 3)
+			result += ", ";
+	}
+	for (; i < 4; ++i)
+	{
+		result += "0";
+		if (i < 3)
+			result += ", ";
+	}
+	result += " )";
+	return result;
+}
+
+std::string getShaderImageFormatQualifier (VkFormat format)
+{
+	switch (format)
+	{
+		case VK_FORMAT_R8_SINT:										return "r8i";
+		case VK_FORMAT_R16_SINT:									return "r16i";
+		case VK_FORMAT_R32_SINT:									return "r32i";
+		case VK_FORMAT_R8_UINT:										return "r8ui";
+		case VK_FORMAT_R16_UINT:									return "r16ui";
+		case VK_FORMAT_R32_UINT:									return "r32ui";
+		case VK_FORMAT_R8_SNORM:									return "r8_snorm";
+		case VK_FORMAT_R16_SNORM:									return "r16_snorm";
+		case VK_FORMAT_R8_UNORM:									return "r8";
+		case VK_FORMAT_R16_UNORM:									return "r16";
+
+		case VK_FORMAT_R8G8_SINT:									return "rg8i";
+		case VK_FORMAT_R16G16_SINT:									return "rg16i";
+		case VK_FORMAT_R32G32_SINT:									return "rg32i";
+		case VK_FORMAT_R8G8_UINT:									return "rg8ui";
+		case VK_FORMAT_R16G16_UINT:									return "rg16ui";
+		case VK_FORMAT_R32G32_UINT:									return "rg32ui";
+		case VK_FORMAT_R8G8_SNORM:									return "rg8_snorm";
+		case VK_FORMAT_R16G16_SNORM:								return "rg16_snorm";
+		case VK_FORMAT_R8G8_UNORM:									return "rg8";
+		case VK_FORMAT_R16G16_UNORM:								return "rg16";
+
+		case VK_FORMAT_R8G8B8A8_SINT:								return "rgba8i";
+		case VK_FORMAT_R16G16B16A16_SINT:							return "rgba16i";
+		case VK_FORMAT_R32G32B32A32_SINT:							return "rgba32i";
+		case VK_FORMAT_R8G8B8A8_UINT:								return "rgba8ui";
+		case VK_FORMAT_R16G16B16A16_UINT:							return "rgba16ui";
+		case VK_FORMAT_R32G32B32A32_UINT:							return "rgba32ui";
+		case VK_FORMAT_R8G8B8A8_SNORM:								return "rgba8_snorm";
+		case VK_FORMAT_R16G16B16A16_SNORM:							return "rgba16_snorm";
+		case VK_FORMAT_R8G8B8A8_UNORM:								return "rgba8";
+		case VK_FORMAT_R16G16B16A16_UNORM:							return "rgba16";
+
+		case VK_FORMAT_G8B8G8R8_422_UNORM:							return "rgba8";
+		case VK_FORMAT_B8G8R8G8_422_UNORM:							return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:					return "rgba8";
+		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:					return "rgba8";
+		case VK_FORMAT_R10X6_UNORM_PACK16:							return "r16";
+		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:					return "rg16";
+		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:			return "rgba16";
+		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_R12X4_UNORM_PACK16:							return "r16";
+		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:					return "rg16";
+		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:			return "rgba16";
+		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:		return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:	return "rgba16";
+		case VK_FORMAT_G16B16G16R16_422_UNORM:						return "rgba16";
+		case VK_FORMAT_B16G16R16G16_422_UNORM:						return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:				return "rgba16";
+		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:					return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:				return "rgba16";
+		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:					return "rgba16";
+		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:				return "rgba16";
+
+		default:
+			DE_FATAL("Unexpected texture format");
+			return "error";
+	}
+}
+
+void initPrograms (SourceCollections& sourceCollections, TestParameters params)
+{
+	// Create compute program
+	const char* const				versionDecl			= glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440);
+	const PlanarFormatDescription	formatDescription	= getPlanarFormatDescription(params.format);
+	const std::string				imageTypeStr		= getShaderImageType(formatDescription);
+	const std::string				formatDataStr		= getShaderImageDataType(formatDescription);
+	const tcu::UVec3				shaderGridSize		( params.size.x(), params.size.y(), params.size.z() );
+
+	std::vector<std::string>		formatValueStrings;
+	switch (formatDescription.channels[0].type)
+	{
+	case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+	case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		formatValueStrings = {
+			"int(gl_GlobalInvocationID.x) % 127",
+			"int(gl_GlobalInvocationID.y) % 127",
+			"int(gl_GlobalInvocationID.z) % 127",
+			"1"
+		};
+		break;
+	case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+	case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+	case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		formatValueStrings = {
+			"float(int(gl_GlobalInvocationID.x) % 127) / 127.0" ,
+			"float(int(gl_GlobalInvocationID.y) % 127) / 127.0",
+			"float(int(gl_GlobalInvocationID.z) % 127) / 127.0",
+			"1.0"
+		};
+		break;
+	default:	DE_ASSERT(false);	break;
+	}
+
+	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
+	{
+		VkFormat						planeCompatibleFormat		= getPlaneCompatibleFormatForWriting(formatDescription, planeNdx);
+		vk::PlanarFormatDescription		compatibleFormatDescription	= (planeCompatibleFormat != getPlaneCompatibleFormat(formatDescription, planeNdx)) ? getPlanarFormatDescription(planeCompatibleFormat) : formatDescription;
+		VkExtent3D						compatibleShaderGridSize	{ shaderGridSize.x() / formatDescription.blockWidth, shaderGridSize.y() / formatDescription.blockHeight, shaderGridSize.z() / 1u };
+
+		std::vector<std::pair<deUint32, deUint32>> channelsOnPlane;
+		for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
+		{
+			if (!formatDescription.hasChannelNdx(channelNdx))
+				continue;
+			if (formatDescription.channels[channelNdx].planeNdx != planeNdx)
+				continue;
+			channelsOnPlane.push_back({ channelNdx,formatDescription.channels[channelNdx].offsetBits });
+		}
+		// reorder channels for multi-planar images
+		if (formatDescription.numPlanes > 1)
+			std::sort(begin(channelsOnPlane), end(channelsOnPlane), [](const std::pair<deUint32, deUint32>& lhs, const std::pair<deUint32, deUint32>& rhs) { return lhs.second < rhs.second; });
+		std::string			formatValueStr		= getFormatValueString(channelsOnPlane, formatValueStrings);
+		VkExtent3D			shaderExtent		= getPlaneExtent(compatibleFormatDescription, compatibleShaderGridSize, planeNdx, 0);
+		const std::string	formatQualifierStr	= getShaderImageFormatQualifier(formatDescription.planes[planeNdx].planeCompatibleFormat);
+		const tcu::UVec3	workGroupSize		= computeWorkGroupSize(shaderExtent);
+
+		std::ostringstream src;
+		src << versionDecl << "\n"
+			<< "layout (local_size_x = " << workGroupSize.x() << ", local_size_y = " << workGroupSize.y() << ", local_size_z = " << workGroupSize.z() << ") in; \n"
+			<< "layout (binding = 0, " << formatQualifierStr << ") writeonly uniform highp " << imageTypeStr << " u_image;\n"
+			<< "void main (void)\n"
+			<< "{\n"
+			<< "	if( gl_GlobalInvocationID.x < " << shaderExtent.width << " ) \n"
+			<< "	if( gl_GlobalInvocationID.y < " << shaderExtent.height << " ) \n"
+			<< "	if( gl_GlobalInvocationID.z < " << shaderExtent.depth << " ) \n"
+			<< "	{\n"
+			<< "		imageStore(u_image, ivec2( gl_GlobalInvocationID.x, gl_GlobalInvocationID.y ) ,"
+			<< formatDataStr << formatValueStr << ");\n"
+			<< "	}\n"
+			<< "}\n";
+		std::ostringstream shaderName;
+		shaderName << "comp" << planeNdx;
+		sourceCollections.glslSources.add(shaderName.str()) << glu::ComputeSource(src.str());
+	}
+}
+
+tcu::TestCaseGroup* populateStorageImageWriteFormatGroup (tcu::TestContext& testCtx, de::MovePtr<tcu::TestCaseGroup> testGroup)
+{
+	const std::vector<tcu::UVec3>	availableSizes{ tcu::UVec3(512u, 512u, 1u), tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(66u, 32u, 1u) };
+
+	for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
+	{
+		const VkFormat					format				= (VkFormat)formatNdx;
+		tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
+		std::string						formatName			= de::toLower(de::toString(format).substr(10));
+		de::MovePtr<tcu::TestCaseGroup> formatGroup			( new tcu::TestCaseGroup(testCtx, formatName.c_str(), "") );
+
+		for (size_t sizeNdx = 0; sizeNdx < availableSizes.size(); sizeNdx++)
+		{
+			const tcu::UVec3 imageSize = availableSizes[sizeNdx];
+
+			// skip test for images with odd sizes for some YCbCr formats
+			if ((imageSize.x() % imageSizeAlignment.x()) != 0)
+				continue;
+			if ((imageSize.y() % imageSizeAlignment.y()) != 0)
+				continue;
+
+			std::ostringstream stream;
+			stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
+			de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, stream.str().c_str(), ""));
+
+			addFunctionCaseWithPrograms(sizeGroup.get(), "joint", "", checkSupport, initPrograms, testStorageImageWrite, TestParameters(format, imageSize, 0u));
+			addFunctionCaseWithPrograms(sizeGroup.get(), "disjoint", "", checkSupport, initPrograms, testStorageImageWrite, TestParameters(format, imageSize, (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT));
+
+			formatGroup->addChild(sizeGroup.release());
+		}
+		testGroup->addChild(formatGroup.release());
+	}
+	return testGroup.release();
+}
+
+} // namespace
+
+tcu::TestCaseGroup* createStorageImageWriteTests (tcu::TestContext& testCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "storage_image_write", "Writing to YCbCr storage images"));
+	return populateStorageImageWriteFormatGroup(testCtx, testGroup);
+}
+
+} // ycbcr
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.hpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.hpp
new file mode 100644
index 0000000..c416ab5
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _VKTYCBCRSTORAGEIMAGEWRITETESTS_HPP
+#define _VKTYCBCRSTORAGEIMAGEWRITETESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 Google 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 Testing compute shader writing to separate planes of a multiplanar format
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace ycbcr
+{
+
+tcu::TestCaseGroup*	createStorageImageWriteTests(tcu::TestContext& testCtx);
+
+} // ycbcr
+} // vkt
+
+#endif // _VKTYCBCRSTORAGEIMAGEWRITETESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrTests.cpp
index b9aa348..1eee5bf 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrTests.cpp
@@ -28,6 +28,7 @@
 #include "vktYCbCrImageQueryTests.hpp"
 #include "vktYCbCrConversionTests.hpp"
 #include "vktYCbCrCopyTests.hpp"
+#include "vktYCbCrStorageImageWriteTests.hpp"
 
 namespace vkt
 {
@@ -47,6 +48,7 @@
 	ycbcrTests->addChild(createConversionTests(testCtx));
 	ycbcrTests->addChild(createCopyTests(testCtx));
 	ycbcrTests->addChild(createDimensionsCopyTests(testCtx));
+	ycbcrTests->addChild(createStorageImageWriteTests(testCtx));
 }
 
 } // anonymous
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
index 1d90102..0da5f69 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
@@ -57,9 +57,6 @@
 using std::vector;
 using std::string;
 
-typedef de::SharedPtr<Allocation>				AllocationSp;
-typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
-
 // MultiPlaneImageData
 
 MultiPlaneImageData::MultiPlaneImageData (VkFormat format, const UVec2& size)
@@ -68,13 +65,7 @@
 	, m_size		(size)
 {
 	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
-	{
-		const deUint32	planeW		= size.x() / m_description.planes[planeNdx].widthDivisor;
-		const deUint32	planeH		= size.y() / m_description.planes[planeNdx].heightDivisor;
-		const deUint32	planeSize	= m_description.planes[planeNdx].elementSizeBytes * planeW * planeH;
-
-		m_planeData[planeNdx].resize(planeSize);
-	}
+		m_planeData[planeNdx].resize(getPlaneSizeInBytes(m_description, size, planeNdx, 0, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY));
 }
 
 MultiPlaneImageData::MultiPlaneImageData (const MultiPlaneImageData& other)
@@ -97,8 +88,7 @@
 
 	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
 	{
-		const deUint32	planeW		= m_size.x() / m_description.planes[planeNdx].widthDivisor;
-
+		const deUint32	planeW		= m_size.x() / ( m_description.blockWidth * m_description.planes[planeNdx].widthDivisor);
 		planeRowPitches[planeNdx]	= m_description.planes[planeNdx].elementSizeBytes * planeW;
 		planePtrs[planeNdx]			= &m_planeData[planeNdx][0];
 	}
@@ -117,8 +107,7 @@
 
 	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
 	{
-		const deUint32	planeW		= m_size.x() / m_description.planes[planeNdx].widthDivisor;
-
+		const deUint32	planeW		= m_size.x() / (m_description.blockWidth * m_description.planes[planeNdx].widthDivisor);
 		planeRowPitches[planeNdx]	= m_description.planes[planeNdx].elementSizeBytes * planeW;
 		planePtrs[planeNdx]			= &m_planeData[planeNdx][0];
 	}
@@ -214,10 +203,7 @@
 	}
 
 	for (const string& ext : reqExts)
-	{
-		if (!context.isDeviceFunctionalitySupported(ext))
-			TCU_THROW(NotSupportedError, (ext + " is not supported").c_str());
-	}
+		context.requireDeviceFunctionality(ext);
 
 	if (features.samplerYcbcrConversion == VK_FALSE)
 	{
@@ -367,12 +353,8 @@
 		const VkImageAspectFlagBits	aspect	= (formatDesc.numPlanes > 1)
 											? getPlaneAspect(planeNdx)
 											: VK_IMAGE_ASPECT_COLOR_BIT;
-		const deUint32				planeW	= (formatDesc.numPlanes > 1)
-											? imageData.getSize().x() / formatDesc.planes[planeNdx].widthDivisor
-											: imageData.getSize().x();
-		const deUint32				planeH	= (formatDesc.numPlanes > 1)
-											? imageData.getSize().y() / formatDesc.planes[planeNdx].heightDivisor
-											: imageData.getSize().y();
+		const VkExtent3D imageExtent		= makeExtent3D(imageData.getSize().x(), imageData.getSize().y(), 1u);
+		const VkExtent3D planeExtent		= getPlaneExtent(formatDesc, imageExtent, planeNdx, 0);
 		const VkBufferImageCopy		copy	=
 		{
 			0u,		// bufferOffset
@@ -380,7 +362,7 @@
 			0u,		// bufferImageHeight
 			{ (VkImageAspectFlags)aspect, 0u, arrayLayer, 1u },
 			makeOffset3D(0u, 0u, 0u),
-			makeExtent3D(planeW, planeH, 1u),
+			planeExtent
 		};
 
 		vkd.cmdCopyBufferToImage(*cmdBuffer, **stagingBuffers[planeNdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copy);
@@ -557,12 +539,8 @@
 									&preCopyBarrier);
 		}
 		{
-			const deUint32				planeW	= (formatDesc.numPlanes > 1)
-												? imageData->getSize().x() / formatDesc.planes[planeNdx].widthDivisor
-												: imageData->getSize().x();
-			const deUint32				planeH	= (formatDesc.numPlanes > 1)
-												? imageData->getSize().y() / formatDesc.planes[planeNdx].heightDivisor
-												: imageData->getSize().y();
+			const VkExtent3D imageExtent		= makeExtent3D(imageData->getSize().x(), imageData->getSize().y(), 1u);
+			const VkExtent3D planeExtent		= getPlaneExtent(formatDesc, imageExtent, planeNdx, 0);
 			const VkBufferImageCopy		copy	=
 			{
 				0u,		// bufferOffset
@@ -570,7 +548,7 @@
 				0u,		// bufferImageHeight
 				{ (VkImageAspectFlags)aspect, 0u, 0u, 1u },
 				makeOffset3D(0u, 0u, 0u),
-				makeExtent3D(planeW, planeH, 1u),
+				planeExtent
 			};
 
 			vkd.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **stagingBuffers[planeNdx], 1u, &copy);
@@ -753,7 +731,6 @@
 	, m_channelSize		(channelSize)
 	, m_size			(size)
 	, m_bitPitch		(bitPitch)
-
 	, m_data			((deUint8*)data + (bitOffset / 8))
 	, m_bitOffset		(bitOffset % 8)
 {
@@ -947,13 +924,12 @@
 	const deUint32	pixelStrideBits		= pixelStrideBytes * 8;
 	const deUint8	sizeBits			= formatInfo.channels[channelNdx].sizeBits;
 
-	DE_ASSERT(size.x() % formatInfo.planes[planeNdx].widthDivisor == 0);
-	DE_ASSERT(size.y() % formatInfo.planes[planeNdx].heightDivisor == 0);
+	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
+	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
 
-	deUint32		accessWidth			= size.x() / formatInfo.planes[planeNdx].widthDivisor;
-	const deUint32	accessHeight		= size.y() / formatInfo.planes[planeNdx].heightDivisor;
+	deUint32		accessWidth			= size.x() / ( formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor );
+	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
 	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
-
 	const deUint32	rowPitch			= formatInfo.planes[planeNdx].elementSizeBytes * accessWidth;
 	const deUint32	rowPitchBits		= rowPitch * 8;
 
@@ -1896,6 +1872,6 @@
 	}
 }
 
-
 } // ycbcr
+
 } // vkt
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.hpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.hpp
index 89f99f9..bf0f754 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.hpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.hpp
@@ -51,6 +51,9 @@
 #define VK_YCBCR_FORMAT_FIRST	VK_FORMAT_G8B8G8R8_422_UNORM
 #define VK_YCBCR_FORMAT_LAST	((vk::VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1))
 
+typedef de::SharedPtr<vk::Allocation>				AllocationSp;
+typedef de::SharedPtr<vk::Unique<vk::VkBuffer> >	VkBufferSp;
+
 class MultiPlaneImageData
 {
 public:
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrViewTests.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrViewTests.cpp
index 0da9bbb..bd156e1 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrViewTests.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrViewTests.cpp
@@ -64,89 +64,6 @@
 using std::vector;
 using std::string;
 
-typedef de::SharedPtr<Allocation>				AllocationSp;
-typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
-
-VkFormat getPlaneCompatibleFormat (VkFormat multiPlanarFormat, deUint32 planeNdx)
-{
-	switch (multiPlanarFormat)
-	{
-		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
-		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
-		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
-			if (de::inRange(planeNdx, 0u, 2u))
-				return VK_FORMAT_R8_UNORM;
-			else
-				break;
-
-		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
-		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
-			if (planeNdx == 0)
-				return VK_FORMAT_R8_UNORM;
-			else if (planeNdx == 1)
-				return VK_FORMAT_R8G8_UNORM;
-			else
-				break;
-
-		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
-		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
-		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
-			if (de::inRange(planeNdx, 0u, 2u))
-				return VK_FORMAT_R10X6_UNORM_PACK16;
-			else
-				break;
-
-		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
-		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
-			if (planeNdx == 0)
-				return VK_FORMAT_R10X6_UNORM_PACK16;
-			else if (planeNdx == 1)
-				return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
-			else
-				break;
-
-		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
-		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
-		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
-			if (de::inRange(planeNdx, 0u, 2u))
-				return VK_FORMAT_R12X4_UNORM_PACK16;
-			else
-				break;
-
-		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
-		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
-			if (planeNdx == 0)
-				return VK_FORMAT_R12X4_UNORM_PACK16;
-			else if (planeNdx == 1)
-				return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
-			else
-				break;
-
-		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
-		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
-		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
-			if (de::inRange(planeNdx, 0u, 2u))
-				return VK_FORMAT_R16_UNORM;
-			else
-				break;
-
-		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
-		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
-			if (planeNdx == 0)
-				return VK_FORMAT_R16_UNORM;
-			else if (planeNdx == 1)
-				return VK_FORMAT_R16G16_UNORM;
-			else
-				break;
-
-		default:
-			break;
-	}
-
-	DE_FATAL("Invalid format and plane index combination");
-	return VK_FORMAT_UNDEFINED;
-}
-
 Move<VkImage> createTestImage (const DeviceInterface&	vkd,
 							   VkDevice					device,
 							   VkFormat					format,
@@ -474,12 +391,10 @@
 	const VkFormat					planeViewFormat	= getPlaneCompatibleFormat(format, params.planeNdx);
 	const PlanarFormatDescription	formatInfo		= getPlanarFormatDescription(format);
 	const UVec2						size			= params.size;
-	const UVec2						planeSize		(size.x() / formatInfo.planes[params.planeNdx].widthDivisor,
-													 size.y() / formatInfo.planes[params.planeNdx].heightDivisor);
-
+	const UVec2						planeExtent		= getPlaneExtent(formatInfo, size, params.planeNdx, 0);
 	const Unique<VkImage>			image			(createTestImage(vkd, device, format, size, createFlags));
 	const Unique<VkImage>			imageAlias		((params.viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS)
-													 ? createTestImage(vkd, device, planeViewFormat, planeSize, createFlags)
+													 ? createTestImage(vkd, device, planeViewFormat, planeExtent, createFlags)
 													 : Move<VkImage>());
 	const vector<AllocationSp>		allocations		(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags));
 
@@ -654,7 +569,7 @@
 		// Plane view sampling reference
 		{
 			const tcu::ConstPixelBufferAccess	planeAccess		(mapVkFormat(planeViewFormat),
-																 tcu::IVec3((int)planeSize.x(), (int)planeSize.y(), 1),
+																 tcu::IVec3((int)planeExtent.x(), (int)planeExtent.y(), 1),
 																 imageData.getPlanePtr(params.planeNdx));
 			const tcu::Sampler					refSampler		= mapVkSampler(planeSamplerInfo);
 			const tcu::Texture2DView			refTexView		(1u, &planeAccess);
@@ -754,7 +669,6 @@
 
 tcu::TestCaseGroup* createViewTests (tcu::TestContext& testCtx)
 {
-	// \todo [2017-05-24 pyry] Extend with memory alias views
 	return createTestGroup(testCtx, "plane_view", "YCbCr Plane View Tests", populateViewGroup);
 }
 
diff --git a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
index 9a909eb..c61b228 100644
--- a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
+++ b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
Binary files differ
diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt
index 499ff84..688bee3 100644
--- a/external/vulkancts/mustpass/master/vk-default.txt
+++ b/external/vulkancts/mustpass/master/vk-default.txt
Binary files differ
diff --git a/external/vulkancts/scripts/build_spirv_binaries.py b/external/vulkancts/scripts/build_spirv_binaries.py
index 9dc1c52..f048228 100644
--- a/external/vulkancts/scripts/build_spirv_binaries.py
+++ b/external/vulkancts/scripts/build_spirv_binaries.py
@@ -44,7 +44,6 @@
 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(
@@ -98,8 +97,8 @@
 	parser.add_argument("-u",
 						"--target-vulkan-version",
 						dest="vulkanVersion",
-						default="1.1",
-						choices=["1.0", "1.1"],
+						default="1.2",
+						choices=["1.0", "1.1", "1.2"],
 						help="Target Vulkan version")
 	return parser.parse_args()
 
diff --git a/external/vulkancts/scripts/gen_framework.py b/external/vulkancts/scripts/gen_framework.py
index edd6031..95baeb1 100644
--- a/external/vulkancts/scripts/gen_framework.py
+++ b/external/vulkancts/scripts/gen_framework.py
@@ -42,12 +42,10 @@
 """
 
 DEFINITIONS			= [
-	("VK_API_VERSION_1_0",					"deUint32"),
-	("VK_API_VERSION_1_1",					"deUint32"),
 	("VK_MAX_PHYSICAL_DEVICE_NAME_SIZE",	"size_t"),
 	("VK_MAX_EXTENSION_NAME_SIZE",			"size_t"),
-	("VK_MAX_DRIVER_NAME_SIZE_KHR",			"size_t"),
-	("VK_MAX_DRIVER_INFO_SIZE_KHR",			"size_t"),
+	("VK_MAX_DRIVER_NAME_SIZE",				"size_t"),
+	("VK_MAX_DRIVER_INFO_SIZE",				"size_t"),
 	("VK_UUID_SIZE",						"size_t"),
 	("VK_LUID_SIZE",						"size_t"),
 	("VK_MAX_MEMORY_TYPES",					"size_t"),
@@ -94,6 +92,7 @@
 	(["const", "SECURITY_ATTRIBUTES", "*"],	["Win32SecurityAttributesPtr"],	"const void*"),
 	(["AHardwareBuffer", "*"],				["AndroidHardwareBufferPtr"],	"void*"),
 	(["HMONITOR"],							["Win32MonitorHandle"],			"void*"),
+	(["LPCWSTR"],							["Win32LPCWSTR"],				"const void*"),
 
 	# VK_EXT_acquire_xlib_display
 	(["RROutput"],							["RROutput"],					"void*"),
@@ -121,11 +120,10 @@
 	# Platform-specific
 	("DWORD",		"deUint32"),
 	("HANDLE*",		PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"),
-	("LPCWSTR",		"char*"),
 ]
 
 EXTENSION_POSTFIXES				= ["KHR", "EXT", "NV", "NVX", "KHX", "NN", "MVK", "FUCHSIA", "GGP", "AMD"]
-EXTENSION_POSTFIXES_STANDARD	= ["KHR"]
+EXTENSION_POSTFIXES_STANDARD	= ["KHR", "EXT"]
 
 def prefixName (prefix, name):
 	name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:])
@@ -151,6 +149,10 @@
 	name = name.replace("SMBUILTINS", "SM_BUILTINS")
 	name = name.replace("ASTCHDRFEATURES", "ASTC_HDR_FEATURES")
 	name = name.replace("UINT_8", "UINT8")
+	name = name.replace("VULKAN_11_FEATURES", "VULKAN_1_1_FEATURES")
+	name = name.replace("VULKAN_11_PROPERTIES", "VULKAN_1_1_PROPERTIES")
+	name = name.replace("VULKAN_12_FEATURES", "VULKAN_1_2_FEATURES")
+	name = name.replace("VULKAN_12_PROPERTIES", "VULKAN_1_2_PROPERTIES")
 	name = name.replace("INT_8_", "INT8_")
 	name = name.replace("AABBNV", "AABB_NV")
 
@@ -163,21 +165,15 @@
 		self.patch = versionTuple[2]
 
 	def getInHex (self):
-		if self.major == 1 and self.minor == 0 and self.patch == 0:
-			return "VK_API_VERSION_1_0"
-		elif self.major == 1 and self.minor == 1 and self.patch == 0:
-			return "VK_API_VERSION_1_1"
-		else:
-			hex = (self.major << 22) | (self.minor << 12) | self.patch
-			return '0x%Xu' % (hex)
+		if self.patch == 0:
+			return "VK_API_VERSION_%d_%d" % (self.major, self.minor)
+		return '0x%Xu' % (hash(self))
 
 	def isStandardVersion (self):
 		if self.patch != 0:
 			return False
 		if self.major != 1:
 			return False
-		if self.minor != 1 and self.minor != 0:
-			return False
 		return True
 
 	def getBestRepresentation (self):
@@ -396,7 +392,8 @@
 		return 'EXT:\n%s ->\nENUMS:\n%s\nCOMPOS:\n%s\nFUNCS:\n%s\nBITF:\n%s\nHAND:\n%s\nDEFS:\n%s\n' % (self.name, self.enums, self.compositeTypes, self.functions, self.bitfields, self.handles, self.definitions, self.versionInCore)
 
 class API:
-	def __init__ (self, definitions, handles, enums, bitfields, compositeTypes, functions, extensions):
+	def __init__ (self, versions, definitions, handles, enums, bitfields, compositeTypes, functions, extensions):
+		self.versions		= versions
 		self.definitions	= definitions
 		self.handles		= handles
 		self.enums			= enums
@@ -451,7 +448,6 @@
 def parsePreprocDefinedValue (src, name):
 	value = parsePreprocDefinedValueOptional(src, name)
 	if value is None:
-
 		raise Exception("No such definition: %s" % name)
 	return value
 
@@ -494,6 +490,14 @@
 		types.append(parseCompositeType(typeMap[type], typename, contents))
 	return types
 
+def parseVersions (src):
+	# returns list of tuples each with four items:
+	# 1. string with version token (without ' 1' at the end)
+	# 2. starting point off version specific definitions in vulkan.h.in
+	# 3. major version number
+	# 4. minor version number
+	return [(m.group()[:-2], m.start(), int(m.group(1)), int(m.group(2))) for m in re.finditer('VK_VERSION_([1-9])_([0-9]) 1', src)]
+
 def parseHandles (src):
 	matches	= re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
 	handles	= []
@@ -517,16 +521,15 @@
 			return name[0:-len(extPostfix)]
 	return None
 
-def populateAliases (objects):
-	objectsByName = {}
-	for object in objects:
-		objectsByName[object.name] = object
-	for object in objects:
+def populateExtensionAliases(allObjects, extensionObjects):
+	for object in extensionObjects:
 		withoutPostfix = removeTypeExtPostfix(object.name)
-		if withoutPostfix != None and withoutPostfix in objectsByName:
-			objectsByName[withoutPostfix].alias = object
+		if withoutPostfix != None and withoutPostfix in allObjects:
+			# max 1 alias is assumed by functions in this file
+			assert allObjects[withoutPostfix].alias == None
+			allObjects[withoutPostfix].alias = object
 			object.isAlias = True
-	for object in objects:
+	for object in extensionObjects:
 		object.checkAliasValidity()
 
 def populateAliasesWithTypedefs (objects, src):
@@ -570,30 +573,33 @@
 		functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
 	return functions
 
-def parseFunctionsByVersion (src):
-	ptrnVer10	= 'VK_VERSION_1_0 1'
-	ptrnVer11	= 'VK_VERSION_1_1 1'
-	matchVer10	= re.search(ptrnVer10, src)
-	matchVer11	= re.search(ptrnVer11, src)
+def parseFunctionsByVersion (src, versions):
+	# construct list of locations where version definitions start, and add the end of the file to it
+	sectionLocations = [versionDef[1] for versionDef in versions]
+	sectionLocations.append(len(src))
+
+	# construct function declaration pattern
 	ptrn		= r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
 	regPtrn		= re.compile(ptrn)
-	matches		= regPtrn.findall(src, matchVer10.start(), matchVer11.start())
 	functions	= []
-	for returnType, name, argList in matches:
-		functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), 'VK_VERSION_1_0'))
-	matches		= regPtrn.findall(src, matchVer11.start())
-	for returnType, name, argList in matches:
-		functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), 'VK_VERSION_1_1'))
+
+	# iterate over all versions and find all function definitions
+	for index, v in enumerate(versions):
+		matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
+		for returnType, name, argList in matches:
+			functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), v[0]))
 	return functions
 
 def splitByExtension (src):
 	ptrn		= r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
+	# Construct long pattern that will be used to split whole source by extensions
 	match		= "#define\s+("
 	for part in re.finditer(ptrn, src):
 		 match += part.group(1)+"|"
 	match = match[:-1] + ")\s+1"
 	parts = re.split(match, src)
-	# First part is core
+
+	# First part is core, following tuples contain extension name and all its definitions
 	byExtension	= [(None, parts[0])]
 	for ndx in range(1, len(parts), 2):
 		byExtension.append((parts[ndx], parts[ndx+1]))
@@ -620,9 +626,12 @@
 
 	return [Definition(None, match[0], match[1]) for match in matches if not skipDefinition(extensionName, match)]
 
-def parseExtensions (src, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions):
+def parseExtensions (src, versions, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions):
 
 	def getCoreVersion (extensionName, extensionsData):
+		# returns None when extension was not added to core for any Vulkan version
+		# returns array containing DEVICE or INSTANCE string followed by the vulkan version in which this extension is core
+		# note that this function is also called for vulkan 1.0 source for which extName is None
 		if not extensionName:
 			return None
 		ptrn		= extensionName + r'\s+(DEVICE|INSTANCE)\s+([0-9_]+)'
@@ -642,7 +651,8 @@
 	definitionsByName		= {definition.name: definition for definition in allDefinitions}
 
 	for extensionName, extensionSrc in splitSrc:
-		definitions			= [Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS]
+		definitions			= [Definition("deUint32", v.getInHex(), parsePreprocDefinedValueOptional(extensionSrc, v.getInHex())) for v in versions]
+		definitions.extend([Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS])
 		definitions			= [definition for definition in definitions if definition.value != None]
 		additionalDefinitions = parseDefinitions(extensionName, extensionSrc)
 		handles				= parseHandles(extensionSrc)
@@ -661,6 +671,14 @@
 		extHandles			= [handlesByName[handle.name] for handle in handles]
 		extDefinitions		= [definitionsByName[definition.name] for definition in definitions]
 
+		if extCoreVersion != None:
+			populateExtensionAliases(functionsByName, extFunctions)
+			populateExtensionAliases(handlesByName, extHandles)
+			populateExtensionAliases(enumsByName, extEnums)
+			populateExtensionAliases(bitfieldsByName, extBitfields)
+			populateExtensionAliases(compositeTypesByName, extCompositeTypes)
+
+
 		extensions.append(Extension(extensionName, extHandles, extEnums, extBitfields, extCompositeTypes, extFunctions, extDefinitions, additionalDefinitions, extCoreVersion))
 	return extensions
 
@@ -671,7 +689,11 @@
 	return matches
 
 def parseAPI (src):
-	definitions		= [Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS]
+	versionsData = parseVersions(src)
+	versions     = [Version((v[2], v[3], 0)) for v in versionsData]
+	definitions	 = [Definition("deUint32", v.getInHex(), parsePreprocDefinedValue(src, v.getInHex())) for v in versions]
+	definitions.extend([Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS])
+
 	handles			= parseHandles(src)
 	rawEnums		= parseEnums(src)
 	bitfieldNames	= parseBitfieldNames(src)
@@ -679,7 +701,7 @@
 	bitfields		= []
 	bitfieldEnums	= set([getBitEnumNameForBitfield(n) for n in bitfieldNames if getBitEnumNameForBitfield(n) in [enum.name for enum in rawEnums]])
 	compositeTypes	= parseCompositeTypes(src)
-	allFunctions	= parseFunctionsByVersion(src)
+	allFunctions	= parseFunctionsByVersion(src, versionsData)
 
 	for enum in rawEnums:
 		if enum.name in bitfieldEnums:
@@ -692,23 +714,18 @@
 			# Add empty bitfield
 			bitfields.append(Bitfield(bitfieldName, []))
 
+	extensions = parseExtensions(src, versions, allFunctions, compositeTypes, enums, bitfields, handles, definitions)
+
 	# Populate alias fields
 	populateAliasesWithTypedefs(compositeTypes, src)
 	populateAliasesWithTypedefs(enums, src)
 	populateAliasesWithTypedefs(bitfields, src)
-	populateAliases(allFunctions)
-	populateAliases(handles)
-	populateAliases(enums)
-	populateAliases(bitfields)
-	populateAliases(compositeTypes)
-
 
 	for enum in enums:
 		removeAliasedValues(enum)
 
-	extensions			= parseExtensions(src, allFunctions, compositeTypes, enums, bitfields, handles, definitions)
-
 	return API(
+		versions		= versions,
 		definitions		= definitions,
 		handles			= handles,
 		enums			= enums,
@@ -1067,6 +1084,8 @@
 						valFmt = "get%sStr(value.%s)" % (member.getType()[2:], member.name)
 					elif member.getType() == "const char*" or member.getType() == "char*":
 						valFmt = "getCharPtrStr(value.%s)" % member.name
+					elif member.getType() == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR":
+						valFmt = "getWStr(value.%s)" % member.name
 					elif member.arraySize != '':
 						if member.name in ["extensionName", "deviceName", "layerName", "description"]:
 							valFmt = "(const char*)value.%s" % member.name
@@ -1493,9 +1512,8 @@
 	writeInlFile(filename, INL_HEADER, lines)
 
 def writeCoreFunctionalities(api, filename):
-	functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
-
-	lines = addVersionDefines([Version((1, 0, 0)), Version((1, 1, 0))]) + [
+	functionOriginValues    = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
+	lines					= addVersionDefines(api.versions) + [
 	"",
 	'enum FunctionOrigin', '{'] + [line for line in indentLines([
 	'\t' + functionOriginValues[0] + '\t= 0,',
@@ -1509,30 +1527,22 @@
 	"",
 	"void initApisMap (ApisMap& apis)",
 	"{",
-	"	apis.clear();",
-	"	apis.insert(::std::pair<deUint32, FunctionInfosList>(" + str(Version((1, 0, 0))) + ", FunctionInfosList()));",
-	"	apis.insert(::std::pair<deUint32, FunctionInfosList>(" + str(Version((1, 1, 0))) + ", FunctionInfosList()));",
+	"	apis.clear();"] + [
+	"	apis.insert(::std::pair<deUint32, FunctionInfosList>(" + str(v) + ", FunctionInfosList()));" for v in api.versions] + [
 	""]
 
-	def list10Funcs ():
-		for fun in api.functions:
-			if fun.apiVersion == 'VK_VERSION_1_0':
-				insert = '	apis[' + str(Version((1, 0, 0))) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));'
-				yield insert
-
-	def listAllFuncs ():
+	apiVersions = []
+	for index, v in enumerate(api.versions):
+		funcs = []
+		apiVersions.append("VK_VERSION_{0}_{1}".format(v.major, v.minor))
+		# iterate over all functions that are core in latest vulkan version
+		# note that first item in api.extension array are actually all definitions that are in vulkan.h.in before section with extensions
 		for fun in api.extensions[0].functions:
-			insert = '	apis[' + str(Version((1, 1, 0))) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));'
-			yield insert
+			if fun.apiVersion in apiVersions:
+				funcs.append('	apis[' + str(v) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));')
+		lines = lines + [line for line in indentLines(funcs)] + [""]
 
-	lines = lines + [line for line in indentLines(list10Funcs())]
-	lines.append("")
-	lines = lines + [line for line in indentLines(listAllFuncs())]
-
-	lines.append("}")
-	lines.append("")
-	lines = lines + removeVersionDefines([Version((1, 0, 0)), Version((1, 1, 0))])
-
+	lines = lines + ["}", ""] + removeVersionDefines(api.versions)
 	writeInlFile(filename, INL_HEADER, lines)
 
 def generateDeviceFeaturesDefs(src):
@@ -1545,11 +1555,17 @@
 	for sType, sSuffix in matches:
 		structName			= re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
 		ptrnStructName		= r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Features' + sSuffix[1:] + ')'
-		matchStructName		= re.search(ptrnStructName, src, re.M)
+		matchStructName		= re.search(ptrnStructName, src, re.IGNORECASE)
 		if matchStructName:
 			# handle special cases
 			if sType == "EXCLUSIVE_SCISSOR":
 				sType = "SCISSOR_EXCLUSIVE"
+			elif sType == "ASTC_DECODE":
+				sType = "ASTC_DECODE_MODE"
+			elif sType == "TEXTURE_COMPRESSION_ASTC_HDR":
+				continue # skip due to const pNext
+			if sType in {'VULKAN_1_1', 'VULKAN_1_2'}:
+				continue
 			# end handling special cases
 			ptrnExtensionName	= r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_EXTENSION_NAME).+$'
 			matchExtensionName	= re.search(ptrnExtensionName, src, re.M)
@@ -1561,7 +1577,96 @@
 							matchSpecVersion.group	(1)	if matchSpecVersion		else '0') )
 	return defs
 
-def writeDeviceFeatures(dfDefs, filename):
+def generateDevicePropertiesDefs(src):
+	# look for definitions
+	ptrnSType	= r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_PROPERTIES(\w*)\s*='
+	matches		= re.findall(ptrnSType, src, re.M)
+	matches		= sorted(matches, key=lambda m: m[0])
+	# construct final list
+	defs = []
+	for sType, sSuffix in matches:
+		# skip VkPhysicalDeviceGroupProperties
+		if sType == "GROUP":
+			continue
+		structName			= re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
+		ptrnStructName		= r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Properties' + sSuffix[1:] + ')'
+		matchStructName		= re.search(ptrnStructName, src, re.M)
+		if matchStructName:
+			if sType in {'VULKAN_1_1', 'VULKAN_1_2'}:
+				continue
+			extType = sType
+			if extType == "MAINTENANCE_3":
+				extType = "MAINTENANCE3"
+			elif extType == "DISCARD_RECTANGLE":
+				extType = "DISCARD_RECTANGLES"
+			# end handling special cases
+			ptrnExtensionName	= r'^\s*#define\s+(\w+' + sSuffix + '_' + extType + '_EXTENSION_NAME).+$'
+			matchExtensionName	= re.search(ptrnExtensionName, src, re.M)
+			ptrnSpecVersion		= r'^\s*#define\s+(\w+' + sSuffix + '_' + extType + '_SPEC_VERSION).+$'
+			matchSpecVersion	= re.search(ptrnSpecVersion, src, re.M)
+			defs.append( (sType, sSuffix, matchStructName.group(1), \
+							matchExtensionName.group(0)	if matchExtensionName	else None,
+							matchExtensionName.group(1)	if matchExtensionName	else None,
+							matchSpecVersion.group	(1)	if matchSpecVersion		else '0') )
+	return defs
+
+def writeDeviceFeatures(api, dfDefs, filename):
+	# find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
+	# and construct dictionary with all of their attributes
+	blobMembers = {}
+	blobStructs = {}
+	blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features$")
+	for structureType in api.compositeTypes:
+		match = blobPattern.match(structureType.name)
+		if match:
+			allMembers = [member.name for member in structureType.members]
+			vkVersion = match.group(1)
+			blobMembers[vkVersion] = allMembers[2:]
+			blobStructs[vkVersion] = set()
+	initFromBlobDefinitions = []
+	emptyInitDefinitions = []
+	# iterate over all feature structures
+	allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features")
+	nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features$")
+	for structureType in api.compositeTypes:
+		# skip structures that are not feature structures
+		if not allFeaturesPattern.match(structureType.name):
+			continue
+		# skip structures that were previously identified as blobs
+		if blobPattern.match(structureType.name):
+			continue
+		if structureType.isAlias:
+			continue
+		# skip sType and pNext and just grab third and next attributes
+		structureMembers = structureType.members[2:]
+		notPartOfBlob = True
+		if nonExtFeaturesPattern.match(structureType.name):
+			# check if this member is part of any of the blobs
+			for blobName, blobMemberList in blobMembers.items():
+				# if just one member is not part of this blob go to the next blob
+				# (we asume that all members are part of blob - no need to check all)
+				if structureMembers[0].name not in blobMemberList:
+					continue
+				# add another feature structure name to this blob
+				blobStructs[blobName].add(structureType)
+				# add specialization for this feature structure
+				memberCopying = ""
+				for member in structureMembers:
+					memberCopying += "\tfeatureType.{0} = allBlobs.vk{1}.{0};\n".format(member.name, blobName)
+				wholeFunction = \
+					"template<> void initFromBlob<{0}>({0}& featureType, const AllBlobs& allBlobs)\n" \
+					"{{\n" \
+					"{1}" \
+					"}}".format(structureType.name, memberCopying)
+				initFromBlobDefinitions.append(wholeFunction)
+				notPartOfBlob = False
+				# assuming that all members are part of blob, goto next
+				break
+		# add empty template definition as on Fedora there are issue with
+		# linking using just generic template - all specializations are needed
+		if notPartOfBlob:
+			emptyFunction = "template<> void initFromBlob<{0}>({0}&, const AllBlobs&) {{}}"
+			emptyInitDefinitions.append(emptyFunction.format(structureType.name))
 	extensionDefines = []
 	makeFeatureDescDefinitions = []
 	featureStructWrappers = []
@@ -1577,49 +1682,133 @@
 		# handle special cases
 		if sType == "SCISSOR_EXCLUSIVE":
 			sType = "EXCLUSIVE_SCISSOR"
+		elif sType == "ASTC_DECODE_MODE":
+			sType = "ASTC_DECODE"
 		# end handling special cases
 		# construct makeFeatureDesc template function definitions
 		sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix)
 		makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \
-			"{{ return FeatureDesc({1}, {2}, {3}, {4}); }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
+			"{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
 		# construct CreateFeatureStruct wrapper block
 		featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
+	# construct method that will check if structure sType is part of blob
+	blobChecker = "bool isPartOfBlobFeatures (VkStructureType sType)\n{\n" \
+				  "\tconst std::vector<VkStructureType> sTypeVect =" \
+				  "\t{\n"
+	# iterate over blobs with list of structures
+	for blobName in sorted(blobStructs.keys()):
+		blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
+		# iterate over all feature structures in current blob
+		structuresList = list(blobStructs[blobName])
+		structuresList = sorted(structuresList, key=lambda s: s.name)
+		for structType in structuresList:
+			# find definition of this structure in dfDefs
+			structName = structType.name
+			# handle special cases
+			if structName == 'VkPhysicalDeviceShaderDrawParameterFeatures':
+				structName = 'VkPhysicalDeviceShaderDrawParametersFeatures'
+			# end handling special cases
+			structDef = [s for s in dfDefs if s[2] == structName][0]
+			sType = structDef[0]
+			sSuffix = structDef[1]
+			# handle special cases
+			if sType == "SCISSOR_EXCLUSIVE":
+				sType = "EXCLUSIVE_SCISSOR"
+			# end handling special cases
+			sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix)
+			blobChecker += "\t\t{0},\n".format(sTypeName)
+	blobChecker += "\t};\n" \
+				   "\treturn de::contains(sTypeVect.begin(), sTypeVect.end(), sType);\n" \
+				   "}\n"
 	# combine all definition lists
 	stream = [
 	'#include "vkDeviceFeatures.hpp"\n',
 	'namespace vk\n{']
 	stream.extend(extensionDefines)
 	stream.append('\n')
+	stream.extend(initFromBlobDefinitions)
+	stream.append('\n// generic template is not enough for some compilers')
+	stream.extend(emptyInitDefinitions)
+	stream.append('\n')
 	stream.extend(makeFeatureDescDefinitions)
 	stream.append('\n')
-	stream.append('static const FeatureStructMapItem featureStructCreatorMap[] =\n{')
+	stream.append('static const FeatureStructCreationData featureStructCreationArray[] =\n{')
 	stream.extend(featureStructWrappers)
+	stream.append('};\n')
+	stream.append(blobChecker)
+	stream.append('} // vk\n')
+	writeInlFile(filename, INL_HEADER, stream)
+
+def writeDeviceProperties(dfDefs, filename):
+	extensionDefines = []
+	makePropertyDescDefinitions = []
+	propertyStructWrappers = []
+	for idx, (sType, sSuffix, extStruct, extLine, extName, specVer) in enumerate(dfDefs):
+		extensionNameDefinition = extName
+		if not extensionNameDefinition:
+			extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sSuffix if sSuffix else ''), sType)
+		# construct defines with names
+		if extLine:
+			extensionDefines.append(extLine)
+		else:
+			extensionDefines.append('#define {0} "not_existent_property"'.format(extensionNameDefinition))
+		# construct makePropertyDesc template function definitions
+		sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix)
+		makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \
+			"{{ return PropertyDesc({1}, {2}, {3}, {4}); }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
+		# construct CreateProperty struct wrapper block
+		propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
+	# combine all definition lists
+	stream = [
+	'#include "vkDeviceProperties.hpp"\n',
+	'namespace vk\n{']
+	stream.extend(extensionDefines)
+	stream.append('\n')
+	stream.extend(makePropertyDescDefinitions)
+	stream.append('\n')
+	stream.append('static const PropertyStructMapItem propertyStructCreatorMap[] =\n{')
+	stream.extend(propertyStructWrappers)
 	stream.append('};\n} // vk\n')
 	writeInlFile(filename, INL_HEADER, stream)
 
 def genericDeviceFeaturesWriter(dfDefs, pattern, filename):
 	stream = []
 	for sType, sSuffix, extStruct, _, _, _ in dfDefs:
-		# Special case to treat BufferDeviceAddressFeaturesEXT differently than BufferDeviceAddressFeaturesKHR
-		if sType == "BUFFER_DEVICE_ADDRESS" and sSuffix == "_EXT":
-			nameSubStr = extStruct.replace("VkPhysicalDevice", "")
-		else:
-			nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("EXT", "").replace("KHR", "").replace("NV", "")
+		nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
 		stream.append(pattern.format(extStruct, nameSubStr))
 	writeInlFile(filename, INL_HEADER, indentLines(stream))
 
-def writeDefaultDeviceDefs(dfDefs, filename):
+def writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename):
 	pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}"
 	genericDeviceFeaturesWriter(dfDefs, pattern, filename)
 
-def writeContextDecl(dfDefs, filename):
+def writeDeviceFeaturesContextDecl(dfDefs, filename):
 	pattern = "const vk::{0}&\tget{1}\t(void) const;"
 	genericDeviceFeaturesWriter(dfDefs, pattern, filename)
 
-def writeContextDefs(dfDefs, filename):
+def writeDeviceFeaturesContextDefs(dfDefs, filename):
 	pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
 	genericDeviceFeaturesWriter(dfDefs, pattern, filename)
 
+def genericDevicePropertiesWriter(dfDefs, pattern, filename):
+	stream = []
+	for _, _, extStruct, _, _, _ in dfDefs:
+		nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
+		stream.append(pattern.format(extStruct, nameSubStr))
+	writeInlFile(filename, INL_HEADER, indentLines(stream))
+
+def writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename):
+	pattern = "const {0}&\tget{1}\t(void) const {{ return m_devicePropertiesFull.getPropertyType<{0}>();\t}}"
+	genericDevicePropertiesWriter(dfDefs, pattern, filename)
+
+def writeDevicePropertiesContextDecl(dfDefs, filename):
+	pattern = "const vk::{0}&\tget{1}\t(void) const;"
+	genericDevicePropertiesWriter(dfDefs, pattern, filename)
+
+def writeDevicePropertiesContextDefs(dfDefs, filename):
+	pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
+	genericDevicePropertiesWriter(dfDefs, pattern, filename)
+
 def splitWithQuotation(line):
 	result = []
 	splitted = re.findall(r'[^"\s]\S*|".+?"', line)
@@ -1645,7 +1834,7 @@
 					dictStructs[m[0]].append(allRequirements[0])
 
 	stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{',
-				   '\tif ( !context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2") )',
+				   '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))',
 				   '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");',
 				   '',
 				   '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();',
@@ -1661,6 +1850,10 @@
 
 	listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
 	for k, v in listStruct:
+		if (v[1].startswith("ApiVersion")):
+			cond = '\tif (context.contextSupports(vk::' + v[1] + '))'
+		else:
+			cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[1] + '"))'
 		stream.extend(['\tvk::' + k + ' ' + v[0]+ ';',
 					'\tdeMemset(&' + v[0] + ', 0, sizeof(' + v[0] + '));',
 					''])
@@ -1743,41 +1936,47 @@
 	instanceFuncs	= [Function.TYPE_INSTANCE]
 	deviceFuncs		= [Function.TYPE_DEVICE]
 
-	dfd							= generateDeviceFeaturesDefs(src)
-	writeDeviceFeatures			(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeatures.inl"))
-	writeDefaultDeviceDefs		(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForDefaultDeviceDefs.inl"))
-	writeContextDecl			(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDecl.inl"))
-	writeContextDefs			(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDefs.inl"))
+	dfd										= generateDeviceFeaturesDefs(src)
+	writeDeviceFeatures						(api, dfd, os.path.join(VULKAN_DIR, "vkDeviceFeatures.inl"))
+	writeDeviceFeaturesDefaultDeviceDefs	(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForDefaultDeviceDefs.inl"))
+	writeDeviceFeaturesContextDecl			(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDecl.inl"))
+	writeDeviceFeaturesContextDefs			(dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDefs.inl"))
 
-	writeHandleType				(api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
-	writeBasicTypes				(api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
-	writeCompositeTypes			(api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"),		platformFuncs,	False)
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"),		instanceFuncs,	False)
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"),			deviceFuncs,	False)
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"),		platformFuncs,	True)
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"),		instanceFuncs,	True)
-	writeInterfaceDecl			(api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"),		deviceFuncs,	True)
-	writeFunctionPtrTypes		(api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
-	writeFunctionPointers		(api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"),		platformFuncs)
-	writeFunctionPointers		(api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"),		instanceFuncs)
-	writeFunctionPointers		(api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"),			deviceFuncs)
-	writeInitFunctionPointers	(api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"),	platformFuncs,	lambda f: f.name != "vkGetInstanceProcAddr")
-	writeInitFunctionPointers	(api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"),	instanceFuncs)
-	writeInitFunctionPointers	(api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"),		deviceFuncs)
-	writeFuncPtrInterfaceImpl	(api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"),				platformFuncs,	"PlatformDriver")
-	writeFuncPtrInterfaceImpl	(api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"),				instanceFuncs,	"InstanceDriver")
-	writeFuncPtrInterfaceImpl	(api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"),				deviceFuncs,	"DeviceDriver")
-	writeStrUtilProto			(api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
-	writeStrUtilImpl			(api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
-	writeRefUtilProto			(api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
-	writeRefUtilImpl			(api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
-	writeStructTraitsImpl		(api, os.path.join(VULKAN_DIR, "vkGetStructureTypeImpl.inl"))
-	writeNullDriverImpl			(api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
-	writeTypeUtil				(api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))
-	writeSupportedExtenions		(api, os.path.join(VULKAN_DIR, "vkSupportedExtensions.inl"))
-	writeCoreFunctionalities	(api, os.path.join(VULKAN_DIR, "vkCoreFunctionalities.inl"))
-	writeExtensionFunctions		(api, os.path.join(VULKAN_DIR, "vkExtensionFunctions.inl"))
-	writeMandatoryFeatures		(     os.path.join(VULKAN_DIR, "vkMandatoryFeatures.inl"))
-	writeExtensionList			(     os.path.join(VULKAN_DIR, "vkInstanceExtensions.inl"),				'INSTANCE')
-	writeExtensionList			(     os.path.join(VULKAN_DIR, "vkDeviceExtensions.inl"),				'DEVICE')
+	dpd										= generateDevicePropertiesDefs(src)
+	writeDeviceProperties					(dpd, os.path.join(VULKAN_DIR, "vkDeviceProperties.inl"))
+	writeDevicePropertiesDefaultDeviceDefs	(dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForDefaultDeviceDefs.inl"))
+	writeDevicePropertiesContextDecl		(dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForContextDecl.inl"))
+	writeDevicePropertiesContextDefs		(dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForContextDefs.inl"))
+
+	writeHandleType							(api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
+	writeBasicTypes							(api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
+	writeCompositeTypes						(api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"),		platformFuncs,	False)
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"),		instanceFuncs,	False)
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"),			deviceFuncs,	False)
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"),		platformFuncs,	True)
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"),		instanceFuncs,	True)
+	writeInterfaceDecl						(api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"),		deviceFuncs,	True)
+	writeFunctionPtrTypes					(api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
+	writeFunctionPointers					(api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"),		platformFuncs)
+	writeFunctionPointers					(api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"),		instanceFuncs)
+	writeFunctionPointers					(api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"),			deviceFuncs)
+	writeInitFunctionPointers				(api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"),	platformFuncs,	lambda f: f.name != "vkGetInstanceProcAddr")
+	writeInitFunctionPointers				(api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"),	instanceFuncs)
+	writeInitFunctionPointers				(api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"),		deviceFuncs)
+	writeFuncPtrInterfaceImpl				(api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"),				platformFuncs,	"PlatformDriver")
+	writeFuncPtrInterfaceImpl				(api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"),				instanceFuncs,	"InstanceDriver")
+	writeFuncPtrInterfaceImpl				(api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"),				deviceFuncs,	"DeviceDriver")
+	writeStrUtilProto						(api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
+	writeStrUtilImpl						(api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
+	writeRefUtilProto						(api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
+	writeRefUtilImpl						(api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
+	writeStructTraitsImpl					(api, os.path.join(VULKAN_DIR, "vkGetStructureTypeImpl.inl"))
+	writeNullDriverImpl						(api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
+	writeTypeUtil							(api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))
+	writeSupportedExtenions					(api, os.path.join(VULKAN_DIR, "vkSupportedExtensions.inl"))
+	writeCoreFunctionalities				(api, os.path.join(VULKAN_DIR, "vkCoreFunctionalities.inl"))
+	writeExtensionFunctions					(api, os.path.join(VULKAN_DIR, "vkExtensionFunctions.inl"))
+	writeMandatoryFeatures					(     os.path.join(VULKAN_DIR, "vkMandatoryFeatures.inl"))
+	writeExtensionList						(     os.path.join(VULKAN_DIR, "vkInstanceExtensions.inl"),				'INSTANCE')
+	writeExtensionList						(     os.path.join(VULKAN_DIR, "vkDeviceExtensions.inl"),				'DEVICE')
diff --git a/external/vulkancts/scripts/src/extensions_data.txt b/external/vulkancts/scripts/src/extensions_data.txt
index 60d6e38..f5a0ebb 100644
--- a/external/vulkancts/scripts/src/extensions_data.txt
+++ b/external/vulkancts/scripts/src/extensions_data.txt
@@ -1,7 +1,7 @@
 // This is manually created file used by gen_framework.py.
 // It contains additional data for extensions that are required to
 // generate code for cts. Currently every line contains:
-// * extension name (at this point only KHR extensions are needed)
+// * extension name
 // * information wheter this is device or instance extension
 // * version number in which this extension is part of core
 
@@ -25,7 +25,7 @@
 VK_KHR_swapchain							DEVICE
 VK_KHR_swapchain_mutable_format				DEVICE
 VK_KHR_display_swapchain					DEVICE
-VK_KHR_sampler_mirror_clamp_to_edge			DEVICE
+VK_KHR_sampler_mirror_clamp_to_edge			DEVICE 1_2_0
 VK_KHR_multiview							DEVICE 1_1_0
 VK_KHR_device_group							DEVICE 1_1_0
 VK_KHR_shader_draw_parameters				DEVICE 1_1_0
@@ -38,12 +38,12 @@
 VK_KHR_external_semaphore_win32				DEVICE
 VK_KHR_external_semaphore_fd				DEVICE
 VK_KHR_push_descriptor						DEVICE
-VK_KHR_shader_float16_int8					DEVICE
+VK_KHR_shader_float16_int8					DEVICE 1_2_0
 VK_KHR_16bit_storage						DEVICE 1_1_0
 VK_KHR_incremental_present					DEVICE
-VK_KHR_8bit_storage							DEVICE
+VK_KHR_8bit_storage							DEVICE 1_2_0
 VK_KHR_descriptor_update_template			DEVICE 1_1_0
-VK_KHR_create_renderpass2					DEVICE
+VK_KHR_create_renderpass2					DEVICE 1_2_0
 VK_KHR_shared_presentable_image				DEVICE
 VK_KHR_external_fence						DEVICE 1_1_0
 VK_KHR_external_fence_win32					DEVICE
@@ -54,23 +54,29 @@
 VK_KHR_storage_buffer_storage_class			DEVICE 1_1_0
 VK_KHR_relaxed_block_layout					DEVICE 1_1_0
 VK_KHR_get_memory_requirements2				DEVICE 1_1_0
-VK_KHR_image_format_list					DEVICE
+VK_KHR_image_format_list					DEVICE 1_2_0
 VK_KHR_sampler_ycbcr_conversion				DEVICE 1_1_0
 VK_KHR_bind_memory2							DEVICE 1_1_0
 VK_KHR_maintenance3							DEVICE 1_1_0
-VK_KHR_driver_properties					DEVICE
-VK_KHR_shader_float_controls				DEVICE
-VK_KHR_depth_stencil_resolve				DEVICE
-VK_KHR_draw_indirect_count					DEVICE
-VK_KHR_shader_atomic_int64					DEVICE
-VK_KHR_vulkan_memory_model					DEVICE
-VK_KHR_uniform_buffer_standard_layout		DEVICE
-VK_KHR_imageless_framebuffer				DEVICE
+VK_KHR_driver_properties					DEVICE 1_2_0
+VK_KHR_shader_float_controls				DEVICE 1_2_0
+VK_KHR_depth_stencil_resolve				DEVICE 1_2_0
+VK_KHR_draw_indirect_count					DEVICE 1_2_0
+VK_KHR_shader_atomic_int64					DEVICE 1_2_0
+VK_KHR_vulkan_memory_model					DEVICE 1_2_0
+VK_KHR_uniform_buffer_standard_layout		DEVICE 1_2_0
+VK_KHR_imageless_framebuffer				DEVICE 1_2_0
+VK_KHR_shader_subgroup_extended_types		DEVICE 1_2_0
+VK_EXT_sampler_filter_minmax				DEVICE 1_2_0
+VK_EXT_shader_viewport_index_layer			DEVICE 1_2_0
+VK_EXT_descriptor_indexing					DEVICE 1_2_0
+VK_EXT_scalar_block_layout					DEVICE 1_2_0
+VK_KHR_buffer_device_address				DEVICE 1_2_0
+VK_EXT_host_query_reset						DEVICE 1_2_0
+VK_KHR_separate_depth_stencil_layouts		DEVICE 1_2_0
+VK_KHR_timeline_semaphore 		 		 	DEVICE 1_2_0
+VK_KHR_spirv_1_4 		 		 	 		DEVICE 1_2_0
+VK_EXT_separate_stencil_usage 		 		DEVICE 1_2_0
 VK_KHR_pipeline_executable_properties 		DEVICE
-VK_KHR_timeline_semaphore					DEVICE
 VK_KHR_shader_clock							DEVICE
-VK_KHR_spirv_1_4							DEVICE
-VK_KHR_shader_subgroup_extended_types		DEVICE
-VK_KHR_separate_depth_stencil_layouts		DEVICE
 VK_KHR_performance_query					DEVICE
-VK_KHR_buffer_device_address				DEVICE
\ No newline at end of file
diff --git a/external/vulkancts/scripts/src/mandatory_features.txt b/external/vulkancts/scripts/src/mandatory_features.txt
index 19e151c..643dd0b 100644
--- a/external/vulkancts/scripts/src/mandatory_features.txt
+++ b/external/vulkancts/scripts/src/mandatory_features.txt
@@ -10,6 +10,7 @@
 VkPhysicalDeviceFeatures								shaderSampledImageArrayDynamicIndexing				REQUIREMENTS ( VK_EXT_descriptor_indexing )
 VkPhysicalDeviceFeatures								shaderStorageBufferArrayDynamicIndexing				REQUIREMENTS ( VK_EXT_descriptor_indexing )
 VkPhysicalDevice8BitStorageFeaturesKHR					storageBuffer8BitAccess								REQUIREMENTS ( VK_KHR_8bit_storage )
+VkPhysicalDeviceVulkan11Features						multiview											REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
 VkPhysicalDeviceMultiviewFeatures						multiview											REQUIREMENTS ( "ApiVersion(1, 1, 0)" )
 VkPhysicalDeviceMultiviewFeatures						multiview											REQUIREMENTS ( VK_KHR_multiview )
 VkPhysicalDeviceVariablePointersFeatures				variablePointersStorageBuffer						REQUIREMENTS ( VK_KHR_variable_pointers )
@@ -31,4 +32,25 @@
 VkPhysicalDeviceScalarBlockLayoutFeaturesEXT			scalarBlockLayout									REQUIREMENTS ( VK_EXT_scalar_block_layout )
 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR	uniformBufferStandardLayout							REQUIREMENTS ( VK_KHR_uniform_buffer_standard_layout )
 VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR	pipelineExecutableInfo								REQUIREMENTS ( VK_KHR_pipeline_executable_properties )
+VkPhysicalDeviceSubgroupSizeControlFeaturesEXT			subgroupSizeControl									REQUIREMENTS ( VK_EXT_subgroup_size_control )
+VkPhysicalDeviceSubgroupSizeControlFeaturesEXT			computeFullSubgroups								REQUIREMENTS ( VK_EXT_subgroup_size_control )
+VkPhysicalDeviceVulkan12Features						subgroupBroadcastDynamicId							REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
+VkPhysicalDeviceVulkan12Features						imagelessFramebuffer								REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
+VkPhysicalDeviceVulkan12Features						uniformBufferStandardLayout							REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
+VkPhysicalDeviceVulkan12Features						separateDepthStencilLayouts							REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
+VkPhysicalDeviceVulkan12Features						hostQueryReset										REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
 VkPhysicalDeviceTimelineSemaphoreFeaturesKHR 			timelineSemaphore									REQUIREMENTS ( VK_KHR_timeline_semaphore )
+VkPhysicalDeviceVulkan12Features						timelineSemaphore									REQUIREMENTS ( "ApiVersion(1, 2, 0)" )
+VkPhysicalDeviceVulkan12Features						shaderUniformTexelBufferArrayDynamicIndexing		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						shaderStorageTexelBufferArrayDynamicIndexing		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						shaderSampledImageArrayNonUniformIndexing			REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						shaderStorageBufferArrayNonUniformIndexing			REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						shaderUniformTexelBufferArrayNonUniformIndexing		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingSampledImageUpdateAfterBind		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingStorageImageUpdateAfterBind		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingStorageBufferUpdateAfterBind		REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingUniformTexelBufferUpdateAfterBind	REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingStorageTexelBufferUpdateAfterBind	REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingUpdateUnusedWhilePending			REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						descriptorBindingPartiallyBound						REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
+VkPhysicalDeviceVulkan12Features						runtimeDescriptorArray								REQUIREMENTS ( "ApiVersion(1, 2, 0)" physicalDeviceVulkan12Features.descriptorIndexing )
diff --git a/external/vulkancts/scripts/src/vulkan_core.h b/external/vulkancts/scripts/src/vulkan_core.h
index f41ccf4..7fcbd61 100644
--- a/external/vulkancts/scripts/src/vulkan_core.h
+++ b/external/vulkancts/scripts/src/vulkan_core.h
@@ -44,7 +44,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 129
+#define VK_HEADER_VERSION 130
 
 
 #define VK_NULL_HANDLE 0
@@ -133,8 +133,11 @@
     VK_ERROR_TOO_MANY_OBJECTS = -10,
     VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
     VK_ERROR_FRAGMENTED_POOL = -12,
+    VK_ERROR_UNKNOWN = -13,
     VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000,
     VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003,
+    VK_ERROR_FRAGMENTATION = -1000161000,
+    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000,
     VK_ERROR_SURFACE_LOST_KHR = -1000000000,
     VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
     VK_SUBOPTIMAL_KHR = 1000001003,
@@ -143,16 +146,16 @@
     VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
     VK_ERROR_INVALID_SHADER_NV = -1000012000,
     VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000,
-    VK_ERROR_FRAGMENTATION_EXT = -1000161000,
     VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
     VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000,
-    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = -1000244000,
     VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
     VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
-    VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR,
-    VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
+    VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
+    VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+    VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+    VK_RESULT_BEGIN_RANGE = VK_ERROR_UNKNOWN,
     VK_RESULT_END_RANGE = VK_INCOMPLETE,
-    VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1),
+    VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_UNKNOWN + 1),
     VK_RESULT_MAX_ENUM = 0x7FFFFFFF
 } VkResult;
 
@@ -271,6 +274,56 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52,
+    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000,
+    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000,
+    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002,
+    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001,
+    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002,
+    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003,
+    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004,
+    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001,
+    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002,
+    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003,
+    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004,
     VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
     VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
     VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
@@ -330,7 +383,6 @@
     VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
     VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = 1000082000,
     VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
     VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
     VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
@@ -354,17 +406,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001,
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000,
-    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001,
-    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002,
-    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003,
-    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000,
-    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001,
-    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002,
-    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003,
-    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004,
-    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005,
-    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006,
     VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
     VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
     VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
@@ -399,8 +440,6 @@
     VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
     VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
     VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000,
-    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001,
     VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002,
@@ -410,7 +449,6 @@
     VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
     VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
-    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
     VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
@@ -426,11 +464,6 @@
     VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
     VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
     VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
     VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
@@ -451,12 +484,9 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000,
     VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001,
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = 1000175000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
     VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000,
     VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000,
     VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
@@ -467,10 +497,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
     VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000,
     VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000,
-    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
@@ -480,12 +506,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
     VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
     VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = 1000207000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = 1000207001,
-    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = 1000207002,
-    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = 1000207003,
-    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = 1000207004,
-    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = 1000207005,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000,
     VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = 1000210000,
     VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001,
@@ -493,7 +513,6 @@
     VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003,
     VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004,
     VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
     VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000,
     VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001,
@@ -502,7 +521,6 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
     VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000,
     VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002,
@@ -513,12 +531,9 @@
     VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
     VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = 1000241000,
-    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = 1000241001,
-    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = 1000241002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000,
     VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
-    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
     VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
     VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
@@ -528,20 +543,13 @@
     VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = 1000253000,
     VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000,
     VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
     VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001,
     VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = 1000257000,
-    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = 1000244001,
-    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = 1000257002,
-    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = 1000257003,
-    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = 1000257004,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = 1000261000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000,
     VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001,
@@ -587,10 +595,22 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
     VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
     VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
-    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
     VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
     VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
+    VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
     VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
     VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
@@ -602,11 +622,14 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES,
     VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
     VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
+    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
     VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
     VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
     VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
+    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
     VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
@@ -615,10 +638,41 @@
     VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
     VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
     VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
+    VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+    VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
+    VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+    VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
-    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+    VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
+    VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
+    VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
     VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
     VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
     VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
@@ -994,16 +1048,20 @@
     VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
+    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000,
+    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001,
+    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002,
+    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003,
     VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
     VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
     VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003,
     VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000,
-    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = 1000241000,
-    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = 1000241001,
-    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = 1000241002,
-    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = 1000241003,
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
+    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
+    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
+    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
     VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
     VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED,
     VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1),
@@ -1451,11 +1509,12 @@
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000,
     VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000,
     VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000,
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000,
-    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000,
     VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000,
     VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT,
     VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT,
     VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
     VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT,
@@ -1663,8 +1722,9 @@
     VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
     VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
     VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008,
-    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000010,
-    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+    VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
     VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferCreateFlagBits;
 typedef VkFlags VkBufferCreateFlags;
@@ -1679,12 +1739,13 @@
     VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
     VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000,
     VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800,
     VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000,
     VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
     VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400,
-    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000,
-    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+    VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
     VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferUsageFlagBits;
 typedef VkFlags VkBufferUsageFlags;
@@ -1782,22 +1843,25 @@
 typedef VkFlags VkSamplerCreateFlags;
 
 typedef enum VkDescriptorSetLayoutCreateFlagBits {
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002,
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
-    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002,
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorSetLayoutCreateFlagBits;
 typedef VkFlags VkDescriptorSetLayoutCreateFlags;
 
 typedef enum VkDescriptorPoolCreateFlagBits {
     VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
-    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002,
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002,
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
     VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorPoolCreateFlagBits;
 typedef VkFlags VkDescriptorPoolCreateFlags;
 typedef VkFlags VkDescriptorPoolResetFlags;
 
 typedef enum VkFramebufferCreateFlagBits {
-    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001,
+    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001,
+    VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,
     VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkFramebufferCreateFlagBits;
 typedef VkFlags VkFramebufferCreateFlags;
@@ -4068,9 +4132,11 @@
 
 typedef enum VkMemoryAllocateFlagBits {
     VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001,
-    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = 0x00000002,
-    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000004,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004,
     VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
+    VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
     VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkMemoryAllocateFlagBits;
 typedef VkFlags VkMemoryAllocateFlags;
@@ -4837,6 +4903,760 @@
 #endif
 
 
+#define VK_VERSION_1_2 1
+// Vulkan 1.2 version number
+#define VK_API_VERSION_1_2 VK_MAKE_VERSION(1, 2, 0)// Patch version should always be set to 0
+
+typedef uint64_t VkDeviceAddress;
+#define VK_MAX_DRIVER_NAME_SIZE           256
+#define VK_MAX_DRIVER_INFO_SIZE           256
+
+typedef enum VkDriverId {
+    VK_DRIVER_ID_AMD_PROPRIETARY = 1,
+    VK_DRIVER_ID_AMD_OPEN_SOURCE = 2,
+    VK_DRIVER_ID_MESA_RADV = 3,
+    VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4,
+    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5,
+    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6,
+    VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7,
+    VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8,
+    VK_DRIVER_ID_ARM_PROPRIETARY = 9,
+    VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10,
+    VK_DRIVER_ID_GGP_PROPRIETARY = 11,
+    VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12,
+    VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
+    VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
+    VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
+    VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY,
+    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
+    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
+    VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
+    VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+    VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY,
+    VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
+    VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY,
+    VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+    VK_DRIVER_ID_BEGIN_RANGE = VK_DRIVER_ID_AMD_PROPRIETARY,
+    VK_DRIVER_ID_END_RANGE = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+    VK_DRIVER_ID_RANGE_SIZE = (VK_DRIVER_ID_BROADCOM_PROPRIETARY - VK_DRIVER_ID_AMD_PROPRIETARY + 1),
+    VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF
+} VkDriverId;
+
+typedef enum VkShaderFloatControlsIndependence {
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_BEGIN_RANGE = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_END_RANGE = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_RANGE_SIZE = (VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY + 1),
+    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF
+} VkShaderFloatControlsIndependence;
+
+typedef enum VkSamplerReductionMode {
+    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0,
+    VK_SAMPLER_REDUCTION_MODE_MIN = 1,
+    VK_SAMPLER_REDUCTION_MODE_MAX = 2,
+    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+    VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN,
+    VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX,
+    VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+    VK_SAMPLER_REDUCTION_MODE_END_RANGE = VK_SAMPLER_REDUCTION_MODE_MAX,
+    VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE = (VK_SAMPLER_REDUCTION_MODE_MAX - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE + 1),
+    VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerReductionMode;
+
+typedef enum VkSemaphoreType {
+    VK_SEMAPHORE_TYPE_BINARY = 0,
+    VK_SEMAPHORE_TYPE_TIMELINE = 1,
+    VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY,
+    VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE,
+    VK_SEMAPHORE_TYPE_BEGIN_RANGE = VK_SEMAPHORE_TYPE_BINARY,
+    VK_SEMAPHORE_TYPE_END_RANGE = VK_SEMAPHORE_TYPE_TIMELINE,
+    VK_SEMAPHORE_TYPE_RANGE_SIZE = (VK_SEMAPHORE_TYPE_TIMELINE - VK_SEMAPHORE_TYPE_BINARY + 1),
+    VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreType;
+
+typedef enum VkResolveModeFlagBits {
+    VK_RESOLVE_MODE_NONE = 0,
+    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001,
+    VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002,
+    VK_RESOLVE_MODE_MIN_BIT = 0x00000004,
+    VK_RESOLVE_MODE_MAX_BIT = 0x00000008,
+    VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE,
+    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+    VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT,
+    VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT,
+    VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT,
+    VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkResolveModeFlagBits;
+typedef VkFlags VkResolveModeFlags;
+
+typedef enum VkDescriptorBindingFlagBits {
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
+    VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorBindingFlagBits;
+typedef VkFlags VkDescriptorBindingFlags;
+
+typedef enum VkSemaphoreWaitFlagBits {
+    VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001,
+    VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT,
+    VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreWaitFlagBits;
+typedef VkFlags VkSemaphoreWaitFlags;
+typedef struct VkPhysicalDeviceVulkan11Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           storageBuffer16BitAccess;
+    VkBool32           uniformAndStorageBuffer16BitAccess;
+    VkBool32           storagePushConstant16;
+    VkBool32           storageInputOutput16;
+    VkBool32           multiview;
+    VkBool32           multiviewGeometryShader;
+    VkBool32           multiviewTessellationShader;
+    VkBool32           variablePointersStorageBuffer;
+    VkBool32           variablePointers;
+    VkBool32           protectedMemory;
+    VkBool32           samplerYcbcrConversion;
+    VkBool32           shaderDrawParameters;
+} VkPhysicalDeviceVulkan11Features;
+
+typedef struct VkPhysicalDeviceVulkan11Properties {
+    VkStructureType            sType;
+    void*                      pNext;
+    uint8_t                    deviceUUID[VK_UUID_SIZE];
+    uint8_t                    driverUUID[VK_UUID_SIZE];
+    uint8_t                    deviceLUID[VK_LUID_SIZE];
+    uint32_t                   deviceNodeMask;
+    VkBool32                   deviceLUIDValid;
+    uint32_t                   subgroupSize;
+    VkShaderStageFlags         subgroupSupportedStages;
+    VkSubgroupFeatureFlags     subgroupSupportedOperations;
+    VkBool32                   subgroupQuadOperationsInAllStages;
+    VkPointClippingBehavior    pointClippingBehavior;
+    uint32_t                   maxMultiviewViewCount;
+    uint32_t                   maxMultiviewInstanceIndex;
+    VkBool32                   protectedNoFault;
+    uint32_t                   maxPerSetDescriptors;
+    VkDeviceSize               maxMemoryAllocationSize;
+} VkPhysicalDeviceVulkan11Properties;
+
+typedef struct VkPhysicalDeviceVulkan12Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           samplerMirrorClampToEdge;
+    VkBool32           drawIndirectCount;
+    VkBool32           storageBuffer8BitAccess;
+    VkBool32           uniformAndStorageBuffer8BitAccess;
+    VkBool32           storagePushConstant8;
+    VkBool32           shaderBufferInt64Atomics;
+    VkBool32           shaderSharedInt64Atomics;
+    VkBool32           shaderFloat16;
+    VkBool32           shaderInt8;
+    VkBool32           descriptorIndexing;
+    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
+    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
+    VkBool32           shaderSampledImageArrayNonUniformIndexing;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageImageArrayNonUniformIndexing;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
+    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
+    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
+    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUpdateUnusedWhilePending;
+    VkBool32           descriptorBindingPartiallyBound;
+    VkBool32           descriptorBindingVariableDescriptorCount;
+    VkBool32           runtimeDescriptorArray;
+    VkBool32           samplerFilterMinmax;
+    VkBool32           scalarBlockLayout;
+    VkBool32           imagelessFramebuffer;
+    VkBool32           uniformBufferStandardLayout;
+    VkBool32           shaderSubgroupExtendedTypes;
+    VkBool32           separateDepthStencilLayouts;
+    VkBool32           hostQueryReset;
+    VkBool32           timelineSemaphore;
+    VkBool32           bufferDeviceAddress;
+    VkBool32           bufferDeviceAddressCaptureReplay;
+    VkBool32           bufferDeviceAddressMultiDevice;
+    VkBool32           vulkanMemoryModel;
+    VkBool32           vulkanMemoryModelDeviceScope;
+    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
+    VkBool32           shaderOutputViewportIndex;
+    VkBool32           shaderOutputLayer;
+    VkBool32           subgroupBroadcastDynamicId;
+} VkPhysicalDeviceVulkan12Features;
+
+typedef struct VkConformanceVersion {
+    uint8_t    major;
+    uint8_t    minor;
+    uint8_t    subminor;
+    uint8_t    patch;
+} VkConformanceVersion;
+
+typedef struct VkPhysicalDeviceVulkan12Properties {
+    VkStructureType                      sType;
+    void*                                pNext;
+    VkDriverId                           driverID;
+    char                                 driverName[VK_MAX_DRIVER_NAME_SIZE];
+    char                                 driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+    VkConformanceVersion                 conformanceVersion;
+    VkShaderFloatControlsIndependence    denormBehaviorIndependence;
+    VkShaderFloatControlsIndependence    roundingModeIndependence;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat16;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat32;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat64;
+    VkBool32                             shaderDenormPreserveFloat16;
+    VkBool32                             shaderDenormPreserveFloat32;
+    VkBool32                             shaderDenormPreserveFloat64;
+    VkBool32                             shaderDenormFlushToZeroFloat16;
+    VkBool32                             shaderDenormFlushToZeroFloat32;
+    VkBool32                             shaderDenormFlushToZeroFloat64;
+    VkBool32                             shaderRoundingModeRTEFloat16;
+    VkBool32                             shaderRoundingModeRTEFloat32;
+    VkBool32                             shaderRoundingModeRTEFloat64;
+    VkBool32                             shaderRoundingModeRTZFloat16;
+    VkBool32                             shaderRoundingModeRTZFloat32;
+    VkBool32                             shaderRoundingModeRTZFloat64;
+    uint32_t                             maxUpdateAfterBindDescriptorsInAllPools;
+    VkBool32                             shaderUniformBufferArrayNonUniformIndexingNative;
+    VkBool32                             shaderSampledImageArrayNonUniformIndexingNative;
+    VkBool32                             shaderStorageBufferArrayNonUniformIndexingNative;
+    VkBool32                             shaderStorageImageArrayNonUniformIndexingNative;
+    VkBool32                             shaderInputAttachmentArrayNonUniformIndexingNative;
+    VkBool32                             robustBufferAccessUpdateAfterBind;
+    VkBool32                             quadDivergentImplicitLod;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindSamplers;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindSampledImages;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindStorageImages;
+    uint32_t                             maxPerStageDescriptorUpdateAfterBindInputAttachments;
+    uint32_t                             maxPerStageUpdateAfterBindResources;
+    uint32_t                             maxDescriptorSetUpdateAfterBindSamplers;
+    uint32_t                             maxDescriptorSetUpdateAfterBindUniformBuffers;
+    uint32_t                             maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+    uint32_t                             maxDescriptorSetUpdateAfterBindStorageBuffers;
+    uint32_t                             maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+    uint32_t                             maxDescriptorSetUpdateAfterBindSampledImages;
+    uint32_t                             maxDescriptorSetUpdateAfterBindStorageImages;
+    uint32_t                             maxDescriptorSetUpdateAfterBindInputAttachments;
+    VkResolveModeFlags                   supportedDepthResolveModes;
+    VkResolveModeFlags                   supportedStencilResolveModes;
+    VkBool32                             independentResolveNone;
+    VkBool32                             independentResolve;
+    VkBool32                             filterMinmaxSingleComponentFormats;
+    VkBool32                             filterMinmaxImageComponentMapping;
+    uint64_t                             maxTimelineSemaphoreValueDifference;
+    VkSampleCountFlags                   framebufferIntegerColorSampleCounts;
+} VkPhysicalDeviceVulkan12Properties;
+
+typedef struct VkImageFormatListCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           viewFormatCount;
+    const VkFormat*    pViewFormats;
+} VkImageFormatListCreateInfo;
+
+typedef struct VkAttachmentDescription2 {
+    VkStructureType                 sType;
+    const void*                     pNext;
+    VkAttachmentDescriptionFlags    flags;
+    VkFormat                        format;
+    VkSampleCountFlagBits           samples;
+    VkAttachmentLoadOp              loadOp;
+    VkAttachmentStoreOp             storeOp;
+    VkAttachmentLoadOp              stencilLoadOp;
+    VkAttachmentStoreOp             stencilStoreOp;
+    VkImageLayout                   initialLayout;
+    VkImageLayout                   finalLayout;
+} VkAttachmentDescription2;
+
+typedef struct VkAttachmentReference2 {
+    VkStructureType       sType;
+    const void*           pNext;
+    uint32_t              attachment;
+    VkImageLayout         layout;
+    VkImageAspectFlags    aspectMask;
+} VkAttachmentReference2;
+
+typedef struct VkSubpassDescription2 {
+    VkStructureType                  sType;
+    const void*                      pNext;
+    VkSubpassDescriptionFlags        flags;
+    VkPipelineBindPoint              pipelineBindPoint;
+    uint32_t                         viewMask;
+    uint32_t                         inputAttachmentCount;
+    const VkAttachmentReference2*    pInputAttachments;
+    uint32_t                         colorAttachmentCount;
+    const VkAttachmentReference2*    pColorAttachments;
+    const VkAttachmentReference2*    pResolveAttachments;
+    const VkAttachmentReference2*    pDepthStencilAttachment;
+    uint32_t                         preserveAttachmentCount;
+    const uint32_t*                  pPreserveAttachments;
+} VkSubpassDescription2;
+
+typedef struct VkSubpassDependency2 {
+    VkStructureType         sType;
+    const void*             pNext;
+    uint32_t                srcSubpass;
+    uint32_t                dstSubpass;
+    VkPipelineStageFlags    srcStageMask;
+    VkPipelineStageFlags    dstStageMask;
+    VkAccessFlags           srcAccessMask;
+    VkAccessFlags           dstAccessMask;
+    VkDependencyFlags       dependencyFlags;
+    int32_t                 viewOffset;
+} VkSubpassDependency2;
+
+typedef struct VkRenderPassCreateInfo2 {
+    VkStructureType                    sType;
+    const void*                        pNext;
+    VkRenderPassCreateFlags            flags;
+    uint32_t                           attachmentCount;
+    const VkAttachmentDescription2*    pAttachments;
+    uint32_t                           subpassCount;
+    const VkSubpassDescription2*       pSubpasses;
+    uint32_t                           dependencyCount;
+    const VkSubpassDependency2*        pDependencies;
+    uint32_t                           correlatedViewMaskCount;
+    const uint32_t*                    pCorrelatedViewMasks;
+} VkRenderPassCreateInfo2;
+
+typedef struct VkSubpassBeginInfo {
+    VkStructureType      sType;
+    const void*          pNext;
+    VkSubpassContents    contents;
+} VkSubpassBeginInfo;
+
+typedef struct VkSubpassEndInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+} VkSubpassEndInfo;
+
+typedef struct VkPhysicalDevice8BitStorageFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           storageBuffer8BitAccess;
+    VkBool32           uniformAndStorageBuffer8BitAccess;
+    VkBool32           storagePushConstant8;
+} VkPhysicalDevice8BitStorageFeatures;
+
+typedef struct VkPhysicalDeviceDriverProperties {
+    VkStructureType         sType;
+    void*                   pNext;
+    VkDriverId              driverID;
+    char                    driverName[VK_MAX_DRIVER_NAME_SIZE];
+    char                    driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+    VkConformanceVersion    conformanceVersion;
+} VkPhysicalDeviceDriverProperties;
+
+typedef struct VkPhysicalDeviceShaderAtomicInt64Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderBufferInt64Atomics;
+    VkBool32           shaderSharedInt64Atomics;
+} VkPhysicalDeviceShaderAtomicInt64Features;
+
+typedef struct VkPhysicalDeviceShaderFloat16Int8Features {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderFloat16;
+    VkBool32           shaderInt8;
+} VkPhysicalDeviceShaderFloat16Int8Features;
+
+typedef struct VkPhysicalDeviceFloatControlsProperties {
+    VkStructureType                      sType;
+    void*                                pNext;
+    VkShaderFloatControlsIndependence    denormBehaviorIndependence;
+    VkShaderFloatControlsIndependence    roundingModeIndependence;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat16;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat32;
+    VkBool32                             shaderSignedZeroInfNanPreserveFloat64;
+    VkBool32                             shaderDenormPreserveFloat16;
+    VkBool32                             shaderDenormPreserveFloat32;
+    VkBool32                             shaderDenormPreserveFloat64;
+    VkBool32                             shaderDenormFlushToZeroFloat16;
+    VkBool32                             shaderDenormFlushToZeroFloat32;
+    VkBool32                             shaderDenormFlushToZeroFloat64;
+    VkBool32                             shaderRoundingModeRTEFloat16;
+    VkBool32                             shaderRoundingModeRTEFloat32;
+    VkBool32                             shaderRoundingModeRTEFloat64;
+    VkBool32                             shaderRoundingModeRTZFloat16;
+    VkBool32                             shaderRoundingModeRTZFloat32;
+    VkBool32                             shaderRoundingModeRTZFloat64;
+} VkPhysicalDeviceFloatControlsProperties;
+
+typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo {
+    VkStructureType                    sType;
+    const void*                        pNext;
+    uint32_t                           bindingCount;
+    const VkDescriptorBindingFlags*    pBindingFlags;
+} VkDescriptorSetLayoutBindingFlagsCreateInfo;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
+    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
+    VkBool32           shaderSampledImageArrayNonUniformIndexing;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageImageArrayNonUniformIndexing;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
+    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
+    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
+    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUpdateUnusedWhilePending;
+    VkBool32           descriptorBindingPartiallyBound;
+    VkBool32           descriptorBindingVariableDescriptorCount;
+    VkBool32           runtimeDescriptorArray;
+} VkPhysicalDeviceDescriptorIndexingFeatures;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxUpdateAfterBindDescriptorsInAllPools;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
+    VkBool32           robustBufferAccessUpdateAfterBind;
+    VkBool32           quadDivergentImplicitLod;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindSamplers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindSampledImages;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageImages;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindInputAttachments;
+    uint32_t           maxPerStageUpdateAfterBindResources;
+    uint32_t           maxDescriptorSetUpdateAfterBindSamplers;
+    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffers;
+    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffers;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+    uint32_t           maxDescriptorSetUpdateAfterBindSampledImages;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageImages;
+    uint32_t           maxDescriptorSetUpdateAfterBindInputAttachments;
+} VkPhysicalDeviceDescriptorIndexingProperties;
+
+typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           descriptorSetCount;
+    const uint32_t*    pDescriptorCounts;
+} VkDescriptorSetVariableDescriptorCountAllocateInfo;
+
+typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxVariableDescriptorCount;
+} VkDescriptorSetVariableDescriptorCountLayoutSupport;
+
+typedef struct VkSubpassDescriptionDepthStencilResolve {
+    VkStructureType                  sType;
+    const void*                      pNext;
+    VkResolveModeFlagBits            depthResolveMode;
+    VkResolveModeFlagBits            stencilResolveMode;
+    const VkAttachmentReference2*    pDepthStencilResolveAttachment;
+} VkSubpassDescriptionDepthStencilResolve;
+
+typedef struct VkPhysicalDeviceDepthStencilResolveProperties {
+    VkStructureType       sType;
+    void*                 pNext;
+    VkResolveModeFlags    supportedDepthResolveModes;
+    VkResolveModeFlags    supportedStencilResolveModes;
+    VkBool32              independentResolveNone;
+    VkBool32              independentResolve;
+} VkPhysicalDeviceDepthStencilResolveProperties;
+
+typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           scalarBlockLayout;
+} VkPhysicalDeviceScalarBlockLayoutFeatures;
+
+typedef struct VkImageStencilUsageCreateInfo {
+    VkStructureType      sType;
+    const void*          pNext;
+    VkImageUsageFlags    stencilUsage;
+} VkImageStencilUsageCreateInfo;
+
+typedef struct VkSamplerReductionModeCreateInfo {
+    VkStructureType           sType;
+    const void*               pNext;
+    VkSamplerReductionMode    reductionMode;
+} VkSamplerReductionModeCreateInfo;
+
+typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           filterMinmaxSingleComponentFormats;
+    VkBool32           filterMinmaxImageComponentMapping;
+} VkPhysicalDeviceSamplerFilterMinmaxProperties;
+
+typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           vulkanMemoryModel;
+    VkBool32           vulkanMemoryModelDeviceScope;
+    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
+} VkPhysicalDeviceVulkanMemoryModelFeatures;
+
+typedef struct VkPhysicalDeviceImagelessFramebufferFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           imagelessFramebuffer;
+} VkPhysicalDeviceImagelessFramebufferFeatures;
+
+typedef struct VkFramebufferAttachmentImageInfo {
+    VkStructureType       sType;
+    const void*           pNext;
+    VkImageCreateFlags    flags;
+    VkImageUsageFlags     usage;
+    uint32_t              width;
+    uint32_t              height;
+    uint32_t              layerCount;
+    uint32_t              viewFormatCount;
+    const VkFormat*       pViewFormats;
+} VkFramebufferAttachmentImageInfo;
+
+typedef struct VkFramebufferAttachmentsCreateInfo {
+    VkStructureType                            sType;
+    const void*                                pNext;
+    uint32_t                                   attachmentImageInfoCount;
+    const VkFramebufferAttachmentImageInfo*    pAttachmentImageInfos;
+} VkFramebufferAttachmentsCreateInfo;
+
+typedef struct VkRenderPassAttachmentBeginInfo {
+    VkStructureType       sType;
+    const void*           pNext;
+    uint32_t              attachmentCount;
+    const VkImageView*    pAttachments;
+} VkRenderPassAttachmentBeginInfo;
+
+typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           uniformBufferStandardLayout;
+} VkPhysicalDeviceUniformBufferStandardLayoutFeatures;
+
+typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderSubgroupExtendedTypes;
+} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures;
+
+typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           separateDepthStencilLayouts;
+} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures;
+
+typedef struct VkAttachmentReferenceStencilLayout {
+    VkStructureType    sType;
+    void*              pNext;
+    VkImageLayout      stencilLayout;
+} VkAttachmentReferenceStencilLayout;
+
+typedef struct VkAttachmentDescriptionStencilLayout {
+    VkStructureType    sType;
+    void*              pNext;
+    VkImageLayout      stencilInitialLayout;
+    VkImageLayout      stencilFinalLayout;
+} VkAttachmentDescriptionStencilLayout;
+
+typedef struct VkPhysicalDeviceHostQueryResetFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           hostQueryReset;
+} VkPhysicalDeviceHostQueryResetFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           timelineSemaphore;
+} VkPhysicalDeviceTimelineSemaphoreFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreProperties {
+    VkStructureType    sType;
+    void*              pNext;
+    uint64_t           maxTimelineSemaphoreValueDifference;
+} VkPhysicalDeviceTimelineSemaphoreProperties;
+
+typedef struct VkSemaphoreTypeCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkSemaphoreType    semaphoreType;
+    uint64_t           initialValue;
+} VkSemaphoreTypeCreateInfo;
+
+typedef struct VkTimelineSemaphoreSubmitInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           waitSemaphoreValueCount;
+    const uint64_t*    pWaitSemaphoreValues;
+    uint32_t           signalSemaphoreValueCount;
+    const uint64_t*    pSignalSemaphoreValues;
+} VkTimelineSemaphoreSubmitInfo;
+
+typedef struct VkSemaphoreWaitInfo {
+    VkStructureType         sType;
+    const void*             pNext;
+    VkSemaphoreWaitFlags    flags;
+    uint32_t                semaphoreCount;
+    const VkSemaphore*      pSemaphores;
+    const uint64_t*         pValues;
+} VkSemaphoreWaitInfo;
+
+typedef struct VkSemaphoreSignalInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkSemaphore        semaphore;
+    uint64_t           value;
+} VkSemaphoreSignalInfo;
+
+typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           bufferDeviceAddress;
+    VkBool32           bufferDeviceAddressCaptureReplay;
+    VkBool32           bufferDeviceAddressMultiDevice;
+} VkPhysicalDeviceBufferDeviceAddressFeatures;
+
+typedef struct VkBufferDeviceAddressInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBuffer           buffer;
+} VkBufferDeviceAddressInfo;
+
+typedef struct VkBufferOpaqueCaptureAddressCreateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint64_t           opaqueCaptureAddress;
+} VkBufferOpaqueCaptureAddressCreateInfo;
+
+typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint64_t           opaqueCaptureAddress;
+} VkMemoryOpaqueCaptureAddressAllocateInfo;
+
+typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkDeviceMemory     memory;
+} VkDeviceMemoryOpaqueCaptureAddressInfo;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfo*      pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo*      pSubpassBeginInfo, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2(
+    VkDevice                                    device,
+    const VkRenderPassCreateInfo2*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkResetQueryPool(
+    VkDevice                                    device,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    firstQuery,
+    uint32_t                                    queryCount);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore,
+    uint64_t*                                   pValue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores(
+    VkDevice                                    device,
+    const VkSemaphoreWaitInfo*                  pWaitInfo,
+    uint64_t                                    timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore(
+    VkDevice                                    device,
+    const VkSemaphoreSignalInfo*                pSignalInfo);
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress(
+    VkDevice                                    device,
+    const VkBufferDeviceAddressInfo*            pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress(
+    VkDevice                                    device,
+    const VkBufferDeviceAddressInfo*            pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress(
+    VkDevice                                    device,
+    const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+#endif
+
+
 #define VK_KHR_surface 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
 #define VK_KHR_SURFACE_SPEC_VERSION       25
@@ -5624,14 +6444,9 @@
 #define VK_KHR_shader_float16_int8 1
 #define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1
 #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8"
-typedef struct VkPhysicalDeviceShaderFloat16Int8FeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderFloat16;
-    VkBool32           shaderInt8;
-} VkPhysicalDeviceShaderFloat16Int8FeaturesKHR;
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR;
 
-typedef VkPhysicalDeviceShaderFloat16Int8FeaturesKHR VkPhysicalDeviceFloat16Int8FeaturesKHR;
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR;
 
 
 
@@ -5705,144 +6520,58 @@
 #define VK_KHR_imageless_framebuffer 1
 #define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1
 #define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer"
-typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           imagelessFramebuffer;
-} VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
+typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
 
-typedef struct VkFramebufferAttachmentImageInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    VkImageCreateFlags    flags;
-    VkImageUsageFlags     usage;
-    uint32_t              width;
-    uint32_t              height;
-    uint32_t              layerCount;
-    uint32_t              viewFormatCount;
-    const VkFormat*       pViewFormats;
-} VkFramebufferAttachmentImageInfoKHR;
+typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR;
 
-typedef struct VkFramebufferAttachmentsCreateInfoKHR {
-    VkStructureType                               sType;
-    const void*                                   pNext;
-    uint32_t                                      attachmentImageInfoCount;
-    const VkFramebufferAttachmentImageInfoKHR*    pAttachmentImageInfos;
-} VkFramebufferAttachmentsCreateInfoKHR;
+typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR;
 
-typedef struct VkRenderPassAttachmentBeginInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    uint32_t              attachmentCount;
-    const VkImageView*    pAttachments;
-} VkRenderPassAttachmentBeginInfoKHR;
+typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR;
 
 
 
 #define VK_KHR_create_renderpass2 1
 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1
 #define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2"
-typedef struct VkAttachmentDescription2KHR {
-    VkStructureType                 sType;
-    const void*                     pNext;
-    VkAttachmentDescriptionFlags    flags;
-    VkFormat                        format;
-    VkSampleCountFlagBits           samples;
-    VkAttachmentLoadOp              loadOp;
-    VkAttachmentStoreOp             storeOp;
-    VkAttachmentLoadOp              stencilLoadOp;
-    VkAttachmentStoreOp             stencilStoreOp;
-    VkImageLayout                   initialLayout;
-    VkImageLayout                   finalLayout;
-} VkAttachmentDescription2KHR;
+typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR;
 
-typedef struct VkAttachmentReference2KHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    uint32_t              attachment;
-    VkImageLayout         layout;
-    VkImageAspectFlags    aspectMask;
-} VkAttachmentReference2KHR;
+typedef VkAttachmentDescription2 VkAttachmentDescription2KHR;
 
-typedef struct VkSubpassDescription2KHR {
-    VkStructureType                     sType;
-    const void*                         pNext;
-    VkSubpassDescriptionFlags           flags;
-    VkPipelineBindPoint                 pipelineBindPoint;
-    uint32_t                            viewMask;
-    uint32_t                            inputAttachmentCount;
-    const VkAttachmentReference2KHR*    pInputAttachments;
-    uint32_t                            colorAttachmentCount;
-    const VkAttachmentReference2KHR*    pColorAttachments;
-    const VkAttachmentReference2KHR*    pResolveAttachments;
-    const VkAttachmentReference2KHR*    pDepthStencilAttachment;
-    uint32_t                            preserveAttachmentCount;
-    const uint32_t*                     pPreserveAttachments;
-} VkSubpassDescription2KHR;
+typedef VkAttachmentReference2 VkAttachmentReference2KHR;
 
-typedef struct VkSubpassDependency2KHR {
-    VkStructureType         sType;
-    const void*             pNext;
-    uint32_t                srcSubpass;
-    uint32_t                dstSubpass;
-    VkPipelineStageFlags    srcStageMask;
-    VkPipelineStageFlags    dstStageMask;
-    VkAccessFlags           srcAccessMask;
-    VkAccessFlags           dstAccessMask;
-    VkDependencyFlags       dependencyFlags;
-    int32_t                 viewOffset;
-} VkSubpassDependency2KHR;
+typedef VkSubpassDescription2 VkSubpassDescription2KHR;
 
-typedef struct VkRenderPassCreateInfo2KHR {
-    VkStructureType                       sType;
-    const void*                           pNext;
-    VkRenderPassCreateFlags               flags;
-    uint32_t                              attachmentCount;
-    const VkAttachmentDescription2KHR*    pAttachments;
-    uint32_t                              subpassCount;
-    const VkSubpassDescription2KHR*       pSubpasses;
-    uint32_t                              dependencyCount;
-    const VkSubpassDependency2KHR*        pDependencies;
-    uint32_t                              correlatedViewMaskCount;
-    const uint32_t*                       pCorrelatedViewMasks;
-} VkRenderPassCreateInfo2KHR;
+typedef VkSubpassDependency2 VkSubpassDependency2KHR;
 
-typedef struct VkSubpassBeginInfoKHR {
-    VkStructureType      sType;
-    const void*          pNext;
-    VkSubpassContents    contents;
-} VkSubpassBeginInfoKHR;
+typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR;
 
-typedef struct VkSubpassEndInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-} VkSubpassEndInfoKHR;
+typedef VkSubpassEndInfo VkSubpassEndInfoKHR;
 
-typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
-typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo);
-typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
-typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfo*      pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo*      pSubpassBeginInfo, const VkSubpassEndInfo*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo*        pSubpassEndInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(
     VkDevice                                    device,
-    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+    const VkRenderPassCreateInfo2*              pCreateInfo,
     const VkAllocationCallbacks*                pAllocator,
     VkRenderPass*                               pRenderPass);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR(
     VkCommandBuffer                             commandBuffer,
     const VkRenderPassBeginInfo*                pRenderPassBegin,
-    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo);
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR(
     VkCommandBuffer                             commandBuffer,
-    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
-    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo,
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR(
     VkCommandBuffer                             commandBuffer,
-    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+    const VkSubpassEndInfo*                     pSubpassEndInfo);
 #endif
 
 
@@ -5957,12 +6686,15 @@
 } VkPerformanceCounterUnitKHR;
 
 typedef enum VkPerformanceCounterScopeKHR {
-    VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = 0,
-    VK_QUERY_SCOPE_RENDER_PASS_KHR = 1,
-    VK_QUERY_SCOPE_COMMAND_KHR = 2,
-    VK_PERFORMANCE_COUNTER_SCOPE_BEGIN_RANGE_KHR = VK_QUERY_SCOPE_COMMAND_BUFFER_KHR,
-    VK_PERFORMANCE_COUNTER_SCOPE_END_RANGE_KHR = VK_QUERY_SCOPE_COMMAND_KHR,
-    VK_PERFORMANCE_COUNTER_SCOPE_RANGE_SIZE_KHR = (VK_QUERY_SCOPE_COMMAND_KHR - VK_QUERY_SCOPE_COMMAND_BUFFER_KHR + 1),
+    VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0,
+    VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1,
+    VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2,
+    VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+    VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR,
+    VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_BEGIN_RANGE_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_END_RANGE_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
+    VK_PERFORMANCE_COUNTER_SCOPE_RANGE_SIZE_KHR = (VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR - VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR + 1),
     VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF
 } VkPerformanceCounterScopeKHR;
 
@@ -6263,12 +6995,7 @@
 #define VK_KHR_image_format_list 1
 #define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1
 #define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list"
-typedef struct VkImageFormatListCreateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    uint32_t           viewFormatCount;
-    const VkFormat*    pViewFormats;
-} VkImageFormatListCreateInfoKHR;
+typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR;
 
 
 
@@ -6382,36 +7109,21 @@
 #define VK_KHR_shader_subgroup_extended_types 1
 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1
 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types"
-typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderSubgroupExtendedTypes;
-} VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
+typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
 
 
 
 #define VK_KHR_8bit_storage 1
 #define VK_KHR_8BIT_STORAGE_SPEC_VERSION  1
 #define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
-typedef struct VkPhysicalDevice8BitStorageFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           storageBuffer8BitAccess;
-    VkBool32           uniformAndStorageBuffer8BitAccess;
-    VkBool32           storagePushConstant8;
-} VkPhysicalDevice8BitStorageFeaturesKHR;
+typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR;
 
 
 
 #define VK_KHR_shader_atomic_int64 1
 #define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1
 #define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64"
-typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderBufferInt64Atomics;
-    VkBool32           shaderSharedInt64Atomics;
-} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
+typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
 
 
 
@@ -6428,113 +7140,37 @@
 
 
 #define VK_KHR_driver_properties 1
-#define VK_MAX_DRIVER_NAME_SIZE_KHR       256
-#define VK_MAX_DRIVER_INFO_SIZE_KHR       256
 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1
 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties"
+#define VK_MAX_DRIVER_NAME_SIZE_KHR       VK_MAX_DRIVER_NAME_SIZE
+#define VK_MAX_DRIVER_INFO_SIZE_KHR       VK_MAX_DRIVER_INFO_SIZE
+typedef VkDriverId VkDriverIdKHR;
 
-typedef enum VkDriverIdKHR {
-    VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1,
-    VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2,
-    VK_DRIVER_ID_MESA_RADV_KHR = 3,
-    VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4,
-    VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5,
-    VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6,
-    VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
-    VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
-    VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
-    VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = 10,
-    VK_DRIVER_ID_GGP_PROPRIETARY_KHR = 11,
-    VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = 12,
-    VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR,
-    VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR,
-    VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1),
-    VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkDriverIdKHR;
-typedef struct VkConformanceVersionKHR {
-    uint8_t    major;
-    uint8_t    minor;
-    uint8_t    subminor;
-    uint8_t    patch;
-} VkConformanceVersionKHR;
+typedef VkConformanceVersion VkConformanceVersionKHR;
 
-typedef struct VkPhysicalDeviceDriverPropertiesKHR {
-    VkStructureType            sType;
-    void*                      pNext;
-    VkDriverIdKHR              driverID;
-    char                       driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
-    char                       driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
-    VkConformanceVersionKHR    conformanceVersion;
-} VkPhysicalDeviceDriverPropertiesKHR;
+typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR;
 
 
 
 #define VK_KHR_shader_float_controls 1
 #define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4
 #define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls"
+typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR;
 
-typedef enum VkShaderFloatControlsIndependenceKHR {
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = 0,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = 1,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = 2,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_BEGIN_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_END_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR,
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_RANGE_SIZE_KHR = (VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR + 1),
-    VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkShaderFloatControlsIndependenceKHR;
-typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR {
-    VkStructureType                         sType;
-    void*                                   pNext;
-    VkShaderFloatControlsIndependenceKHR    denormBehaviorIndependence;
-    VkShaderFloatControlsIndependenceKHR    roundingModeIndependence;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat16;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat32;
-    VkBool32                                shaderSignedZeroInfNanPreserveFloat64;
-    VkBool32                                shaderDenormPreserveFloat16;
-    VkBool32                                shaderDenormPreserveFloat32;
-    VkBool32                                shaderDenormPreserveFloat64;
-    VkBool32                                shaderDenormFlushToZeroFloat16;
-    VkBool32                                shaderDenormFlushToZeroFloat32;
-    VkBool32                                shaderDenormFlushToZeroFloat64;
-    VkBool32                                shaderRoundingModeRTEFloat16;
-    VkBool32                                shaderRoundingModeRTEFloat32;
-    VkBool32                                shaderRoundingModeRTEFloat64;
-    VkBool32                                shaderRoundingModeRTZFloat16;
-    VkBool32                                shaderRoundingModeRTZFloat32;
-    VkBool32                                shaderRoundingModeRTZFloat64;
-} VkPhysicalDeviceFloatControlsPropertiesKHR;
+typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR;
 
 
 
 #define VK_KHR_depth_stencil_resolve 1
 #define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1
 #define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve"
+typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR;
 
-typedef enum VkResolveModeFlagBitsKHR {
-    VK_RESOLVE_MODE_NONE_KHR = 0,
-    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001,
-    VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002,
-    VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004,
-    VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008,
-    VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkResolveModeFlagBitsKHR;
-typedef VkFlags VkResolveModeFlagsKHR;
-typedef struct VkSubpassDescriptionDepthStencilResolveKHR {
-    VkStructureType                     sType;
-    const void*                         pNext;
-    VkResolveModeFlagBitsKHR            depthResolveMode;
-    VkResolveModeFlagBitsKHR            stencilResolveMode;
-    const VkAttachmentReference2KHR*    pDepthStencilResolveAttachment;
-} VkSubpassDescriptionDepthStencilResolveKHR;
+typedef VkResolveModeFlags VkResolveModeFlagsKHR;
 
-typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR {
-    VkStructureType          sType;
-    void*                    pNext;
-    VkResolveModeFlagsKHR    supportedDepthResolveModes;
-    VkResolveModeFlagsKHR    supportedStencilResolveModes;
-    VkBool32                 independentResolveNone;
-    VkBool32                 independentResolve;
-} VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
+typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR;
+
+typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
 
 
 
@@ -6546,68 +7182,27 @@
 #define VK_KHR_timeline_semaphore 1
 #define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2
 #define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore"
+typedef VkSemaphoreType VkSemaphoreTypeKHR;
 
-typedef enum VkSemaphoreTypeKHR {
-    VK_SEMAPHORE_TYPE_BINARY_KHR = 0,
-    VK_SEMAPHORE_TYPE_TIMELINE_KHR = 1,
-    VK_SEMAPHORE_TYPE_BEGIN_RANGE_KHR = VK_SEMAPHORE_TYPE_BINARY_KHR,
-    VK_SEMAPHORE_TYPE_END_RANGE_KHR = VK_SEMAPHORE_TYPE_TIMELINE_KHR,
-    VK_SEMAPHORE_TYPE_RANGE_SIZE_KHR = (VK_SEMAPHORE_TYPE_TIMELINE_KHR - VK_SEMAPHORE_TYPE_BINARY_KHR + 1),
-    VK_SEMAPHORE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkSemaphoreTypeKHR;
+typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR;
 
-typedef enum VkSemaphoreWaitFlagBitsKHR {
-    VK_SEMAPHORE_WAIT_ANY_BIT_KHR = 0x00000001,
-    VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkSemaphoreWaitFlagBitsKHR;
-typedef VkFlags VkSemaphoreWaitFlagsKHR;
-typedef struct VkPhysicalDeviceTimelineSemaphoreFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           timelineSemaphore;
-} VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
+typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR;
 
-typedef struct VkPhysicalDeviceTimelineSemaphorePropertiesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    uint64_t           maxTimelineSemaphoreValueDifference;
-} VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
+typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
 
-typedef struct VkSemaphoreTypeCreateInfoKHR {
-    VkStructureType       sType;
-    const void*           pNext;
-    VkSemaphoreTypeKHR    semaphoreType;
-    uint64_t              initialValue;
-} VkSemaphoreTypeCreateInfoKHR;
+typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
 
-typedef struct VkTimelineSemaphoreSubmitInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    uint32_t           waitSemaphoreValueCount;
-    const uint64_t*    pWaitSemaphoreValues;
-    uint32_t           signalSemaphoreValueCount;
-    const uint64_t*    pSignalSemaphoreValues;
-} VkTimelineSemaphoreSubmitInfoKHR;
+typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR;
 
-typedef struct VkSemaphoreWaitInfoKHR {
-    VkStructureType            sType;
-    const void*                pNext;
-    VkSemaphoreWaitFlagsKHR    flags;
-    uint32_t                   semaphoreCount;
-    const VkSemaphore*         pSemaphores;
-    const uint64_t*            pValues;
-} VkSemaphoreWaitInfoKHR;
+typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR;
 
-typedef struct VkSemaphoreSignalInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkSemaphore        semaphore;
-    uint64_t           value;
-} VkSemaphoreSignalInfoKHR;
+typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR;
+
+typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR;
 
 typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue);
-typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, uint64_t timeout);
-typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR(
@@ -6617,25 +7212,19 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR(
     VkDevice                                    device,
-    const VkSemaphoreWaitInfoKHR*               pWaitInfo,
+    const VkSemaphoreWaitInfo*                  pWaitInfo,
     uint64_t                                    timeout);
 
 VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR(
     VkDevice                                    device,
-    const VkSemaphoreSignalInfoKHR*             pSignalInfo);
+    const VkSemaphoreSignalInfo*                pSignalInfo);
 #endif
 
 
 #define VK_KHR_vulkan_memory_model 1
 #define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3
 #define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model"
-typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           vulkanMemoryModel;
-    VkBool32           vulkanMemoryModelDeviceScope;
-    VkBool32           vulkanMemoryModelAvailabilityVisibilityChains;
-} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
+typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
 
 
 
@@ -6658,90 +7247,50 @@
 #define VK_KHR_separate_depth_stencil_layouts 1
 #define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1
 #define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts"
-typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           separateDepthStencilLayouts;
-} VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
+typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
 
-typedef struct VkAttachmentReferenceStencilLayoutKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkImageLayout      stencilLayout;
-} VkAttachmentReferenceStencilLayoutKHR;
+typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR;
 
-typedef struct VkAttachmentDescriptionStencilLayoutKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkImageLayout      stencilInitialLayout;
-    VkImageLayout      stencilFinalLayout;
-} VkAttachmentDescriptionStencilLayoutKHR;
+typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR;
 
 
 
 #define VK_KHR_uniform_buffer_standard_layout 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout"
-typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           uniformBufferStandardLayout;
-} VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
+typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
 
 
 
 #define VK_KHR_buffer_device_address 1
-typedef uint64_t VkDeviceAddress;
 #define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1
 #define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address"
-typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesKHR {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           bufferDeviceAddress;
-    VkBool32           bufferDeviceAddressCaptureReplay;
-    VkBool32           bufferDeviceAddressMultiDevice;
-} VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
+typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
 
-typedef struct VkBufferDeviceAddressInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkBuffer           buffer;
-} VkBufferDeviceAddressInfoKHR;
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR;
 
-typedef struct VkBufferOpaqueCaptureAddressCreateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    uint64_t           opaqueCaptureAddress;
-} VkBufferOpaqueCaptureAddressCreateInfoKHR;
+typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR;
 
-typedef struct VkMemoryOpaqueCaptureAddressAllocateInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    uint64_t           opaqueCaptureAddress;
-} VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
+typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
 
-typedef struct VkDeviceMemoryOpaqueCaptureAddressInfoKHR {
-    VkStructureType    sType;
-    const void*        pNext;
-    VkDeviceMemory     memory;
-} VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
+typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
 
-typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
-typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
 
 VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
 
 VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR(
     VkDevice                                    device,
-    const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo);
+    const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
 #endif
 
 
@@ -8238,28 +8787,11 @@
 #define VK_EXT_sampler_filter_minmax 1
 #define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2
 #define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax"
+typedef VkSamplerReductionMode VkSamplerReductionModeEXT;
 
-typedef enum VkSamplerReductionModeEXT {
-    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0,
-    VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1,
-    VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2,
-    VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT,
-    VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT,
-    VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1),
-    VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkSamplerReductionModeEXT;
-typedef struct VkSamplerReductionModeCreateInfoEXT {
-    VkStructureType              sType;
-    const void*                  pNext;
-    VkSamplerReductionModeEXT    reductionMode;
-} VkSamplerReductionModeCreateInfoEXT;
+typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT;
 
-typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           filterMinmaxSingleComponentFormats;
-    VkBool32           filterMinmaxImageComponentMapping;
-} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
+typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
 
 
 
@@ -8618,87 +9150,19 @@
 #define VK_EXT_descriptor_indexing 1
 #define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
 #define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT;
 
-typedef enum VkDescriptorBindingFlagBitsEXT {
-    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001,
-    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002,
-    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004,
-    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
-    VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkDescriptorBindingFlagBitsEXT;
-typedef VkFlags VkDescriptorBindingFlagsEXT;
-typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
-    VkStructureType                       sType;
-    const void*                           pNext;
-    uint32_t                              bindingCount;
-    const VkDescriptorBindingFlagsEXT*    pBindingFlags;
-} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT;
 
-typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
-    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
-    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
-    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
-    VkBool32           shaderSampledImageArrayNonUniformIndexing;
-    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
-    VkBool32           shaderStorageImageArrayNonUniformIndexing;
-    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
-    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
-    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
-    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
-    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
-    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
-    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
-    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
-    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
-    VkBool32           descriptorBindingUpdateUnusedWhilePending;
-    VkBool32           descriptorBindingPartiallyBound;
-    VkBool32           descriptorBindingVariableDescriptorCount;
-    VkBool32           runtimeDescriptorArray;
-} VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
 
-typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    uint32_t           maxUpdateAfterBindDescriptorsInAllPools;
-    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
-    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
-    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
-    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
-    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
-    VkBool32           robustBufferAccessUpdateAfterBind;
-    VkBool32           quadDivergentImplicitLod;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindSamplers;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindSampledImages;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageImages;
-    uint32_t           maxPerStageDescriptorUpdateAfterBindInputAttachments;
-    uint32_t           maxPerStageUpdateAfterBindResources;
-    uint32_t           maxDescriptorSetUpdateAfterBindSamplers;
-    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffers;
-    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
-    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffers;
-    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
-    uint32_t           maxDescriptorSetUpdateAfterBindSampledImages;
-    uint32_t           maxDescriptorSetUpdateAfterBindStorageImages;
-    uint32_t           maxDescriptorSetUpdateAfterBindInputAttachments;
-} VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
 
-typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
-    VkStructureType    sType;
-    const void*        pNext;
-    uint32_t           descriptorSetCount;
-    const uint32_t*    pDescriptorCounts;
-} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
 
-typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    uint32_t           maxVariableDescriptorCount;
-} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
 
 
 
@@ -9131,7 +9595,7 @@
 
 
 #define VK_EXT_filter_cubic 1
-#define VK_EXT_FILTER_CUBIC_SPEC_VERSION  2
+#define VK_EXT_FILTER_CUBIC_SPEC_VERSION  3
 #define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic"
 typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT {
     VkStructureType    sType;
@@ -9143,7 +9607,7 @@
     VkStructureType    sType;
     void*              pNext;
     VkBool32           filterCubic;
-    VkBool32           filterCubicMinmax ;
+    VkBool32           filterCubicMinmax;
 } VkFilterCubicImageViewImageFormatPropertiesEXT;
 
 
@@ -9762,11 +10226,7 @@
 #define VK_EXT_scalar_block_layout 1
 #define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1
 #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
-typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           scalarBlockLayout;
-} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
+typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
 
 
 
@@ -9888,7 +10348,7 @@
 
 typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT;
 
-typedef VkBufferDeviceAddressInfoKHR VkBufferDeviceAddressInfoEXT;
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT;
 
 typedef struct VkBufferDeviceAddressCreateInfoEXT {
     VkStructureType    sType;
@@ -9896,23 +10356,54 @@
     VkDeviceAddress    deviceAddress;
 } VkBufferDeviceAddressCreateInfoEXT;
 
-typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfoKHR* pInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
 
 #ifndef VK_NO_PROTOTYPES
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT(
     VkDevice                                    device,
-    const VkBufferDeviceAddressInfoKHR*         pInfo);
+    const VkBufferDeviceAddressInfo*            pInfo);
+#endif
+
+
+#define VK_EXT_tooling_info 1
+#define VK_EXT_TOOLING_INFO_SPEC_VERSION  1
+#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info"
+
+typedef enum VkToolPurposeFlagBitsEXT {
+    VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001,
+    VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002,
+    VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004,
+    VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008,
+    VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010,
+    VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020,
+    VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040,
+    VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkToolPurposeFlagBitsEXT;
+typedef VkFlags VkToolPurposeFlagsEXT;
+typedef struct VkPhysicalDeviceToolPropertiesEXT {
+    VkStructureType          sType;
+    void*                    pNext;
+    char                     name[VK_MAX_EXTENSION_NAME_SIZE];
+    char                     version[VK_MAX_EXTENSION_NAME_SIZE];
+    VkToolPurposeFlagsEXT    purposes;
+    char                     description[VK_MAX_DESCRIPTION_SIZE];
+    char                     layer[VK_MAX_EXTENSION_NAME_SIZE];
+} VkPhysicalDeviceToolPropertiesEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pToolCount,
+    VkPhysicalDeviceToolPropertiesEXT*          pToolProperties);
 #endif
 
 
 #define VK_EXT_separate_stencil_usage 1
 #define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
 #define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage"
-typedef struct VkImageStencilUsageCreateInfoEXT {
-    VkStructureType      sType;
-    const void*          pNext;
-    VkImageUsageFlags    stencilUsage;
-} VkImageStencilUsageCreateInfoEXT;
+typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT;
 
 
 
@@ -10165,11 +10656,7 @@
 #define VK_EXT_host_query_reset 1
 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1
 #define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset"
-typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT {
-    VkStructureType    sType;
-    void*              pNext;
-    VkBool32           hostQueryReset;
-} VkPhysicalDeviceHostQueryResetFeaturesEXT;
+typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT;
 
 typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
 
diff --git a/framework/common/tcuCommandLine.cpp b/framework/common/tcuCommandLine.cpp
index bdb76ff..de9c337 100644
--- a/framework/common/tcuCommandLine.cpp
+++ b/framework/common/tcuCommandLine.cpp
@@ -86,6 +86,7 @@
 DE_DECLARE_COMMAND_LINE_OPT(LogImages,					bool);
 DE_DECLARE_COMMAND_LINE_OPT(LogShaderSources,			bool);
 DE_DECLARE_COMMAND_LINE_OPT(TestOOM,					bool);
+DE_DECLARE_COMMAND_LINE_OPT(ArchiveDir,					std::string);
 DE_DECLARE_COMMAND_LINE_OPT(VKDeviceID,					int);
 DE_DECLARE_COMMAND_LINE_OPT(VKDeviceGroupID,			int);
 DE_DECLARE_COMMAND_LINE_OPT(LogFlush,					bool);
@@ -185,6 +186,7 @@
 		<< Option<LogImages>					(DE_NULL,	"deqp-log-images",							"Enable or disable logging of result images",		s_enableNames,		"enable")
 		<< Option<LogShaderSources>				(DE_NULL,	"deqp-log-shader-sources",					"Enable or disable logging of shader sources",		s_enableNames,		"enable")
 		<< Option<TestOOM>						(DE_NULL,	"deqp-test-oom",							"Run tests that exhaust memory on purpose",			s_enableNames,		TEST_OOM_DEFAULT)
+		<< Option<ArchiveDir>					(DE_NULL,	"deqp-archive-dir",							"Path to test resource files",											".")
 		<< Option<LogFlush>						(DE_NULL,	"deqp-log-flush",							"Enable or disable log file fflush",				s_enableNames,		"enable")
 		<< Option<Validation>					(DE_NULL,	"deqp-validation",							"Enable or disable test case validation",			s_enableNames,		"disable")
 		<< Option<Optimization>					(DE_NULL,	"deqp-optimization-recipe",					"Shader optimization recipe (0=disabled, 1=performance, 2=size)",		"0")
@@ -824,6 +826,7 @@
 bool					CommandLine::isRenderDocEnabled				(void) const	{ return m_cmdLine.getOption<opt::RenderDoc>();								}
 const std::vector<int>&	CommandLine::getCaseFraction				(void) const	{ return m_cmdLine.getOption<opt::CaseFraction>();							}
 const char*				CommandLine::getCaseFractionMandatoryTests	(void) const	{ return m_cmdLine.getOption<opt::CaseFractionMandatoryTests>().c_str();	}
+const char*				CommandLine::getArchiveDir					(void) const	{ return m_cmdLine.getOption<opt::ArchiveDir>().c_str();					}
 
 const char* CommandLine::getGLContextType (void) const
 {
diff --git a/framework/common/tcuCommandLine.hpp b/framework/common/tcuCommandLine.hpp
index a7cb3ab..88527f2 100644
--- a/framework/common/tcuCommandLine.hpp
+++ b/framework/common/tcuCommandLine.hpp
@@ -240,6 +240,9 @@
 	//! Get must-list filename
 	const char*						getCaseFractionMandatoryTests(void) const;
 
+	//! Get archive directory path
+	const char*						getArchiveDir				(void) const;
+
 	/*--------------------------------------------------------------------*//*!
 	 * \brief Creates case list filter
 	 * \param archive Resources
diff --git a/framework/common/tcuFloat.hpp b/framework/common/tcuFloat.hpp
index eb1c9c1..1b46e17 100644
--- a/framework/common/tcuFloat.hpp
+++ b/framework/common/tcuFloat.hpp
@@ -37,6 +37,13 @@
 	FLOAT_SUPPORT_DENORM	= (1<<1)
 };
 
+enum RoundingDirection
+{
+	ROUND_TO_EVEN = 0,
+	ROUND_DOWNWARD,		// Towards -Inf.
+	ROUND_UPWARD,		// Towards +Inf.
+};
+
 /*--------------------------------------------------------------------*//*!
  * \brief Floating-point format template
  *
@@ -60,13 +67,13 @@
 
 							Float			(void);
 	explicit				Float			(StorageType value);
-	explicit				Float			(float v);
-	explicit				Float			(double v);
+	explicit				Float			(float v, RoundingDirection rd = ROUND_TO_EVEN);
+	explicit				Float			(double v, RoundingDirection rd = ROUND_TO_EVEN);
 
 	template <typename OtherStorageType, int OtherExponentBits, int OtherMantissaBits, int OtherExponentBias, deUint32 OtherFlags>
-	static Float			convert			(const Float<OtherStorageType, OtherExponentBits, OtherMantissaBits, OtherExponentBias, OtherFlags>& src);
+	static Float			convert			(const Float<OtherStorageType, OtherExponentBits, OtherMantissaBits, OtherExponentBias, OtherFlags>& src, RoundingDirection rd = ROUND_TO_EVEN);
 
-	static inline Float		convert			(const Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>& src) { return src; }
+	static inline Float		convert			(const Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>& src, RoundingDirection = ROUND_TO_EVEN) { return src; }
 
 	/*--------------------------------------------------------------------*//*!
 	 * \brief Construct floating point value
@@ -123,6 +130,9 @@
 	static Float			inf				(int sign);
 	static Float			nan				(void);
 
+	static Float			largestNormal	(int sign);
+	static Float			smallestNormal	(int sign);
+
 private:
 	StorageType				m_value;
 } DE_WARN_UNUSED_TYPE;
@@ -147,21 +157,21 @@
 }
 
 template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
-inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::Float (float value)
+inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::Float (float value, RoundingDirection rd)
 	: m_value(0)
 {
 	deUint32 u32;
 	memcpy(&u32, &value, sizeof(deUint32));
-	*this = convert(Float32(u32));
+	*this = convert(Float32(u32), rd);
 }
 
 template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
-inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::Float (double value)
+inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::Float (double value, RoundingDirection rd)
 	: m_value(0)
 {
 	deUint64 u64;
 	memcpy(&u64, &value, sizeof(deUint64));
-	*this = convert(Float64(u64));
+	*this = convert(Float64(u64), rd);
 }
 
 template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
@@ -203,6 +213,20 @@
 }
 
 template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
+inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags> Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::largestNormal (int sign)
+{
+	DE_ASSERT(sign == 1 || ((Flags & FLOAT_HAS_SIGN) && sign == -1));
+	return Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::construct(sign, ExponentBias, (static_cast<StorageType>(1) << (MantissaBits + 1)) - 1);
+}
+
+template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
+inline Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags> Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::smallestNormal (int sign)
+{
+	DE_ASSERT(sign == 1 || ((Flags & FLOAT_HAS_SIGN) && sign == -1));
+	return Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::construct(sign, 1 - ExponentBias, (static_cast<StorageType>(1) << MantissaBits));
+}
+
+template <typename StorageType, int ExponentBits, int MantissaBits, int ExponentBias, deUint32 Flags>
 Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>
 Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::construct
 	(int sign, int exponent, StorageType mantissa)
@@ -242,98 +266,148 @@
 template <typename OtherStorageType, int OtherExponentBits, int OtherMantissaBits, int OtherExponentBias, deUint32 OtherFlags>
 Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>
 Float<StorageType, ExponentBits, MantissaBits, ExponentBias, Flags>::convert
-	(const Float<OtherStorageType, OtherExponentBits, OtherMantissaBits, OtherExponentBias, OtherFlags>& other)
+	(const Float<OtherStorageType, OtherExponentBits, OtherMantissaBits, OtherExponentBias, OtherFlags>& other, RoundingDirection rd)
 {
 	if (!(Flags & FLOAT_HAS_SIGN) && other.sign() < 0)
 	{
 		// Negative number, truncate to zero.
 		return zero(+1);
 	}
-	else if (other.isInf())
+
+	if (other.isInf())
 	{
 		return inf(other.sign());
 	}
-	else if (other.isNaN())
+
+	if (other.isNaN())
 	{
 		return nan();
 	}
-	else if (other.isZero())
+
+	if (other.isZero())
 	{
 		return zero(other.sign());
 	}
-	else
+
+	const int			eMin	= 1 - ExponentBias;
+	const int			eMax	= ((1<<ExponentBits)-2) - ExponentBias;
+
+	const StorageType	s		= StorageType((StorageType(other.signBit())) << (StorageType(ExponentBits+MantissaBits))); // \note Not sign, but sign bit.
+	int					e		= other.exponent();
+	deUint64			m		= other.mantissa();
+
+	// Normalize denormalized values prior to conversion.
+	while (!(m & (1ull<<OtherMantissaBits)))
 	{
-		const int			eMin	= 1 - ExponentBias;
-		const int			eMax	= ((1<<ExponentBits)-2) - ExponentBias;
+		m <<= 1;
+		e  -= 1;
+	}
 
-		const StorageType	s		= StorageType((StorageType(other.signBit())) << (StorageType(ExponentBits+MantissaBits))); // \note Not sign, but sign bit.
-		int					e		= other.exponent();
-		deUint64			m		= other.mantissa();
-
-		// Normalize denormalized values prior to conversion.
-		while (!(m & (1ull<<OtherMantissaBits)))
+	if (e < eMin)
+	{
+		// Underflow.
+		if ((Flags & FLOAT_SUPPORT_DENORM) && (eMin-e-1 <= MantissaBits))
 		{
-			m <<= 1;
-			e  -= 1;
-		}
+			// Shift and round.
+			int			bitDiff			= (OtherMantissaBits-MantissaBits) + (eMin-e);
+			deUint64	lastBitsMask	= (1ull << bitDiff) - 1ull;
+			deUint64	lastBits		= (static_cast<deUint64>(m) & lastBitsMask);
+			deUint64	half			= (1ull << (bitDiff - 1)) - 1;
+			deUint64	bias			= (m >> bitDiff) & 1;
 
-		if (e < eMin)
-		{
-			// Underflow.
-			if ((Flags & FLOAT_SUPPORT_DENORM) && (eMin-e-1 <= MantissaBits))
+			switch (rd)
 			{
-				// Shift and round (RTE).
-				int			bitDiff	= (OtherMantissaBits-MantissaBits) + (eMin-e);
-				deUint64	half	= (1ull << (bitDiff - 1)) - 1;
-				deUint64	bias	= (m >> bitDiff) & 1;
-
+			case ROUND_TO_EVEN:
 				return Float(StorageType(s | (m + half + bias) >> bitDiff));
-			}
-			else
-				return zero(other.sign());
-		}
-		else
-		{
-			// Remove leading 1.
-			m = m & ~(1ull<<OtherMantissaBits);
 
-			if (MantissaBits < OtherMantissaBits)
-			{
-				// Round mantissa (round to nearest even).
-				int			bitDiff	= OtherMantissaBits-MantissaBits;
-				deUint64	half	= (1ull << (bitDiff - 1)) - 1;
-				deUint64	bias	= (m >> bitDiff) & 1;
-
-				m = (m + half + bias) >> bitDiff;
-
-				if (m & (1ull<<MantissaBits))
+			case ROUND_DOWNWARD:
+				m = (m >> bitDiff);
+				if (lastBits != 0ull && other.sign() < 0)
 				{
-					// Overflow in mantissa.
-					m  = 0;
-					e += 1;
+					m += 1;
 				}
-			}
-			else
-			{
-				int bitDiff = MantissaBits-OtherMantissaBits;
-				m = m << bitDiff;
-			}
+				return Float(StorageType(s | m));
 
-			if (e > eMax)
-			{
-				// Overflow.
-				return inf(other.sign());
-			}
-			else
-			{
-				DE_ASSERT(de::inRange(e, eMin, eMax));
-				DE_ASSERT(((e + ExponentBias) & ~((1ull<<ExponentBits)-1)) == 0);
-				DE_ASSERT((m & ~((1ull<<MantissaBits)-1)) == 0);
+			case ROUND_UPWARD:
+				m = (m >> bitDiff);
+				if (lastBits != 0ull && other.sign() > 0)
+				{
+					m += 1;
+				}
+				return Float(StorageType(s | m));
 
-				return Float(StorageType(s | (StorageType(e + ExponentBias) << MantissaBits) | m));
+			default:
+				DE_ASSERT(false);
+				break;
 			}
 		}
+
+		return zero(other.sign());
+	}
+
+	// Remove leading 1.
+	m = m & ~(1ull<<OtherMantissaBits);
+
+	if (MantissaBits < OtherMantissaBits)
+	{
+		// Round mantissa.
+		int			bitDiff			= OtherMantissaBits-MantissaBits;
+		deUint64	lastBitsMask	= (1ull << bitDiff) - 1ull;
+		deUint64	lastBits		= (static_cast<deUint64>(m) & lastBitsMask);
+		deUint64	half			= (1ull << (bitDiff - 1)) - 1;
+		deUint64	bias			= (m >> bitDiff) & 1;
+
+		switch (rd)
+		{
+		case ROUND_TO_EVEN:
+			m = (m + half + bias) >> bitDiff;
+			break;
+
+		case ROUND_DOWNWARD:
+			m = (m >> bitDiff);
+			if (lastBits != 0ull && other.sign() < 0)
+			{
+				m += 1;
+			}
+			break;
+
+		case ROUND_UPWARD:
+			m = (m >> bitDiff);
+			if (lastBits != 0ull && other.sign() > 0)
+			{
+				m += 1;
+			}
+			break;
+
+		default:
+			DE_ASSERT(false);
+			break;
+		}
+
+		if (m & (1ull<<MantissaBits))
+		{
+			// Overflow in mantissa.
+			m  = 0;
+			e += 1;
+		}
 	}
+	else
+	{
+		int bitDiff = MantissaBits-OtherMantissaBits;
+		m = m << bitDiff;
+	}
+
+	if (e > eMax)
+	{
+		// Overflow.
+		return (((other.sign() < 0 && rd == ROUND_UPWARD) || (other.sign() > 0 && rd == ROUND_DOWNWARD)) ? largestNormal(other.sign()) : inf(other.sign()));
+	}
+
+	DE_ASSERT(de::inRange(e, eMin, eMax));
+	DE_ASSERT(((e + ExponentBias) & ~((1ull<<ExponentBits)-1)) == 0);
+	DE_ASSERT((m & ~((1ull<<MantissaBits)-1)) == 0);
+
+	return Float(StorageType(s | (StorageType(e + ExponentBias) << MantissaBits) | m));
 }
 
 } // tcu
diff --git a/framework/common/tcuImageCompare.cpp b/framework/common/tcuImageCompare.cpp
index fb2412d..b3907ef 100644
--- a/framework/common/tcuImageCompare.cpp
+++ b/framework/common/tcuImageCompare.cpp
@@ -807,6 +807,108 @@
 }
 
 /*--------------------------------------------------------------------*//*!
+ * \brief Per-pixel depth/stencil threshold-based comparison
+ *
+ * This compare computes per-pixel differences between result and reference
+ * image. Comparison fails if any pixels exceed the given threshold value.
+ *
+ * This comparison can be used for depth and depth/stencil images.
+ * Difference is computed in integer space.
+ *
+ * On failure error image is generated that shows where the failing pixels
+ * are.
+ *
+ * \param log			Test log for results
+ * \param imageSetName	Name for image set when logging results
+ * \param imageSetDesc	Description for image set
+ * \param reference		Reference image
+ * \param result		Result image
+ * \param threshold		Maximum allowed depth difference (stencil must be exact)
+ * \param logMode		Logging mode
+ * \return true if comparison passes, false otherwise
+ *//*--------------------------------------------------------------------*/
+bool dsThresholdCompare(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const float threshold, CompareLogMode logMode)
+{
+	int					width = reference.getWidth();
+	int					height = reference.getHeight();
+	int					depth = reference.getDepth();
+	TextureLevel		errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
+	PixelBufferAccess	errorMask = errorMaskStorage.getAccess();
+	float				maxDiff = 0.0;
+	bool				allStencilOk = true;
+	bool				hasDepth = tcu::hasDepthComponent(result.getFormat().order);
+	bool				hasStencil = tcu::hasStencilComponent(result.getFormat().order);
+
+	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
+
+	for (int z = 0; z < depth; z++)
+	{
+		for (int y = 0; y < height; y++)
+		{
+			for (int x = 0; x < width; x++)
+			{
+				bool	isOk = true;
+
+				if (hasDepth)
+				{
+					float	refDepth = reference.getPixDepth(x, y, z);
+					float	cmpDepth = result.getPixDepth(x, y, z);
+
+					float	diff = refDepth - cmpDepth;
+					isOk = diff <= threshold;
+					maxDiff = (float) deMax(maxDiff, diff);
+				}
+
+				if (hasStencil)
+				{
+					deUint8 refStencil = (deUint8) reference.getPixStencil(x, y, z);
+					deUint8 cmpStencil = (deUint8) result.getPixStencil(x, y, z);
+
+					bool isStencilOk = (refStencil == cmpStencil);
+					allStencilOk = allStencilOk && isStencilOk;
+					isOk = isOk && isStencilOk;
+				}
+
+				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
+			}
+		}
+	}
+
+	bool compareOk = (maxDiff <= threshold) && allStencilOk;
+
+	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
+	{
+		if (!compareOk)
+		{
+			if (maxDiff > threshold)
+				log << TestLog::Message << "Depth comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
+			if (!allStencilOk)
+				log << TestLog::Message << "Stencil comparison failed" << TestLog::EndMessage;
+		}
+
+		log << TestLog::ImageSet(imageSetName, imageSetDesc)
+			// TODO: Convert depth/stencil buffers into separate depth & stencil for logging?
+//			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+//			<< TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
+			<< TestLog::Image("ErrorMask", "Error mask", errorMask)
+			<< TestLog::EndImageSet;
+	}
+	else if (logMode == COMPARE_LOG_RESULT)
+	{
+#if 0
+		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
+			computePixelScaleBias(result, pixelScale, pixelBias);
+
+		log << TestLog::ImageSet(imageSetName, imageSetDesc)
+			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+			<< TestLog::EndImageSet;
+#endif
+	}
+
+	return compareOk;
+}
+
+/*--------------------------------------------------------------------*//*!
  * \brief Per-pixel threshold-based deviation-ignoring comparison
  *
  * This compare computes per-pixel differences between result and reference
diff --git a/framework/common/tcuImageCompare.hpp b/framework/common/tcuImageCompare.hpp
index a16f30a..684cdf3 100644
--- a/framework/common/tcuImageCompare.hpp
+++ b/framework/common/tcuImageCompare.hpp
@@ -55,6 +55,7 @@
 bool	intThresholdCompare									(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode);
 bool	intThresholdPositionDeviationCompare				(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, CompareLogMode logMode);
 bool	intThresholdPositionDeviationErrorThresholdCompare	(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, int maxAllowedFailingPixels, CompareLogMode logMode);
+bool	dsThresholdCompare									(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const float threshold, CompareLogMode logMode);
 int		measurePixelDiffAccuracy							(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode);
 bool	bilinearCompare										(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const RGBA threshold, CompareLogMode logMode);
 
diff --git a/framework/common/tcuTestLog.cpp b/framework/common/tcuTestLog.cpp
index 8b9fc2d..3c84ebb 100644
--- a/framework/common/tcuTestLog.cpp
+++ b/framework/common/tcuTestLog.cpp
@@ -209,7 +209,7 @@
 
 void TestLog::writeMessage (const char* msgStr)
 {
-	if (qpTestLog_writeText(m_log, DE_NULL, DE_NULL, QP_KEY_TAG_LAST, msgStr) == DE_FALSE)
+	if (qpTestLog_writeText(m_log, DE_NULL, DE_NULL, QP_KEY_TAG_NONE, msgStr) == DE_FALSE)
 		throw LogWriteFailedError();
 }
 
diff --git a/framework/common/tcuTexture.cpp b/framework/common/tcuTexture.cpp
index bda2575..34b92cd 100644
--- a/framework/common/tcuTexture.cpp
+++ b/framework/common/tcuTexture.cpp
@@ -912,6 +912,7 @@
 ConstPixelBufferAccess::ConstPixelBufferAccess (void)
 	: m_size		(0)
 	, m_pitch		(0)
+	, m_divider		(1,1,1)
 	, m_data		(DE_NULL)
 {
 }
@@ -920,6 +921,7 @@
 	: m_format		(format)
 	, m_size		(width, height, depth)
 	, m_pitch		(calculatePackedPitch(m_format, m_size))
+	, m_divider		(1,1,1)
 	, m_data		((void*)data)
 {
 	DE_ASSERT(isValid(format));
@@ -929,6 +931,7 @@
 	: m_format		(format)
 	, m_size		(size)
 	, m_pitch		(calculatePackedPitch(m_format, m_size))
+	, m_divider		(1,1,1)
 	, m_data		((void*)data)
 {
 	DE_ASSERT(isValid(format));
@@ -938,6 +941,7 @@
 	: m_format		(format)
 	, m_size		(width, height, depth)
 	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
+	, m_divider		(1,1,1)
 	, m_data		((void*)data)
 {
 	DE_ASSERT(isValid(format));
@@ -947,6 +951,18 @@
 	: m_format		(format)
 	, m_size		(size)
 	, m_pitch		(pitch)
+	, m_divider		(1,1,1)
+	, m_data		((void*)data)
+{
+	DE_ASSERT(isValid(format));
+	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
+}
+
+ConstPixelBufferAccess::ConstPixelBufferAccess(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& block, const void* data)
+	: m_format		(format)
+	, m_size		(size)
+	, m_pitch		(pitch)
+	, m_divider		(block)
 	, m_data		((void*)data)
 {
 	DE_ASSERT(isValid(format));
@@ -957,6 +973,7 @@
 	: m_format		(level.getFormat())
 	, m_size		(level.getSize())
 	, m_pitch		(calculatePackedPitch(m_format, m_size))
+	, m_divider		(1,1,1)
 	, m_data		((void*)level.getPtr())
 {
 }
@@ -981,6 +998,12 @@
 {
 }
 
+PixelBufferAccess::PixelBufferAccess(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& block, void* data)
+	: ConstPixelBufferAccess(format, size, pitch, block, data)
+{
+}
+
+
 PixelBufferAccess::PixelBufferAccess (TextureLevel& level)
 	: ConstPixelBufferAccess(level)
 {
diff --git a/framework/common/tcuTexture.hpp b/framework/common/tcuTexture.hpp
index a0fdff5..722cd11 100644
--- a/framework/common/tcuTexture.hpp
+++ b/framework/common/tcuTexture.hpp
@@ -349,6 +349,7 @@
 							ConstPixelBufferAccess		(const TextureFormat& format, const IVec3& size, const void* data);
 							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data);
 							ConstPixelBufferAccess		(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data);
+							ConstPixelBufferAccess		(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& divider, const void* data);
 
 	const TextureFormat&	getFormat					(void) const	{ return m_format;					}
 	const IVec3&			getSize						(void) const	{ return m_size;					}
@@ -359,9 +360,10 @@
 	int						getRowPitch					(void) const	{ return m_pitch.y();				}
 	int						getSlicePitch				(void) const	{ return m_pitch.z();				}
 	const IVec3&			getPitch					(void) const	{ return m_pitch;					}
+	const IVec3&			getDivider					(void) const	{ return m_divider;					}
 
 	const void*				getDataPtr					(void) const	{ return m_data;					}
-	const void*				getPixelPtr					(int x, int y, int z = 0) const { return (const deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
+	const void*				getPixelPtr					(int x, int y, int z = 0) const { return (const deUint8*)m_data + (x/m_divider.x()) * m_pitch.x() + (y/m_divider.y()) * m_pitch.y() + (z/m_divider.z()) * m_pitch.z(); }
 
 	Vec4					getPixel					(int x, int y, int z = 0) const;
 	IVec4					getPixelInt					(int x, int y, int z = 0) const;
@@ -388,6 +390,7 @@
 	TextureFormat			m_format;
 	IVec3					m_size;
 	IVec3					m_pitch;	//!< (pixelPitch, rowPitch, slicePitch)
+	IVec3					m_divider;
 	mutable void*			m_data;
 } DE_WARN_UNUSED_TYPE;
 
@@ -409,9 +412,10 @@
 						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, void* data);
 						PixelBufferAccess	(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data);
 						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data);
+						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& block, void* data);
 
 	void*				getDataPtr			(void) const { return m_data; }
-	void*				getPixelPtr			(int x, int y, int z = 0) const { return (deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
+	void*				getPixelPtr			(int x, int y, int z = 0) const { return (deUint8*)m_data + (x/m_divider.x()) * m_pitch.x() + (y/m_divider.y()) * m_pitch.y() + (z/m_divider.z()) * m_pitch.z(); }
 
 	void				setPixel			(const tcu::Vec4& color, int x, int y, int z = 0) const;
 	void				setPixel			(const tcu::IVec4& color, int x, int y, int z = 0) const;
diff --git a/framework/common/tcuTextureUtil.cpp b/framework/common/tcuTextureUtil.cpp
index 44bb696..4687713 100644
--- a/framework/common/tcuTextureUtil.cpp
+++ b/framework/common/tcuTextureUtil.cpp
@@ -1051,7 +1051,7 @@
 	}
 }
 
-void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
+void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, const bool clearUnused)
 {
 	DE_ASSERT(src.getSize() == dst.getSize());
 
@@ -1097,7 +1097,7 @@
 			for (int x = 0; x < width; x++)
 				dst.setPixDepth(src.getPixDepth(x, y, z), x, y, z);
 		}
-		else if (dstHasDepth && !srcHasDepth)
+		else if (dstHasDepth && !srcHasDepth && clearUnused)
 		{
 			// consistency with color copies
 			tcu::clearDepth(dst, 0.0f);
@@ -1110,7 +1110,7 @@
 			for (int x = 0; x < width; x++)
 				dst.setPixStencil(src.getPixStencil(x, y, z), x, y, z);
 		}
-		else if (dstHasStencil && !srcHasStencil)
+		else if (dstHasStencil && !srcHasStencil && clearUnused)
 		{
 			// consistency with color copies
 			tcu::clearStencil(dst, 0u);
diff --git a/framework/common/tcuTextureUtil.hpp b/framework/common/tcuTextureUtil.hpp
index 3df5466..3cc770a 100644
--- a/framework/common/tcuTextureUtil.hpp
+++ b/framework/common/tcuTextureUtil.hpp
@@ -122,7 +122,7 @@
 void	fillWithRGBAQuads				(const PixelBufferAccess& access);
 
 //! Copies contents of src to dst. If formats of dst and src are equal, a bit-exact copy is made.
-void	copy							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src);
+void	copy							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, const bool clearUnused = DE_TRUE);
 
 void	scale							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, Sampler::FilterMode filter);
 
diff --git a/framework/delibs/cmake/CFlags.cmake b/framework/delibs/cmake/CFlags.cmake
index 64ac7ec..b3abf72 100644
--- a/framework/delibs/cmake/CFlags.cmake
+++ b/framework/delibs/cmake/CFlags.cmake
@@ -39,10 +39,6 @@
 		set(LINK_FLAGS		"${LINK_FLAGS} -lgcov")
 	endif ()
 
-	# For 3rd party sw disable all warnings
-	set(DE_3RD_PARTY_C_FLAGS	"${CMAKE_C_FLAGS} ${TARGET_FLAGS} -w")
-	set(DE_3RD_PARTY_CXX_FLAGS	"${CMAKE_CXX_FLAGS} ${TARGET_FLAGS} -w")
-
 	# \note Remove -Wno-sign-conversion for more warnings
 	set(WARNING_FLAGS			"-Wall -Wextra -Wno-long-long -Wshadow -Wundef -Wconversion -Wno-sign-conversion")
 
@@ -58,6 +54,10 @@
 	# Any static libraries build are linked into the standalone executable binaries.
 	set(CMAKE_C_FLAGS			"${CMAKE_C_FLAGS} -fvisibility=hidden")
 	set(CMAKE_CXX_FLAGS			"${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
+
+	# For 3rd party sw disable all warnings
+	set(DE_3RD_PARTY_C_FLAGS	"${CMAKE_C_FLAGS} ${TARGET_FLAGS} -w")
+	set(DE_3RD_PARTY_CXX_FLAGS	"${CMAKE_CXX_FLAGS} ${TARGET_FLAGS} -w")
 elseif (DE_COMPILER_IS_MSC)
 	# Compiler flags for msc
 
@@ -70,13 +70,12 @@
 	set(MSC_BASE_FLAGS "/DWIN32 /D_WINDOWS /D_CRT_SECURE_NO_WARNINGS")
 	set(MSC_WARNING_FLAGS "/W3 /wd4820 /wd4255 /wd4668 /wd4738 /wd4711")
 
-	# For 3rd party sw disable all warnings
-	set(DE_3RD_PARTY_C_FLAGS	"${CMAKE_C_FLAGS} ${MSC_BASE_FLAGS} /W0")
-	set(DE_3RD_PARTY_CXX_FLAGS	"${CMAKE_CXX_FLAGS} ${MSC_BASE_FLAGS} /EHsc /W0")
-
 	set(CMAKE_C_FLAGS			"${CMAKE_C_FLAGS} ${MSC_BASE_FLAGS} ${MSC_WARNING_FLAGS}")
 	set(CMAKE_CXX_FLAGS			"${CMAKE_CXX_FLAGS} ${MSC_BASE_FLAGS} /EHsc ${MSC_WARNING_FLAGS}")
 
+	# For 3rd party sw disable all warnings
+	set(DE_3RD_PARTY_C_FLAGS	"${CMAKE_C_FLAGS} ${MSC_BASE_FLAGS} /W0")
+	set(DE_3RD_PARTY_CXX_FLAGS	"${CMAKE_CXX_FLAGS} ${MSC_BASE_FLAGS} /EHsc /W0")
 else ()
 	message(FATAL_ERROR "DE_COMPILER is not valid")
 endif ()
diff --git a/framework/egl/egluGLContextFactory.cpp b/framework/egl/egluGLContextFactory.cpp
index 21d103f..8fbea2a 100644
--- a/framework/egl/egluGLContextFactory.cpp
+++ b/framework/egl/egluGLContextFactory.cpp
@@ -466,6 +466,8 @@
 
 		m_glRenderTarget = tcu::RenderTarget(width, height, pixelFmt, depthBits, stencilBits, numSamples);
 	}
+
+	egl.swapInterval(m_eglDisplay, 0);
 }
 
 void RenderContext::destroy (void)
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index aba9796..70f162e 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -1547,6 +1547,13 @@
 	m_gl.framebufferTexture2D(target, attachment, textarget, texture, level);
 }
 
+void CallLogWrapper::glFramebufferTexture2DMultisampleEXT (glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level, glw::GLsizei samples)
+{
+	if (m_enableLog)
+		m_log << TestLog::Message << "glFramebufferTexture2DMultisampleEXT(" << toHex(target) << ", " << toHex(attachment) << ", " << toHex(textarget) << ", " << texture << ", " << level << ", " << samples << ");" << TestLog::EndMessage;
+	m_gl.framebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
+}
+
 void CallLogWrapper::glFramebufferTexture3D (glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level, glw::GLint zoffset)
 {
 	if (m_enableLog)
@@ -4740,6 +4747,13 @@
 	m_gl.renderbufferStorageMultisample(target, samples, internalformat, width, height);
 }
 
+void CallLogWrapper::glRenderbufferStorageMultisampleEXT (glw::GLenum target, glw::GLsizei samples, glw::GLenum internalformat, glw::GLsizei width, glw::GLsizei height)
+{
+	if (m_enableLog)
+		m_log << TestLog::Message << "glRenderbufferStorageMultisampleEXT(" << toHex(target) << ", " << samples << ", " << toHex(internalformat) << ", " << width << ", " << height << ");" << TestLog::EndMessage;
+	m_gl.renderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+}
+
 void CallLogWrapper::glResumeTransformFeedback (void)
 {
 	if (m_enableLog)
diff --git a/framework/opengl/gluCallLogWrapperApi.inl b/framework/opengl/gluCallLogWrapperApi.inl
index c46f5e3..ea8bc87 100644
--- a/framework/opengl/gluCallLogWrapperApi.inl
+++ b/framework/opengl/gluCallLogWrapperApi.inl
@@ -220,6 +220,7 @@
 void					glFramebufferTexture								(glw::GLenum target, glw::GLenum attachment, glw::GLuint texture, glw::GLint level);
 void					glFramebufferTexture1D								(glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level);
 void					glFramebufferTexture2D								(glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level);
+void					glFramebufferTexture2DMultisampleEXT				(glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level, glw::GLsizei samples);
 void					glFramebufferTexture3D								(glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level, glw::GLint zoffset);
 void					glFramebufferTexture3DOES							(glw::GLenum target, glw::GLenum attachment, glw::GLenum textarget, glw::GLuint texture, glw::GLint level, glw::GLint zoffset);
 void					glFramebufferTextureLayer							(glw::GLenum target, glw::GLenum attachment, glw::GLuint texture, glw::GLint level, glw::GLint layer);
@@ -646,6 +647,7 @@
 void					glRenderGpuMaskNV									(glw::GLbitfield mask);
 void					glRenderbufferStorage								(glw::GLenum target, glw::GLenum internalformat, glw::GLsizei width, glw::GLsizei height);
 void					glRenderbufferStorageMultisample					(glw::GLenum target, glw::GLsizei samples, glw::GLenum internalformat, glw::GLsizei width, glw::GLsizei height);
+void					glRenderbufferStorageMultisampleEXT					(glw::GLenum target, glw::GLsizei samples, glw::GLenum internalformat, glw::GLsizei width, glw::GLsizei height);
 void					glResumeTransformFeedback							(void);
 void					glSampleCoverage									(glw::GLfloat value, glw::GLboolean invert);
 void					glSampleMaski										(glw::GLuint maskNumber, glw::GLbitfield mask);
diff --git a/framework/opengl/gluContextInfo.cpp b/framework/opengl/gluContextInfo.cpp
index 27d5583..a7e0eed 100644
--- a/framework/opengl/gluContextInfo.cpp
+++ b/framework/opengl/gluContextInfo.cpp
@@ -62,6 +62,17 @@
 
 typedef CachedValue<bool, TryCompileProgram> IsProgramSupported;
 
+bool IsES3Compatible(const glw::Functions& gl)
+{
+	// Detect compatible GLES context by querying GL_MAJOR_VERSION.
+	// This query does not exist on GLES2 so succeeding query implies GLES3+ context.
+	glw::GLint majorVersion = 0;
+	gl.getError();
+	gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
+
+	return (gl.getError() == GL_NO_ERROR);
+}
+
 // ES2-specific context info
 class ES2ContextInfo : public ContextInfo
 {
@@ -247,6 +258,11 @@
 	return std::find(extensions.begin(), extensions.end(), name) != extensions.end();
 }
 
+bool ContextInfo::isES3Compatible() const
+{
+   return IsES3Compatible(m_context.getFunctions());
+}
+
 ContextInfo* ContextInfo::create (const RenderContext& context)
 {
 	// ES2 uses special variant that checks support for various shader features
diff --git a/framework/opengl/gluContextInfo.hpp b/framework/opengl/gluContextInfo.hpp
index 9bb9088..26378c3 100644
--- a/framework/opengl/gluContextInfo.hpp
+++ b/framework/opengl/gluContextInfo.hpp
@@ -23,6 +23,7 @@
  * \brief Context Info Class.
  *//*--------------------------------------------------------------------*/
 
+#include "glwFunctions.hpp"
 #include "gluDefs.hpp"
 
 #include <vector>
@@ -69,6 +70,8 @@
 
 typedef CachedValue<std::set<int>, GetCompressedTextureFormats>	CompressedTextureFormats;
 
+bool IsES3Compatible(const glw::Functions& gl);
+
 /*--------------------------------------------------------------------*//*!
  * \brief Context information & limit query.
  *//*--------------------------------------------------------------------*/
@@ -92,6 +95,8 @@
 	const std::vector<std::string>&				getExtensions						(void) const { return m_extensions; }
 	bool										isExtensionSupported				(const char* extName) const;
 
+	bool											isES3Compatible() const;
+
 	static ContextInfo*							create								(const RenderContext& context);
 
 protected:
diff --git a/framework/opengl/gluShaderProgram.cpp b/framework/opengl/gluShaderProgram.cpp
index a11814d..87f02be 100644
--- a/framework/opengl/gluShaderProgram.cpp
+++ b/framework/opengl/gluShaderProgram.cpp
@@ -588,12 +588,12 @@
 		QP_SHADER_TYPE_TESS_CONTROL,
 		QP_SHADER_TYPE_TESS_EVALUATION,
 		QP_SHADER_TYPE_COMPUTE,
-		QP_SHADER_TYPE_LAST,
-		QP_SHADER_TYPE_LAST,
-		QP_SHADER_TYPE_LAST,
-		QP_SHADER_TYPE_LAST,
-		QP_SHADER_TYPE_LAST,
-		QP_SHADER_TYPE_LAST
+		QP_SHADER_TYPE_RAYGEN,
+		QP_SHADER_TYPE_ANY_HIT,
+		QP_SHADER_TYPE_CLOSEST_HIT,
+		QP_SHADER_TYPE_MISS,
+		QP_SHADER_TYPE_INTERSECTION,
+		QP_SHADER_TYPE_CALLABLE,
 	};
 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typeMap) == SHADERTYPE_LAST);
 	DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typeMap)));
@@ -639,12 +639,12 @@
 			{ "TessControlCompileTime",		"Tesselation control shader compile time"		},
 			{ "TessEvaluationCompileTime",	"Tesselation evaluation shader compile time"	},
 			{ "ComputeCompileTime",			"Compute shader compile time"					},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
-			{ "ERROR Unused for GL",		"ERROR Unused for GL"							},
+			{ "RaygenCompileTime",			"Raygen shader compile time"					},
+			{ "AnyHitCompileTime",			"Any hit shader compile time"					},
+			{ "ClosestHitCompileTime",		"Closest hit shader compile time"				},
+			{ "MissCompileTime",			"Miss shader compile time"						},
+			{ "IntersectionCompileTime",	"Intersection shader compile time"				},
+			{ "CallableCompileTime",		"Callable shader compile time"					},
 		};
 		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_compileTimeDesc) == SHADERTYPE_LAST);
 
diff --git a/framework/opengl/wrapper/glwApi.inl b/framework/opengl/wrapper/glwApi.inl
index 9dde9ff..54e3110 100644
--- a/framework/opengl/wrapper/glwApi.inl
+++ b/framework/opengl/wrapper/glwApi.inl
@@ -220,6 +220,7 @@
 #define			glFramebufferTexture								glwFramebufferTexture
 #define			glFramebufferTexture1D								glwFramebufferTexture1D
 #define			glFramebufferTexture2D								glwFramebufferTexture2D
+#define			glFramebufferTexture2DMultisampleEXT				glwFramebufferTexture2DMultisampleEXT
 #define			glFramebufferTexture3D								glwFramebufferTexture3D
 #define			glFramebufferTexture3DOES							glwFramebufferTexture3DOES
 #define			glFramebufferTextureLayer							glwFramebufferTextureLayer
@@ -646,6 +647,7 @@
 #define			glRenderGpuMaskNV									glwRenderGpuMaskNV
 #define			glRenderbufferStorage								glwRenderbufferStorage
 #define			glRenderbufferStorageMultisample					glwRenderbufferStorageMultisample
+#define			glRenderbufferStorageMultisampleEXT					glwRenderbufferStorageMultisampleEXT
 #define			glResumeTransformFeedback							glwResumeTransformFeedback
 #define			glSampleCoverage									glwSampleCoverage
 #define			glSampleMaski										glwSampleMaski
@@ -1124,6 +1126,7 @@
 void			glwFramebufferTexture								(GLenum target, GLenum attachment, GLuint texture, GLint level);
 void			glwFramebufferTexture1D								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 void			glwFramebufferTexture2D								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void			glwFramebufferTexture2DMultisampleEXT				(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
 void			glwFramebufferTexture3D								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 void			glwFramebufferTexture3DOES							(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 void			glwFramebufferTextureLayer							(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
@@ -1550,6 +1553,7 @@
 void			glwRenderGpuMaskNV									(GLbitfield mask);
 void			glwRenderbufferStorage								(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
 void			glwRenderbufferStorageMultisample					(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void			glwRenderbufferStorageMultisampleEXT				(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 void			glwResumeTransformFeedback							();
 void			glwSampleCoverage									(GLfloat value, GLboolean invert);
 void			glwSampleMaski										(GLuint maskNumber, GLbitfield mask);
diff --git a/framework/opengl/wrapper/glwEnums.inl b/framework/opengl/wrapper/glwEnums.inl
index 944fc6e..c8d01ab 100644
--- a/framework/opengl/wrapper/glwEnums.inl
+++ b/framework/opengl/wrapper/glwEnums.inl
@@ -1058,6 +1058,7 @@
 #define GL_DRAW_FRAMEBUFFER												0x8CA9
 #define GL_READ_FRAMEBUFFER_BINDING										0x8CAA
 #define GL_RENDERBUFFER_SAMPLES											0x8CAB
+#define GL_RENDERBUFFER_SAMPLES_EXT										0x8CAB
 #define GL_DEPTH_COMPONENT32F											0x8CAC
 #define GL_DEPTH32F_STENCIL8											0x8CAD
 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE							0x8CD0
@@ -1126,7 +1127,9 @@
 #define GL_RENDERBUFFER_DEPTH_SIZE										0x8D54
 #define GL_RENDERBUFFER_STENCIL_SIZE									0x8D55
 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE							0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT						0x8D56
 #define GL_MAX_SAMPLES													0x8D57
+#define GL_MAX_SAMPLES_EXT												0x8D57
 #define GL_HALF_FLOAT_OES												0x8D61
 #define GL_RGB565_OES													0x8D62
 #define GL_RGB565														0x8D62
@@ -1138,6 +1141,7 @@
 #define GL_PRIMITIVE_RESTART_FIXED_INDEX								0x8D69
 #define GL_ANY_SAMPLES_PASSED_CONSERVATIVE								0x8D6A
 #define GL_MAX_ELEMENT_INDEX											0x8D6B
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT					0x8D6C
 #define GL_RGBA32UI														0x8D70
 #define GL_RGB32UI														0x8D71
 #define GL_RGBA16UI														0x8D76
diff --git a/framework/opengl/wrapper/glwFunctionTypes.inl b/framework/opengl/wrapper/glwFunctionTypes.inl
index 48fd604..152890d 100644
--- a/framework/opengl/wrapper/glwFunctionTypes.inl
+++ b/framework/opengl/wrapper/glwFunctionTypes.inl
@@ -220,6 +220,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTextureFunc)								(GLenum target, GLenum attachment, GLuint texture, GLint level);
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTexture1DFunc)								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTexture2DFunc)								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTexture2DMultisampleEXTFunc)				(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTexture3DFunc)								(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTexture3DOESFunc)							(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 typedef GLW_APICALL void			(GLW_APIENTRY* glFramebufferTextureLayerFunc)							(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
@@ -646,6 +647,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glRenderGpuMaskNVFunc)									(GLbitfield mask);
 typedef GLW_APICALL void			(GLW_APIENTRY* glRenderbufferStorageFunc)								(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
 typedef GLW_APICALL void			(GLW_APIENTRY* glRenderbufferStorageMultisampleFunc)					(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef GLW_APICALL void			(GLW_APIENTRY* glRenderbufferStorageMultisampleEXTFunc)					(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 typedef GLW_APICALL void			(GLW_APIENTRY* glResumeTransformFeedbackFunc)							(void);
 typedef GLW_APICALL void			(GLW_APIENTRY* glSampleCoverageFunc)									(GLfloat value, GLboolean invert);
 typedef GLW_APICALL void			(GLW_APIENTRY* glSampleMaskiFunc)										(GLuint maskNumber, GLbitfield mask);
diff --git a/framework/opengl/wrapper/glwFunctions.inl b/framework/opengl/wrapper/glwFunctions.inl
index 2e1ce5f..bb89906 100644
--- a/framework/opengl/wrapper/glwFunctions.inl
+++ b/framework/opengl/wrapper/glwFunctions.inl
@@ -220,6 +220,7 @@
 glFramebufferTextureFunc								framebufferTexture;
 glFramebufferTexture1DFunc								framebufferTexture1D;
 glFramebufferTexture2DFunc								framebufferTexture2D;
+glFramebufferTexture2DMultisampleEXTFunc				framebufferTexture2DMultisampleEXT;
 glFramebufferTexture3DFunc								framebufferTexture3D;
 glFramebufferTexture3DOESFunc							framebufferTexture3DOES;
 glFramebufferTextureLayerFunc							framebufferTextureLayer;
@@ -646,6 +647,7 @@
 glRenderGpuMaskNVFunc									renderGpuMaskNV;
 glRenderbufferStorageFunc								renderbufferStorage;
 glRenderbufferStorageMultisampleFunc					renderbufferStorageMultisample;
+glRenderbufferStorageMultisampleEXTFunc					renderbufferStorageMultisampleEXT;
 glResumeTransformFeedbackFunc							resumeTransformFeedback;
 glSampleCoverageFunc									sampleCoverage;
 glSampleMaskiFunc										sampleMaski;
diff --git a/framework/opengl/wrapper/glwImpl.inl b/framework/opengl/wrapper/glwImpl.inl
index f7aa5e0..e537ee5 100644
--- a/framework/opengl/wrapper/glwImpl.inl
+++ b/framework/opengl/wrapper/glwImpl.inl
@@ -1740,6 +1740,14 @@
 	gl->framebufferTexture2D(target, attachment, textarget, texture, level);
 }
 
+void glwFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+	const glw::Functions* gl = glw::getCurrentThreadFunctions();
+	if (!gl)
+		return;
+	gl->framebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
+}
+
 void glwFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
@@ -5148,6 +5156,14 @@
 	gl->renderbufferStorageMultisample(target, samples, internalformat, width, height);
 }
 
+void glwRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	const glw::Functions* gl = glw::getCurrentThreadFunctions();
+	if (!gl)
+		return;
+	gl->renderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+}
+
 void glwResumeTransformFeedback (void)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
diff --git a/framework/opengl/wrapper/glwInitExtES.inl b/framework/opengl/wrapper/glwInitExtES.inl
index 9775c98..b5ad2bb 100644
--- a/framework/opengl/wrapper/glwInitExtES.inl
+++ b/framework/opengl/wrapper/glwInitExtES.inl
@@ -119,6 +119,12 @@
 	gl->texParameterIuiv		= (glTexParameterIuivFunc)			loader->get("glTexParameterIuivEXT");
 }
 
+if (de::contains(extSet, "GL_EXT_multisampled_render_to_texture"))
+{
+	gl->framebufferTexture2DMultisampleEXT	= (glFramebufferTexture2DMultisampleEXTFunc)	loader->get("glFramebufferTexture2DMultisampleEXT");
+	gl->renderbufferStorageMultisample		= (glRenderbufferStorageMultisampleFunc)		loader->get("glRenderbufferStorageMultisampleEXT");
+}
+
 if (de::contains(extSet, "GL_EXT_debug_marker"))
 {
 	gl->insertEventMarkerEXT	= (glInsertEventMarkerEXTFunc)	loader->get("glInsertEventMarkerEXT");
diff --git a/framework/platform/lnx/X11/tcuLnxX11GlxPlatform.cpp b/framework/platform/lnx/X11/tcuLnxX11GlxPlatform.cpp
index fd1b2e0..24bb797 100644
--- a/framework/platform/lnx/X11/tcuLnxX11GlxPlatform.cpp
+++ b/framework/platform/lnx/X11/tcuLnxX11GlxPlatform.cpp
@@ -35,10 +35,15 @@
 #define GLX_GLXEXT_PROTOTYPES
 #include <GL/glx.h>
 
+
 #ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
 #define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
 #endif
 
+#ifndef PFNGLXSWAPINTERVALMESAPROC
+#define PFNGLXSWAPINTERVALMESAPROC PFNGLXSWAPINTERVALSGIPROC
+#endif
+
 namespace tcu
 {
 namespace lnx
@@ -181,6 +186,7 @@
 	virtual void						postIterate			(void);
 	virtual void						makeCurrent			(void);
 	void								clearCurrent		(void);
+	void								swapInterval		(int interval);
 	virtual const glw::Functions&		getFunctions		(void) const;
 	virtual const tcu::RenderTarget&	getRenderTarget		(void) const;
 	virtual glw::GenericFuncType		getProcAddress		(const char* name) const;
@@ -245,12 +251,17 @@
 	{
 		const int screen = XDefaultScreen(m_display);
 		// nVidia doesn't seem to report client-side extensions correctly,
-		// so only use server side
-		const char* const extensions =
+		// so use also server side
+		const char* const server_extensions =
 			TCU_CHECK_GLX(glXQueryServerString(m_display, screen, GLX_EXTENSIONS));
-		istringstream extStream(extensions);
-		m_extensions = set<string>(istream_iterator<string>(extStream),
+		const char* const client_extensions =
+			TCU_CHECK_GLX(glXQueryExtensionsString(m_display, screen));
+		istringstream srvExtStream(server_extensions);
+		istringstream cliExtStream(client_extensions);
+		m_extensions = set<string>(istream_iterator<string>(srvExtStream),
 								   istream_iterator<string>());
+		m_extensions.insert(istream_iterator<string>(cliExtStream),
+							istream_iterator<string>());
 	}
 }
 
@@ -714,6 +725,7 @@
 	const GlxFunctionLoader loader;
 	makeCurrent();
 	glu::initFunctions(&m_functions, &loader, config.type.getAPI());
+	swapInterval(0);
 }
 
 GlxRenderContext::~GlxRenderContext (void)
@@ -741,6 +753,30 @@
 	return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
 }
 
+void GlxRenderContext::swapInterval (int interval)
+{
+	if (m_glxVisual.getGlxDisplay().isGlxExtensionSupported("GLX_EXT_swap_control"))
+	{
+		PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
+			reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(
+				TCU_CHECK_GLX(
+					glXGetProcAddress(
+						reinterpret_cast<const GLubyte*>("glXSwapIntervalEXT"))));
+
+		glXSwapIntervalEXT(m_glxVisual.getXDisplay(), m_glxDrawable->getGLXDrawable(), interval);
+	}
+	else if (m_glxVisual.getGlxDisplay().isGlxExtensionSupported("GLX_MESA_swap_control"))
+	{
+		PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA =
+			reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(
+				TCU_CHECK_GLX(
+					glXGetProcAddress(
+						reinterpret_cast<const GLubyte*>("glXSwapIntervalMESA"))));
+
+		glXSwapIntervalMESA(interval);
+	}
+}
+
 ContextType GlxRenderContext::getType (void) const
 {
 	return m_type;
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index 9926b80..c717875 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -1956,6 +1956,17 @@
 
 }
 
+GLW_APICALL void GLW_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+	DE_UNREF(target);
+	DE_UNREF(attachment);
+	DE_UNREF(textarget);
+	DE_UNREF(texture);
+	DE_UNREF(level);
+	DE_UNREF(samples);
+
+}
+
 GLW_APICALL void GLW_APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
 {
 	DE_UNREF(target);
@@ -5589,6 +5600,16 @@
 
 }
 
+GLW_APICALL void GLW_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	DE_UNREF(target);
+	DE_UNREF(samples);
+	DE_UNREF(internalformat);
+	DE_UNREF(width);
+	DE_UNREF(height);
+
+}
+
 GLW_APICALL void GLW_APIENTRY glResumeTransformFeedback (void)
 {
 
diff --git a/framework/platform/null/tcuNullRenderContextInitFuncs.inl b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
index 61f6c89..a84255a 100644
--- a/framework/platform/null/tcuNullRenderContextInitFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
@@ -220,6 +220,7 @@
 gl->framebufferTexture								= glFramebufferTexture;
 gl->framebufferTexture1D							= glFramebufferTexture1D;
 gl->framebufferTexture2D							= glFramebufferTexture2D;
+gl->framebufferTexture2DMultisampleEXT				= glFramebufferTexture2DMultisampleEXT;
 gl->framebufferTexture3D							= glFramebufferTexture3D;
 gl->framebufferTexture3DOES							= glFramebufferTexture3DOES;
 gl->framebufferTextureLayer							= glFramebufferTextureLayer;
@@ -646,6 +647,7 @@
 gl->renderGpuMaskNV									= glRenderGpuMaskNV;
 gl->renderbufferStorage								= glRenderbufferStorage;
 gl->renderbufferStorageMultisample					= glRenderbufferStorageMultisample;
+gl->renderbufferStorageMultisampleEXT				= glRenderbufferStorageMultisampleEXT;
 gl->resumeTransformFeedback							= glResumeTransformFeedback;
 gl->sampleCoverage									= glSampleCoverage;
 gl->sampleMaski										= glSampleMaski;
diff --git a/framework/platform/tcuMain.cpp b/framework/platform/tcuMain.cpp
index f3e0fb4..57d62e8 100644
--- a/framework/platform/tcuMain.cpp
+++ b/framework/platform/tcuMain.cpp
@@ -47,7 +47,7 @@
 	try
 	{
 		tcu::CommandLine				cmdLine		(argc, argv);
-		tcu::DirArchive					archive		(".");
+		tcu::DirArchive					archive		(cmdLine.getArchiveDir());
 		tcu::TestLog					log			(cmdLine.getLogFileName(), argc-1, argv+1, cmdLine.getLogFlags());
 		de::UniquePtr<tcu::Platform>	platform	(createPlatform());
 		de::UniquePtr<tcu::App>			app			(new tcu::App(*platform, archive, log, cmdLine));
diff --git a/framework/platform/win32/tcuWGL.cpp b/framework/platform/win32/tcuWGL.cpp
index c36ee94..e871b4c 100644
--- a/framework/platform/win32/tcuWGL.cpp
+++ b/framework/platform/win32/tcuWGL.cpp
@@ -136,6 +136,9 @@
 typedef HGLRC		(WINAPI* wglCreateContextAttribsARBFunc)	(HDC hdc, HGLRC hshareContext, const int* attribList);
 typedef const char*	(WINAPI* wglGetExtensionsStringARBFunc)		(HDC hdc);
 
+// WGL_EXT_swap_control
+typedef BOOL		(WINAPI* wglSwapIntervalEXTFunc)			(int interval);
+
 DE_END_EXTERN_C
 
 namespace tcu
@@ -163,6 +166,10 @@
 	wglCreateContextAttribsARBFunc		createContextAttribsARB;
 	wglGetExtensionsStringARBFunc		getExtensionsStringARB;
 
+	// WGL_EXT_swap_control
+	wglSwapIntervalEXTFunc				swapIntervalEXT;
+
+
 	Functions (void)
 		: createContext				(DE_NULL)
 		, deleteContext				(DE_NULL)
@@ -249,6 +256,9 @@
 	m_functions.createContextAttribsARB		= (wglCreateContextAttribsARBFunc)m_functions.getProcAddress("wglCreateContextAttribsARB");
 	m_functions.getExtensionsStringARB		= (wglGetExtensionsStringARBFunc)m_functions.getProcAddress("wglGetExtensionsStringARB");
 
+	// WGL_EXT_swap_control
+	m_functions.swapIntervalEXT				= (wglSwapIntervalEXTFunc)m_functions.getProcAddress("wglSwapIntervalEXT");
+
 	m_functions.makeCurrent(tmpWindow.getDeviceContext(), NULL);
 	m_functions.deleteContext(tmpCtx);
 
@@ -525,6 +535,9 @@
 		wgl.deleteContext(m_context);
 		TCU_THROW(ResourceError, "wglMakeCurrent() failed");
 	}
+
+	if (core->getLibrary()->isWglExtensionSupported("WGL_EXT_swap_control"))
+		core->getLibrary()->getFunctions().swapIntervalEXT(0);
 }
 
 Context::~Context (void)
diff --git a/framework/qphelper/qpTestLog.c b/framework/qphelper/qpTestLog.c
index 58e8a8e..d970bcf 100644
--- a/framework/qphelper/qpTestLog.c
+++ b/framework/qphelper/qpTestLog.c
@@ -242,6 +242,12 @@
 	{ QP_SHADER_TYPE_TESS_CONTROL,		"TessControlShader"		},
 	{ QP_SHADER_TYPE_TESS_EVALUATION,	"TessEvaluationShader"	},
 	{ QP_SHADER_TYPE_COMPUTE,			"ComputeShader"			},
+	{ QP_SHADER_TYPE_RAYGEN,			"RaygenShader"			},
+	{ QP_SHADER_TYPE_ANY_HIT,			"AnyHitShader"			},
+	{ QP_SHADER_TYPE_CLOSEST_HIT,		"ClosestHitShader"		},
+	{ QP_SHADER_TYPE_MISS,				"MissShader"			},
+	{ QP_SHADER_TYPE_INTERSECTION,		"IntersectionShader"	},
+	{ QP_SHADER_TYPE_CALLABLE,			"CallableShader"		},
 
 	{ QP_SHADER_TYPE_LAST,				DE_NULL					}
 };
@@ -263,7 +269,8 @@
 static const char* qpLookupString (const qpKeyStringMap* keyMap, int keyMapSize, int key)
 {
 	DE_ASSERT(keyMap);
-	DE_ASSERT(deInBounds32(key, 0, keyMapSize));
+	DE_ASSERT(deInBounds32(key, 0, keyMapSize - 1)); /* Last element in map is assumed to be terminator */
+	DE_ASSERT(keyMap[keyMapSize - 1].string == DE_NULL); /* Ensure map is properly completed, *_LAST element is not missing */
 	DE_ASSERT(keyMap[key].key == key);
 	DE_UNREF(keyMapSize); /* for asserting only */
 	return keyMap[key].string;
diff --git a/framework/qphelper/qpTestLog.h b/framework/qphelper/qpTestLog.h
index 8e2e290..7c24ed9 100644
--- a/framework/qphelper/qpTestLog.h
+++ b/framework/qphelper/qpTestLog.h
@@ -146,6 +146,12 @@
 	QP_SHADER_TYPE_TESS_CONTROL,
 	QP_SHADER_TYPE_TESS_EVALUATION,
 	QP_SHADER_TYPE_COMPUTE,
+	QP_SHADER_TYPE_RAYGEN,
+	QP_SHADER_TYPE_ANY_HIT,
+	QP_SHADER_TYPE_CLOSEST_HIT,
+	QP_SHADER_TYPE_MISS,
+	QP_SHADER_TYPE_INTERSECTION,
+	QP_SHADER_TYPE_CALLABLE,
 
 	QP_SHADER_TYPE_LAST
 } qpShaderType;
diff --git a/modules/egl/teglNegativePartialUpdateTests.cpp b/modules/egl/teglNegativePartialUpdateTests.cpp
index 0267c70..553a56e 100644
--- a/modules/egl/teglNegativePartialUpdateTests.cpp
+++ b/modules/egl/teglNegativePartialUpdateTests.cpp
@@ -50,10 +50,10 @@
 class NegativePartialUpdateTest : public TestCase
 {
 public:
-	enum SurfaceType
+	enum SurfaceType // used as a bit field when selecting a suitable EGL config
 	{
-		SURFACETYPE_WINDOW = 0,
-		SURFACETYPE_PBUFFER
+		SURFACETYPE_WINDOW  = 1 << 0,
+		SURFACETYPE_PBUFFER = 1 << 1
 	};
 
 								NegativePartialUpdateTest		(EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description);
@@ -97,14 +97,15 @@
 	return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
 }
 
-EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, NegativePartialUpdateTest::SurfaceType surfaceType, bool preserveBuffer)
+EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, unsigned surfaceTypes, bool preserveBuffer)
 {
 	FilterList filters;
-	if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_WINDOW)
+	if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) != 0)
 		filters << isWindow;
-	else if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_PBUFFER)
+	if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) != 0)
 		filters << isPbuffer;
-	else
+	if (((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) == 0) &&
+		((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) == 0))
 		DE_FATAL("Invalid surfaceType");
 
 	filters << isES2Renderable;
@@ -157,15 +158,15 @@
 	if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update"))
 		TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported");
 
-	m_eglConfig = getEGLConfig(egl, m_eglDisplay, m_surfaceType, m_preserveBuffer);
-
 	if (m_surfaceType == SURFACETYPE_PBUFFER)
 	{
+		m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, m_preserveBuffer);
 		const EGLint pbufferAttribList[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE };
 		m_eglSurface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttribList);
 	}
 	else
 	{
+		m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_WINDOW | SURFACETYPE_PBUFFER, m_preserveBuffer);
 		const NativeWindowFactory&	factory	= selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
 		m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL,
 										WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine())));
@@ -272,14 +273,13 @@
 {
 	const int					impossibleBufferAge = -26084;
 	const Library&				egl					= m_eglTestCtx.getLibrary();
-	const EGLConfig				config				= getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
 	const EGLint				attribList[]		=
 	{
 		EGL_WIDTH,	64,
 		EGL_HEIGHT,	64,
 		EGL_NONE
 	};
-	const eglu::UniqueSurface	dummyPbuffer		(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, attribList));
+	const eglu::UniqueSurface	dummyPbuffer		(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
 	TestLog&					log					= m_testCtx.getLog();
 	CallLogWrapper				wrapper				(egl, log);
 	EGLint						damageRegion[]		= { 10, 10, 10, 10 };
@@ -496,14 +496,13 @@
 TestCase::IterateResult NotCurrentSurfaceTest2::iterate (void)
 {
 	const Library&				egl				= m_eglTestCtx.getLibrary();
-	const EGLConfig				config			= getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
 	const EGLint				attribList[]	=
 	{
 		EGL_WIDTH,	64,
 		EGL_HEIGHT,	64,
 		EGL_NONE
 	};
-	const eglu::UniqueSurface	dummyPbuffer	(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, attribList));
+	const eglu::UniqueSurface	dummyPbuffer	(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
 	TestLog&					log				= m_testCtx.getLog();
 	CallLogWrapper				wrapper			(egl, log);
 	EGLint						damageRegion[]	= { 10, 10, 10, 10 };
diff --git a/modules/egl/teglWideColorTests.cpp b/modules/egl/teglWideColorTests.cpp
index c053789..b9ced47 100644
--- a/modules/egl/teglWideColorTests.cpp
+++ b/modules/egl/teglWideColorTests.cpp
@@ -38,6 +38,7 @@
 
 #include "gluDefs.hpp"
 #include "gluRenderContext.hpp"
+#include "gluContextInfo.hpp"
 #include "gluShaderProgram.hpp"
 
 #include "glw.h"
@@ -1194,15 +1195,9 @@
 
 				reference += it->increment;
 
-				// Detect compatible GLES context by querying GL_MAJOR_VERSION.
-				// This query does not exist on GLES2 so succeeding query implies GLES3+ context.
-				glw::GLint majorVersion = 0;
-				m_gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
-				if (m_gl.getError() == GL_NO_ERROR)
-				{
-					// This device is ES3 compatible, so do some additional testing
+				// If this device is ES3 compatible, so do some additional testing
+				if (glu::IsES3Compatible(m_gl))
 					testFramebufferColorEncoding();
-				}
 			}
 
 			EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, surface));
diff --git a/modules/gles2/functional/es2fClipControlTests.cpp b/modules/gles2/functional/es2fClipControlTests.cpp
index 2145cd2..ab561b5 100644
--- a/modules/gles2/functional/es2fClipControlTests.cpp
+++ b/modules/gles2/functional/es2fClipControlTests.cpp
@@ -848,10 +848,10 @@
 		for (size_t orig = 0; orig < DE_LENGTH_OF_ARRAY(origins); orig++)
 		{
 			//Set viewport to A = (x, y, w, h) = (1/8, 1/4, 1/2, 1/4) in terms of proportional window size
-			gl.viewport(static_cast<glw::GLint>(0.125f * static_cast<float>(windowW)),
-						static_cast<glw::GLint>(0.25f * static_cast<float>(windowH)),
-						static_cast<glw::GLsizei>(0.5f * static_cast<float>(windowW)),
-						static_cast<glw::GLsizei>(0.25f * static_cast<float>(windowH)));
+			gl.viewport(static_cast<glw::GLint>((0.125f * static_cast<float>(windowW))+0.5f),
+						static_cast<glw::GLint>((0.25f * static_cast<float>(windowH))+0.5f),
+						static_cast<glw::GLsizei>((0.5f * static_cast<float>(windowW))+0.5f),
+						static_cast<glw::GLsizei>((0.25f * static_cast<float>(windowH))+0.5f));
 
 			//Set ClipControl(<origin>, NEGATIVE_ONE_TO_ONE)
 			cc.clipControl(origins[orig], GL_NEGATIVE_ONE_TO_ONE);
diff --git a/modules/gles2/functional/es2fNegativeBufferApiTests.cpp b/modules/gles2/functional/es2fNegativeBufferApiTests.cpp
index 043903a..467c38b 100644
--- a/modules/gles2/functional/es2fNegativeBufferApiTests.cpp
+++ b/modules/gles2/functional/es2fNegativeBufferApiTests.cpp
@@ -340,15 +340,8 @@
 			expectError(GL_INVALID_ENUM);
 			m_log << TestLog::EndSection;
 
-			// Detect compatible GLES context by querying GL_MAJOR_VERSION.
-			// This query does not exist on GLES2 so succeeding query implies GLES3+ context.
-			bool isES3Compatible = false;
-			glw::GLint majorVersion = 0;
-			glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
-			if (glGetError() == GL_NO_ERROR)
-				isES3Compatible = true;
-
-			if (!(m_context.getContextInfo().isExtensionSupported("GL_OES_fbo_render_mipmap") || isES3Compatible))
+			if (!(m_context.getContextInfo().isExtensionSupported("GL_OES_fbo_render_mipmap") ||
+					m_context.getContextInfo().isES3Compatible()))
 			{
 				m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if level is not 0.");
 				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 3);
diff --git a/modules/gles2/functional/es2fShaderBuiltinVarTests.cpp b/modules/gles2/functional/es2fShaderBuiltinVarTests.cpp
index 8cc6259..5012c21 100644
--- a/modules/gles2/functional/es2fShaderBuiltinVarTests.cpp
+++ b/modules/gles2/functional/es2fShaderBuiltinVarTests.cpp
@@ -87,7 +87,8 @@
 	if (m_varName == "gl_MaxDrawBuffers")
 	{
 		if (m_ctxInfo.isExtensionSupported("GL_EXT_draw_buffers") ||
-			m_ctxInfo.isExtensionSupported("GL_NV_draw_buffers"))
+			m_ctxInfo.isExtensionSupported("GL_NV_draw_buffers") ||
+			m_ctxInfo.isES3Compatible())
 			return m_ctxInfo.getInt(GL_MAX_DRAW_BUFFERS);
 		else
 			return 1;
diff --git a/modules/gles2/functional/es2fShaderTextureFunctionTests.cpp b/modules/gles2/functional/es2fShaderTextureFunctionTests.cpp
index 6f283cc..7b51b72 100644
--- a/modules/gles2/functional/es2fShaderTextureFunctionTests.cpp
+++ b/modules/gles2/functional/es2fShaderTextureFunctionTests.cpp
@@ -576,11 +576,7 @@
 	static tcu::Sampler			samplerLinearMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
 														 tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR);
 
-	// GL_MAJOR_VERSION query does not exist on GLES2
-	// so succeeding query implies GLES3+ hardware.
-	glw::GLint majorVersion = 0;
-	gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
-	samplerLinearMipmap.seamlessCubeMap = (gl.getError() == GL_NO_ERROR);
+	samplerLinearMipmap.seamlessCubeMap = glu::IsES3Compatible(gl);
 
 	// Default textures.
 	//												Type			Format		DataType			W		H		L	Sampler
diff --git a/modules/gles2/functional/es2fTextureMipmapTests.cpp b/modules/gles2/functional/es2fTextureMipmapTests.cpp
index 56ca396..6ba4c5f 100644
--- a/modules/gles2/functional/es2fTextureMipmapTests.cpp
+++ b/modules/gles2/functional/es2fTextureMipmapTests.cpp
@@ -600,13 +600,7 @@
 	if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2)
 		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
 
-	// Detect compatible GLES context by querying GL_MAJOR_VERSION.
-	// This query does not exist on GLES2 so succeeding query implies GLES3+ context.
-	bool isES3Compatible = false;
-	glw::GLint majorVersion = 0;
-	gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
-	if (gl.getError() == GL_NO_ERROR)
-		isES3Compatible = true;
+	bool isES3Compatible = m_renderCtxInfo.isES3Compatible();
 
 	// Upload texture data.
 	m_texture->upload();
diff --git a/modules/gles2/functional/es2fVertexTextureTests.cpp b/modules/gles2/functional/es2fVertexTextureTests.cpp
index 47be969..8e6eb97 100644
--- a/modules/gles2/functional/es2fVertexTextureTests.cpp
+++ b/modules/gles2/functional/es2fVertexTextureTests.cpp
@@ -761,11 +761,7 @@
 		"	gl_FragColor = v_color;\n"
 		"}\n";
 
-	// GL_MAJOR_VERSION query does not exist on GLES2
-	// so succeeding query implies GLES3+ hardware.
-	glw::GLint majorVersion = 0;
-	glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
-	m_isES3Capable = (glGetError() == GL_NO_ERROR);
+	m_isES3Capable = glu::IsES3Compatible(m_context.getRenderContext().getFunctions());
 
 	if (m_context.getRenderTarget().getNumSamples() != 0)
 		throw tcu::NotSupportedError("MSAA config not supported by this test");
diff --git a/modules/gles3/functional/es3fInternalFormatQueryTests.cpp b/modules/gles3/functional/es3fInternalFormatQueryTests.cpp
index eefb110..e550947 100644
--- a/modules/gles3/functional/es3fInternalFormatQueryTests.cpp
+++ b/modules/gles3/functional/es3fInternalFormatQueryTests.cpp
@@ -176,11 +176,6 @@
 		bool		isIntegerFormat;
 	} internalFormats[] =
 	{
-		// color renderable and unsized
-		// \note These unsized formats seem to allowed by the spec, but they are not useful in any way. (You can't create a renderbuffer with such internalFormat)
-		{ "rgba",					GL_RGBA,				false	},
-		{ "rgb",					GL_RGB,					false	},
-
 		// color renderable
 		{ "r8",						GL_R8,					false	},
 		{ "rg8",					GL_RG8,					false	},
diff --git a/modules/gles31/functional/es31fNegativeBufferApiTests.cpp b/modules/gles31/functional/es31fNegativeBufferApiTests.cpp
index ba44e09..23394ba 100644
--- a/modules/gles31/functional/es31fNegativeBufferApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeBufferApiTests.cpp
@@ -1226,7 +1226,7 @@
 	maxSize = deLog2Floor32(maxTexSize) + 1;
 	ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, maxSize);
 	ctx.expectError(GL_INVALID_VALUE);
-	maxSize = deLog2Floor32(maxTexSize) + 1;
+	maxSize = deLog2Floor32(maxTexCubeSize) + 1;
 	ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, maxSize);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
diff --git a/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp b/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
index 72e0f00..977e268 100644
--- a/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
@@ -486,7 +486,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1]	= {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -495,19 +495,19 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElements(GL_POINTS, 1, -1, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -515,7 +515,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -539,11 +539,11 @@
 		ctx.glBeginTransformFeedback(GL_POINTS);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -559,23 +559,23 @@
 void draw_elements_invalid_program (NegativeTestContext& ctx)
 {
 	ctx.glUseProgram(0);
-	GLuint	fbo = 0;
-	GLfloat	vertices[1];
+	GLuint	fbo			= 0;
+	GLbyte indices[1]	= {0};
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElements(GL_POINTS, 1, -1, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -583,7 +583,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -596,7 +596,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -605,19 +605,19 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElements(GL_TRIANGLES, 1, -1, vertices);
+	ctx.glDrawElements(GL_TRIANGLES, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElements(GL_TRIANGLES, 1, GL_FLOAT, vertices);
+	ctx.glDrawElements(GL_TRIANGLES, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawElements(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -625,7 +625,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -649,11 +649,11 @@
 		ctx.glBeginTransformFeedback(GL_TRIANGLES);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -671,22 +671,22 @@
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
 	GLuint				fbo = 0;
-	GLfloat				vertices[1];
+	GLuint				indices[1] = {0};
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, -1, vertices, 1);
+	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, -1, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_FLOAT, vertices, 1);
+	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_FLOAT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawElementsBaseVertex(GL_POINTS, -1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.glDrawElementsBaseVertex(GL_POINTS, -1, GL_UNSIGNED_INT, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -694,7 +694,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, indices, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -705,7 +705,7 @@
 {
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-	GLfloat						vertices[1];
+	GLuint						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
 
@@ -713,7 +713,7 @@
 
 	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
 	ctx.glUseProgram(program.getProgram());
-	ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, indices, 1);
 	ctx.expectError(GL_INVALID_OPERATION);
 	ctx.endSection();
 
@@ -830,7 +830,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -840,21 +840,21 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
-	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -862,7 +862,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -886,11 +886,11 @@
 		ctx.glBeginTransformFeedback(GL_POINTS);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
+		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
+		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -907,26 +907,26 @@
 {
 	ctx.glUseProgram(0);
 	GLuint fbo = 0;
-	GLfloat vertices[1];
+	GLbyte indices[1] = {0};
 	ctx.glVertexAttribDivisor(0, 1);
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
-	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -934,7 +934,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -947,7 +947,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -957,21 +957,21 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, -1, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, -1, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_FLOAT, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_FLOAT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
-	ctx.glDrawElementsInstanced(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDrawElementsInstanced(GL_TRIANGLES, 11, GL_UNSIGNED_BYTE, vertices, -1);
+	ctx.glDrawElementsInstanced(GL_TRIANGLES, 11, GL_UNSIGNED_BYTE, indices, -1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -979,7 +979,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1003,11 +1003,11 @@
 		ctx.glBeginTransformFeedback(GL_TRIANGLES);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
+		ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawElementsInstanced	(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
+		ctx.glDrawElementsInstanced	(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -1026,7 +1026,7 @@
 
 	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
 	GLuint						fbo		= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program			(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -1036,21 +1036,21 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawElementsInstancedBaseVertex(-1, 1, GL_UNSIGNED_BYTE, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(-1, 1, GL_UNSIGNED_BYTE, indices, 1, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, -1, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, -1, indices, 1, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_FLOAT, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_FLOAT, indices, 1, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
-	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1, 1);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1, 1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -1058,7 +1058,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1071,14 +1071,14 @@
 {
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-	GLfloat						vertices[1];
+	GLuint						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
 	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
 
 	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
 	ctx.glUseProgram(geometryProgram.getProgram());
-	ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1, 1);
+	ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, indices, 1, 1);
 	ctx.expectError(GL_INVALID_OPERATION);
 	ctx.endSection();
 
@@ -1091,7 +1091,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1]	= {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -1100,24 +1100,24 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
-	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -1125,7 +1125,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1149,11 +1149,11 @@
 		ctx.glBeginTransformFeedback(GL_POINTS);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -1170,27 +1170,27 @@
 {
 	ctx.glUseProgram(0);
 	GLuint fbo = 0;
-	GLfloat vertices[1];
+	GLbyte indices[1] = {0};
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
-	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -1198,7 +1198,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1211,7 +1211,7 @@
 	GLuint						fbo		= 0;
 	GLuint						buf		= 0;
 	GLuint						tfID	= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -1220,24 +1220,24 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, vertices);
+	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, indices);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, vertices);
+	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, indices);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
-	ctx.glDrawRangeElements(GL_TRIANGLES, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_TRIANGLES, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -1245,7 +1245,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1269,11 +1269,11 @@
 		ctx.glBeginTransformFeedback(GL_TRIANGLES);
 		ctx.expectError(GL_NO_ERROR);
 
-		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_INVALID_OPERATION);
 
 		ctx.glPauseTransformFeedback();
-		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
+		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
 		ctx.expectError(GL_NO_ERROR);
 
 		ctx.glEndTransformFeedback();
@@ -1291,7 +1291,7 @@
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
 	GLuint						fbo		= 0;
-	GLfloat						vertices[1];
+	GLbyte						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
@@ -1300,24 +1300,24 @@
 	ctx.expectError(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
-	ctx.glDrawRangeElementsBaseVertex(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
-	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, -1, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, -1, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
-	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_FLOAT, indices, 1);
 	ctx.expectError(GL_INVALID_ENUM);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
-	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
-	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -1325,7 +1325,7 @@
 	ctx.glGenFramebuffers(1, &fbo);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices, 1);
 	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
 	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	ctx.glDeleteFramebuffers(1, &fbo);
@@ -1338,14 +1338,14 @@
 {
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-	GLfloat						vertices[1];
+	GLuint						indices[1] = {0};
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
 	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
 
 	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
 	ctx.glUseProgram(geometryProgram.getProgram());
-	ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, indices, 1);
 	ctx.expectError(GL_INVALID_OPERATION);
 	ctx.endSection();
 
diff --git a/modules/glshared/glsShaderLibraryCase.cpp b/modules/glshared/glsShaderLibraryCase.cpp
index 1a40998..e9b4a29 100644
--- a/modules/glshared/glsShaderLibraryCase.cpp
+++ b/modules/glshared/glsShaderLibraryCase.cpp
@@ -945,15 +945,8 @@
 
 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): start");
 
-	if(isCapabilityRequired(CAPABILITY_ONLY_GLSL_ES_100_SUPPORT, m_spec))
-	{
-		// GL_MAJOR_VERSION query does not exist on GLES2
-		// so succeeding query implies GLES3+ hardware.
-		glw::GLint majorVersion = 0;
-		gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
-		if (gl.getError() == GL_NO_ERROR)
-			return true;
-	}
+	if(isCapabilityRequired(CAPABILITY_ONLY_GLSL_ES_100_SUPPORT, m_spec) && glu::IsES3Compatible(gl))
+		return true;
 
 	if(isCapabilityRequired(CAPABILITY_EXACTLY_ONE_DRAW_BUFFER, m_spec))
 	{
diff --git a/scripts/android/build_apk.py b/scripts/android/build_apk.py
index 630cd41..4534a1e 100644
--- a/scripts/android/build_apk.py
+++ b/scripts/android/build_apk.py
@@ -343,7 +343,6 @@
 				'-DDEQP_TARGET_TOOLCHAIN=ndk-modern',
 				'-DCMAKE_C_FLAGS=-Werror',
 				'-DCMAKE_CXX_FLAGS=-Werror',
-				'-DANDROID_NDK_HOST_OS=%s' % config.env.ndk.hostOsName,
 				'-DANDROID_NDK_PATH=%s' % config.env.ndk.path,
 				'-DANDROID_ABI=%s' % abiName,
 				'-DDE_ANDROID_API=%s' % config.nativeApi,
diff --git a/scripts/list_test_changes.py b/scripts/list_test_changes.py
new file mode 100644
index 0000000..f79336c
--- /dev/null
+++ b/scripts/list_test_changes.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+# VK-GL-CTS log scrubber
+# ----------------------
+#
+# Copyright (c) 2019 The Khronos Group Inc.
+# Copyright (c) 2019 Google LLC
+#
+# 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.
+
+# This script attempts to find out which tests have changed since a
+# certain time, release or changelist. The commit messages are scrubbed
+# for dEQP test names, and these are merged to find a suitable set.
+#
+# The changelists that claim to change all tests are ignored.
+
+import subprocess
+import sys
+import fnmatch
+import re
+
+assert sys.version_info >= (3, 0)
+
+if len(sys.argv) == 1:
+	print("""
+VK-GL-CTS log scrubber
+----------------------
+This script attempts to list changed tests since certain time or
+git revision. It does this by looking at git log.
+
+Caveat: git log messages are written by humans, so there may be
+errors. Overly broad changes are ignored (e.g, dEQP-VK.*).
+
+Usage: Give the git log parameters
+
+Examples:""")
+	print(sys.argv[0], '--since="two months ago"')
+	print(sys.argv[0], '--since="7.7.2019"')
+	print(sys.argv[0], 'vulkan-cts-1.1.3.1..HEAD')
+	quit()
+
+params = ""
+first = True
+for x in sys.argv[1:]:
+	if not first:
+		params = params + " "
+	params = params + x
+	first = False
+
+res = []
+
+rawlogoutput = subprocess.check_output(['git', 'log', params, '--pretty=format:"%B"'])
+logoutput = rawlogoutput.decode().split()
+for x in logoutput:
+	xs = x.strip()
+	# regexp matches various over-large test masks like "dEQP-*", "dEQP-VK*", "dEQP-VK.*",
+	# but not "dEQP-VK.a" or "dEQP-VK.*a"
+	if xs.startswith('dEQP-') and not re.search('dEQP-\w*\**\.*\**$',xs):
+		found = False
+		killlist = []
+		for y in res:
+			if fnmatch.fnmatch(xs, y):
+				found = True
+			if fnmatch.fnmatch(y, xs):
+				killlist.append(y)
+		for y in killlist:
+			res.remove(y)
+		if not found:
+			res.append(xs)
+for x in sorted(res):
+	print(x)
+print(len(res), 'total')
diff --git a/scripts/opengl/src_util.py b/scripts/opengl/src_util.py
index 287f865..6c4a7fd 100644
--- a/scripts/opengl/src_util.py
+++ b/scripts/opengl/src_util.py
@@ -75,6 +75,7 @@
 	'GL_EXT_texture_border_clamp',
 	'GL_EXT_texture_sRGB_R8',
 	'GL_EXT_texture_sRGB_RG8',
+	'GL_EXT_multisampled_render_to_texture',
 	'GL_EXT_debug_marker',
 	'GL_EXT_polygon_offset_clamp',
 	'GL_IMG_texture_compression_pvrtc',
@@ -142,6 +143,13 @@
 	'GL_OVR_multiview_multisampled_render_to_texture',
 ]
 
+ALIASING_EXCEPTIONS = [
+	# registry insists that this aliases glRenderbufferStorageMultisample,
+	# and from a desktop GL / GLX perspective it *must*, but for ES they are
+	# unfortunately separate functions with different semantics.
+	'glRenderbufferStorageMultisampleEXT',
+]
+
 def getGLRegistry ():
 	return khr_util.registry_cache.getRegistry(GL_SOURCE)
 
@@ -172,7 +180,7 @@
 		strippedCmds = []
 
 		for command in iface.commands:
-			if command.alias == None:
+			if command.alias == None or command.name in ALIASING_EXCEPTIONS:
 				strippedCmds.append(command)
 
 		iface.commands = strippedCmds