Merge vk-gl-cts/master into vk-gl-cts/vulkan-cts-next-dev
authorAlexander Galazin <alexander.galazin@arm.com>
Sun, 27 Oct 2019 18:13:30 +0000 (19:13 +0100)
committerAlexander Galazin <alexander.galazin@arm.com>
Mon, 28 Oct 2019 08:02:15 +0000 (09:02 +0100)
Change-Id: Ia2c5b71c6849b5306169097223726e8afd37223f

37 files changed:
1  2 
AndroidGen.mk
android/cts/master/vk-master.txt
external/fetch_sources.py
external/vulkancts/framework/vulkan/vkBasicTypes.inl
external/vulkancts/framework/vulkan/vkDeviceFeatures.inl
external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl
external/vulkancts/framework/vulkan/vkImageUtil.cpp
external/vulkancts/framework/vulkan/vkImageUtil.hpp
external/vulkancts/framework/vulkan/vkNullDriver.cpp
external/vulkancts/framework/vulkan/vkStrUtil.inl
external/vulkancts/framework/vulkan/vkStrUtilImpl.inl
external/vulkancts/framework/vulkan/vkStructTypes.inl
external/vulkancts/framework/vulkan/vkVulkan_c.inl
external/vulkancts/modules/vulkan/amber/vktAmberTestCase.hpp
external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
external/vulkancts/modules/vulkan/binding_model/vktBindingDescriptorCopyTests.cpp
external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp
external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt
external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendOperationAdvancedTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmFloatControlsTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
external/vulkancts/modules/vulkan/synchronization/vktSynchronizationWin32KeyedMutexTests.cpp
external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
external/vulkancts/modules/vulkan/ycbcr/vktYCbCrConversionTests.cpp
external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp
external/vulkancts/modules/vulkan/ycbcr/vktYCbCrStorageImageWriteTests.cpp
external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt
external/vulkancts/scripts/gen_framework.py
external/vulkancts/scripts/src/extensions_data.txt
external/vulkancts/scripts/src/vulkan_core.h

diff --cc AndroidGen.mk
Simple merge
Simple merge
Simple merge
@@@ -3059,9 -2880,8 +3060,10 @@@ VK_DEFINE_PLATFORM_TYPE(CAMetalLayer
  #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1
  #define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1
  #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
@@@ -37,9 -35,8 +37,9 @@@ namespace v
  #define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test"
  #define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion"
  #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts"
  #define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64"
- #define VK_KHR_SHADER_CLOCK_EXTENSION_NAME    "VK_KHR_shader_clock"
+ #define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock"
  #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation"
  #define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters"
  #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8"
  #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, 48); }
 -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, 47); }
 -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, 46); }
 -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, 45); }
 -template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME, 0, 44); }
 -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, 43); }
 -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, 42); }
 -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, 41); }
 -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, 40); }
 -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, 39); }
 -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, 38); }
 -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, 37); }
 -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, 36); }
 -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, 35); }
 -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, 34); }
 -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, 33); }
 -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, 32); }
 -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, 31); }
 -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, 30); }
 -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, 29); }
 -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, 28); }
 -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, 27); }
 -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, 26); }
 -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, 25); }
 -template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceMultiviewFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION, 24); }
 -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, 23); }
 -template<> FeatureDesc makeFeatureDesc<VkPhysicalDeviceProtectedMemoryFeatures>(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 22); }
 -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, 21); }
 -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, 20); }
 -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, 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;
 +}
  
- template<> void initFromBlob<VkPhysicalDeviceShaderClockFeaturesKHR>(VkPhysicalDeviceShaderClockFeaturesKHR&, const AllBlobs&) {}
 +// 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, 51}; }
 +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, 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<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, 48}; }
 +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, 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<VkPhysicalDeviceDescriptorIndexingFeatures>(void) { return FeatureDesc{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, 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<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, 33}; }
 +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, 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<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, 20}; }
 +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, 19}; }
 +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, 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<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, 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<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<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<VkPhysicalDeviceCoherentMemoryFeaturesAMD>, DECL_AMD_COHERENT_MEMORY_EXTENSION_NAME, 0 },
        { createFeatureStructWrapper<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>, VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION },
@@@ -561,439 -561,299 +561,444 @@@ template<> VkStructureType getStructure
        return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSwapchainCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan11Features> (void)
  {
 -      return VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkPresentInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan11Properties> (void)
  {
 -      return VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkImageSwapchainCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan12Features> (void)
  {
 -      return VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkBindImageMemorySwapchainInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceVulkan12Properties> (void)
  {
 -      return VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkAcquireNextImageInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkImageFormatListCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkDeviceGroupPresentCapabilitiesKHR> (void)
 +template<> VkStructureType getStructureType<VkAttachmentDescription2> (void)
  {
 -      return VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR;
 +      return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
  }
  
 -template<> VkStructureType getStructureType<VkDeviceGroupPresentInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkAttachmentReference2> (void)
  {
 -      return VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
  }
  
 -template<> VkStructureType getStructureType<VkDeviceGroupSwapchainCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSubpassDescription2> (void)
  {
 -      return VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayModeCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSubpassDependency2> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
  }
  
 -template<> VkStructureType getStructureType<VkDisplaySurfaceCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkRenderPassCreateInfo2> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayPresentInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSubpassBeginInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkImportMemoryFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSubpassEndInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkMemoryFdPropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDevice8BitStorageFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkMemoryGetFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceDriverProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkImportSemaphoreFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceShaderAtomicInt64Features> (void)
  {
 -      return VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSemaphoreGetFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceShaderFloat16Int8Features> (void)
  {
 -      return VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDevicePushDescriptorPropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceFloatControlsProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceShaderFloat16Int8FeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkDescriptorSetLayoutBindingFlagsCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPresentRegionsKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceImagelessFramebufferFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceDescriptorIndexingProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkFramebufferAttachmentImageInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountAllocateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkFramebufferAttachmentsCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkDescriptorSetVariableDescriptorCountLayoutSupport> (void)
  {
 -      return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT;
  }
  
 -template<> VkStructureType getStructureType<VkRenderPassAttachmentBeginInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSubpassDescriptionDepthStencilResolve> (void)
  {
 -      return VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE;
  }
  
 -template<> VkStructureType getStructureType<VkAttachmentDescription2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceDepthStencilResolveProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkAttachmentReference2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceScalarBlockLayoutFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSubpassDescription2KHR> (void)
 +template<> VkStructureType getStructureType<VkImageStencilUsageCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
 +      return VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkSubpassDependency2KHR> (void)
 +template<> VkStructureType getStructureType<VkSamplerReductionModeCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
 +      return VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkRenderPassCreateInfo2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceSamplerFilterMinmaxProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkSubpassBeginInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceVulkanMemoryModelFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSubpassEndInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceImagelessFramebufferFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSharedPresentSurfaceCapabilitiesKHR> (void)
 +template<> VkStructureType getStructureType<VkFramebufferAttachmentImageInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
 +      return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkImportFenceFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkFramebufferAttachmentsCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkFenceGetFdInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkRenderPassAttachmentBeginInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceSurfaceInfo2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSurfaceCapabilities2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkSurfaceFormat2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayProperties2KHR> (void)
 +template<> VkStructureType getStructureType<VkAttachmentReferenceStencilLayout> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;
 +      return VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayPlaneProperties2KHR> (void)
 +template<> VkStructureType getStructureType<VkAttachmentDescriptionStencilLayout> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR;
 +      return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayModeProperties2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceHostQueryResetFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayPlaneInfo2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;
  }
  
 -template<> VkStructureType getStructureType<VkDisplayPlaneCapabilities2KHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreProperties> (void)
  {
 -      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;
  }
  
 -template<> VkStructureType getStructureType<VkImageFormatListCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkSemaphoreTypeCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkTimelineSemaphoreSubmitInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDevice8BitStorageFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkSemaphoreWaitInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceShaderAtomicInt64FeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkSemaphoreSignalInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceShaderClockFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkPhysicalDeviceBufferDeviceAddressFeatures> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
 +      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<VkPhysicalDeviceDriverPropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkBufferOpaqueCaptureAddressCreateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceFloatControlsPropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkMemoryOpaqueCaptureAddressAllocateInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkSubpassDescriptionDepthStencilResolveKHR> (void)
 +template<> VkStructureType getStructureType<VkDeviceMemoryOpaqueCaptureAddressInfo> (void)
  {
 -      return VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR;
 +      return VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceDepthStencilResolvePropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkSwapchainCreateInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkPresentInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceTimelineSemaphorePropertiesKHR> (void)
 +template<> VkStructureType getStructureType<VkImageSwapchainCreateInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR;
 +      return VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkSemaphoreTypeCreateInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkBindImageMemorySwapchainInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkTimelineSemaphoreSubmitInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkAcquireNextImageInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkSemaphoreWaitInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkDeviceGroupPresentCapabilitiesKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkSemaphoreSignalInfoKHR> (void)
 +template<> VkStructureType getStructureType<VkDeviceGroupPresentInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR;
 +      return VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceVulkanMemoryModelFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkDeviceGroupSwapchainCreateInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkSurfaceProtectedCapabilitiesKHR> (void)
 +template<> VkStructureType getStructureType<VkDisplayModeCreateInfoKHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
 +      return VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplaySurfaceCreateInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplayPresentInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkImportMemoryFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkMemoryFdPropertiesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkMemoryGetFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkImportSemaphoreFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkSemaphoreGetFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPhysicalDevicePushDescriptorPropertiesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPresentRegionsKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkSharedPresentSurfaceCapabilitiesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkImportFenceFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkFenceGetFdInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPhysicalDevicePerformanceQueryFeaturesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPhysicalDevicePerformanceQueryPropertiesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPerformanceCounterKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPerformanceCounterDescriptionKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkQueryPoolPerformanceCreateInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkAcquireProfilingLockInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPerformanceQuerySubmitInfoKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkPhysicalDeviceSurfaceInfo2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkSurfaceCapabilities2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkSurfaceFormat2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplayProperties2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplayPlaneProperties2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplayModeProperties2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR;
  }
  
 -template<> VkStructureType getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR> (void)
 +template<> VkStructureType getStructureType<VkDisplayPlaneInfo2KHR> (void)
  {
 -      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
 +      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR;
 +}
 +
 +template<> VkStructureType getStructureType<VkDisplayPlaneCapabilities2KHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
 +}
 +
++template<> VkStructureType getStructureType<VkPhysicalDeviceShaderClockFeaturesKHR> (void)
++{
++      return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
++}
++
 +template<> VkStructureType getStructureType<VkSurfaceProtectedCapabilitiesKHR> (void)
 +{
 +      return VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
  }
  
  template<> VkStructureType getStructureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR> (void)
@@@ -670,7 -612,25 +670,8 @@@ std::ostream&     operator<<      (std::ostream
  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 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR& 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);
@@@ -6993,6 -6389,18 +6994,17 @@@ std::ostream& operator<< (std::ostream
        return s;
  }
  
 -std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& value)
++std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceShaderClockFeaturesKHR& value)
+ {
 -      s << "VkPhysicalDeviceVulkanMemoryModelFeaturesKHR = {\n";
++      s << "VkPhysicalDeviceShaderClockFeaturesKHR = {\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 << "\tshaderSubgroupClock = " << value.shaderSubgroupClock << '\n';
++      s << "\tshaderDeviceClock = " << value.shaderDeviceClock << '\n';
+       s << '}';
+       return s;
+ }
  std::ostream& operator<< (std::ostream& s, const VkSurfaceProtectedCapabilitiesKHR& value)
  {
        s << "VkSurfaceProtectedCapabilitiesKHR = {\n";
@@@ -2638,120 -2238,129 +2638,128 @@@ struct VkPhysicalDevicePerformanceQuery
  {
        VkStructureType sType;
        void*                   pNext;
 -      VkBool32                shaderSubgroupClock;
 -      VkBool32                shaderDeviceClock;
 +      VkBool32                allowCommandBufferQueryCopies;
  };
  
 -struct VkConformanceVersionKHR
 +struct VkPerformanceCounterKHR
  {
 -      deUint8 major;
 -      deUint8 minor;
 -      deUint8 subminor;
 -      deUint8 patch;
 +      VkStructureType                                 sType;
 +      const void*                                             pNext;
 +      VkPerformanceCounterUnitKHR             unit;
 +      VkPerformanceCounterScopeKHR    scope;
 +      VkPerformanceCounterStorageKHR  storage;
 +      deUint8                                                 uuid[VK_UUID_SIZE];
  };
  
 -struct VkPhysicalDeviceDriverPropertiesKHR
 +struct VkPerformanceCounterDescriptionKHR
  {
 -      VkStructureType                 sType;
 -      void*                                   pNext;
 -      VkDriverIdKHR                   driverID;
 -      char                                    driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
 -      char                                    driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
 -      VkConformanceVersionKHR conformanceVersion;
 +      VkStructureType                                                 sType;
 +      const void*                                                             pNext;
 +      VkPerformanceCounterDescriptionFlagsKHR flags;
 +      char                                                                    name[VK_MAX_DESCRIPTION_SIZE];
 +      char                                                                    category[VK_MAX_DESCRIPTION_SIZE];
 +      char                                                                    description[VK_MAX_DESCRIPTION_SIZE];
  };
  
 -struct VkPhysicalDeviceFloatControlsPropertiesKHR
 +struct VkQueryPoolPerformanceCreateInfoKHR
  {
 -      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;
 +      deUint32                queueFamilyIndex;
 +      deUint32                counterIndexCount;
 +      const deUint32* pCounterIndices;
 +};
 +
 +union VkPerformanceCounterResultKHR
  {
 -      VkStructureType                                         sType;
 -      const void*                                                     pNext;
 -      VkResolveModeFlagBitsKHR                        depthResolveMode;
 -      VkResolveModeFlagBitsKHR                        stencilResolveMode;
 -      const VkAttachmentReference2KHR*        pDepthStencilResolveAttachment;
 +      deInt32         int32;
 +      deInt64         int64;
 +      deUint32        uint32;
 +      deUint64        uint64;
 +      float           float32;
 +      double          float64;
  };
  
 -struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR
 +struct VkAcquireProfilingLockInfoKHR
  {
 -      VkStructureType                 sType;
 -      void*                                   pNext;
 -      VkResolveModeFlagsKHR   supportedDepthResolveModes;
 -      VkResolveModeFlagsKHR   supportedStencilResolveModes;
 -      VkBool32                                independentResolveNone;
 -      VkBool32                                independentResolve;
 +      VkStructureType                                 sType;
 +      const void*                                             pNext;
 +      VkAcquireProfilingLockFlagsKHR  flags;
 +      deUint64                                                timeout;
  };
  
 -struct VkPhysicalDeviceTimelineSemaphoreFeaturesKHR
 +struct VkPerformanceQuerySubmitInfoKHR
  {
        VkStructureType sType;
 -      void*                   pNext;
 -      VkBool32                timelineSemaphore;
 +      const void*             pNext;
 +      deUint32                counterPassIndex;
  };
  
 -struct VkPhysicalDeviceTimelineSemaphorePropertiesKHR
 +struct VkPhysicalDeviceSurfaceInfo2KHR
  {
        VkStructureType sType;
 -      void*                   pNext;
 -      deUint64                maxTimelineSemaphoreValueDifference;
 +      const void*             pNext;
 +      VkSurfaceKHR    surface;
  };
  
 -struct VkSemaphoreTypeCreateInfoKHR
 +struct VkSurfaceCapabilities2KHR
  {
 -      VkStructureType         sType;
 -      const void*                     pNext;
 -      VkSemaphoreTypeKHR      semaphoreType;
 -      deUint64                        initialValue;
 +      VkStructureType                         sType;
 +      void*                                           pNext;
 +      VkSurfaceCapabilitiesKHR        surfaceCapabilities;
  };
  
 -struct VkTimelineSemaphoreSubmitInfoKHR
 +struct VkSurfaceFormat2KHR
  {
 -      VkStructureType sType;
 -      const void*             pNext;
 -      deUint32                waitSemaphoreValueCount;
 -      const deUint64* pWaitSemaphoreValues;
 -      deUint32                signalSemaphoreValueCount;
 -      const deUint64* pSignalSemaphoreValues;
 +      VkStructureType         sType;
 +      void*                           pNext;
 +      VkSurfaceFormatKHR      surfaceFormat;
  };
  
 -struct VkSemaphoreWaitInfoKHR
 +struct VkDisplayProperties2KHR
  {
        VkStructureType                 sType;
 -      const void*                             pNext;
 -      VkSemaphoreWaitFlagsKHR flags;
 -      deUint32                                semaphoreCount;
 -      const VkSemaphore*              pSemaphores;
 -      const deUint64*                 pValues;
 +      void*                                   pNext;
 +      VkDisplayPropertiesKHR  displayProperties;
  };
  
 -struct VkSemaphoreSignalInfoKHR
 +struct VkDisplayPlaneProperties2KHR
  {
 -      VkStructureType sType;
 -      const void*             pNext;
 -      VkSemaphore             semaphore;
 -      deUint64                value;
 +      VkStructureType                         sType;
 +      void*                                           pNext;
 +      VkDisplayPlanePropertiesKHR     displayPlaneProperties;
 +};
 +
 +struct VkDisplayModeProperties2KHR
 +{
 +      VkStructureType                         sType;
 +      void*                                           pNext;
 +      VkDisplayModePropertiesKHR      displayModeProperties;
 +};
 +
 +struct VkDisplayPlaneInfo2KHR
 +{
 +      VkStructureType         sType;
 +      const void*                     pNext;
 +      VkDisplayModeKHR        mode;
 +      deUint32                        planeIndex;
 +};
 +
 +struct VkDisplayPlaneCapabilities2KHR
 +{
 +      VkStructureType                                 sType;
 +      void*                                                   pNext;
 +      VkDisplayPlaneCapabilitiesKHR   capabilities;
  };
  
 -struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR
++struct VkPhysicalDeviceShaderClockFeaturesKHR
+ {
+       VkStructureType sType;
+       void*                   pNext;
 -      VkBool32                vulkanMemoryModel;
 -      VkBool32                vulkanMemoryModelDeviceScope;
 -      VkBool32                vulkanMemoryModelAvailabilityVisibilityChains;
++      VkBool32                shaderSubgroupClock;
++      VkBool32                shaderDeviceClock;
+ };
  struct VkSurfaceProtectedCapabilitiesKHR
  {
        VkStructureType sType;
@@@ -7124,16 -6248,57 +7124,28 @@@ typedef VkPhysicalDeviceShaderAtomicInt
  
  
  
+ #define VK_KHR_shader_clock 1
+ #define VK_KHR_SHADER_CLOCK_SPEC_VERSION  1
+ #define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock"
+ typedef struct VkPhysicalDeviceShaderClockFeaturesKHR {
+     VkStructureType    sType;
+     void*              pNext;
+     VkBool32           shaderSubgroupClock;
+     VkBool32           shaderDeviceClock;
+ } VkPhysicalDeviceShaderClockFeaturesKHR;
  #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;
  
  
  
@@@ -7209,10 -6462,15 +7221,9 @@@ VKAPI_ATTR VkResult VKAPI_CALL vkSignal
  #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;
  
  
  #define VK_KHR_spirv_1_4 1
  #define VK_KHR_SPIRV_1_4_SPEC_VERSION     1
  #define VK_KHR_SPIRV_1_4_EXTENSION_NAME   "VK_KHR_spirv_1_4"
@@@ -1419,9 -1559,39 +1559,39 @@@ tcu::TestStatus DescriptorCommands::ru
        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.");
  
 -              if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
+       // 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;
index 0000000,a2272f6..560c1e9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2497 +1,2497 @@@
 -      context.requireDeviceExtension("VK_EXT_blend_operation_advanced");
+ /*------------------------------------------------------------------------
+  * 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();
 -      const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT blendFeatures = context.getBlendOperationAdvancedFeatures();
++      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
index 0000000,b82b112..ec48454
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,718 +1,718 @@@
 -              if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extIter))
+ /*-------------------------------------------------------------------------
+  * 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
@@@ -58,24 -58,16 +58,24 @@@ VK_KHR_image_format_list                                   DEVICE 1_2
  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_shader_clock                                                   DEVICE
@@@ -7121,16 -6245,57 +7121,28 @@@ typedef VkPhysicalDeviceShaderAtomicInt
  
  
  
+ #define VK_KHR_shader_clock 1
+ #define VK_KHR_SHADER_CLOCK_SPEC_VERSION  1
+ #define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock"
+ typedef struct VkPhysicalDeviceShaderClockFeaturesKHR {
+     VkStructureType    sType;
+     void*              pNext;
+     VkBool32           shaderSubgroupClock;
+     VkBool32           shaderDeviceClock;
+ } VkPhysicalDeviceShaderClockFeaturesKHR;
  #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;
  
  
  
@@@ -7206,10 -6459,15 +7218,9 @@@ VKAPI_ATTR VkResult VKAPI_CALL vkSignal
  #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;
  
  
  #define VK_KHR_spirv_1_4 1
  #define VK_KHR_SPIRV_1_4_SPEC_VERSION     1
  #define VK_KHR_SPIRV_1_4_EXTENSION_NAME   "VK_KHR_spirv_1_4"