Optimize format flag fetch function
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiFeatureInfo.cpp
index c55c067..4020894 100644 (file)
@@ -59,6 +59,8 @@ namespace api
 namespace
 {
 
+#include "vkApiExtensionDependencyInfo.inl"
+
 using namespace vk;
 using std::vector;
 using std::set;
@@ -99,9 +101,15 @@ enum LimitType
 
 bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
 {
-       bool                                            limitsOk        = true;
-       VkPhysicalDeviceLimits*         limits          = &properties->limits;
-       deUint32                                        shaderStages = 3;
+       bool                                            limitsOk                                = true;
+       VkPhysicalDeviceLimits*         limits                                  = &properties->limits;
+       deUint32                                        shaderStages                    = 3;
+       deUint32                                        maxPerStageResourcesMin = deMin32(128,  limits->maxPerStageDescriptorUniformBuffers             +
+                                                                                                                                               limits->maxPerStageDescriptorStorageBuffers             +
+                                                                                                                                               limits->maxPerStageDescriptorSampledImages              +
+                                                                                                                                               limits->maxPerStageDescriptorStorageImages              +
+                                                                                                                                               limits->maxPerStageDescriptorInputAttachments   +
+                                                                                                                                               limits->maxColorAttachments);
 
        if (features->tessellationShader)
        {
@@ -133,10 +141,10 @@ bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDev
                { LIMIT(maxImageArrayLayers),                                                           256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
                { LIMIT(maxTexelBufferElements),                                                        65536, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxUniformBufferRange),                                                         16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
-               { LIMIT(maxStorageBufferRange),                                                         0, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
+               { LIMIT(maxStorageBufferRange),                                                         134217728, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxPushConstantsSize),                                                          128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxMemoryAllocationCount),                                                      4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
-               { LIMIT(maxSamplerAllocationCount),                                                     0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE , -1 },
+               { LIMIT(maxSamplerAllocationCount),                                                     4000, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
                { LIMIT(bufferImageGranularity),                                                        0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
                { LIMIT(bufferImageGranularity),                                                        0, 0, 131072, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
                { LIMIT(sparseAddressSpaceSize),                                                        0, 0, 2UL*1024*1024*1024, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
@@ -147,7 +155,7 @@ bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDev
                { LIMIT(maxPerStageDescriptorSampledImages),                            16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
                { LIMIT(maxPerStageDescriptorStorageImages),                            4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
                { LIMIT(maxPerStageDescriptorInputAttachments),                         4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
-               { LIMIT(maxPerStageResources),                                                          0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE , -1 },
+               { LIMIT(maxPerStageResources),                                                          maxPerStageResourcesMin, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
                { LIMIT(maxDescriptorSetSamplers),                                                      shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxDescriptorSetUniformBuffers),                                        shaderStages * 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxDescriptorSetUniformBuffersDynamic),                         8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
@@ -155,7 +163,7 @@ bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDev
                { LIMIT(maxDescriptorSetStorageBuffersDynamic),                         4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxDescriptorSetSampledImages),                                         shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxDescriptorSetStorageImages),                                         shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
-               { LIMIT(maxDescriptorSetInputAttachments),                                      0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE  , -1 },
+               { LIMIT(maxDescriptorSetInputAttachments),                                      4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxVertexInputAttributes),                                                      16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxVertexInputBindings),                                                        16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
                { LIMIT(maxVertexInputAttributeOffset),                                         2047, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
@@ -232,7 +240,7 @@ bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDev
                { LIMIT(maxClipDistances),                                                                      8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxCullDistances),                                                                      8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(maxCombinedClipAndCullDistances),                                       8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
-               { LIMIT(discreteQueuePriorities),                                                       8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
+               { LIMIT(discreteQueuePriorities),                                                       2, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(pointSizeRange[0]),                                                                     0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
                { LIMIT(pointSizeRange[0]),                                                                     0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
                { LIMIT(pointSizeRange[1]),                                                                     0, 0, 0, 64.0f - limits->pointSizeGranularity , LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
@@ -472,7 +480,7 @@ bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDev
        }
 
        if (limits->maxFramebufferWidth > limits->maxViewportDimensions[0] ||
-           limits->maxFramebufferHeight > limits->maxViewportDimensions[1])
+               limits->maxFramebufferHeight > limits->maxViewportDimensions[1])
        {
                log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
                        << "[" << limits->maxFramebufferWidth << ", " << limits->maxFramebufferHeight << "] "
@@ -604,22 +612,6 @@ tcu::TestStatus enumeratePhysicalDevices (Context& context)
        return tcu::TestStatus(results.getResult(), results.getMessage());
 }
 
-Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, deUint32 version, const char* extensionName)
-{
-       const vector<VkExtensionProperties>     instanceExts = enumerateInstanceExtensionProperties(vkp, DE_NULL);
-       vector<string>                                          enabledExts;
-
-       if (!isCoreInstanceExtension(version, extensionName))
-       {
-               if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
-                       TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
-               else
-                       enabledExts.push_back(extensionName);
-       }
-
-       return createDefaultInstance(vkp, version, vector<string>() /* layers */, enabledExts, DE_NULL);
-}
-
 tcu::TestStatus enumeratePhysicalDeviceGroups (Context& context)
 {
        TestLog&                                                                                        log                             = context.getTestContext().getLog();
@@ -714,6 +706,7 @@ void checkInstanceExtensions (tcu::ResultCollector& results, const vector<string
                "VK_KHR_external_fence_capabilities",
                "VK_KHR_device_group_creation",
                "VK_KHR_get_display_properties2",
+               "VK_KHR_surface_protected_capabilities",
        };
 
        checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions);
@@ -728,6 +721,8 @@ void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>&
                "VK_KHR_display_swapchain",
                "VK_KHR_sampler_mirror_clamp_to_edge",
                "VK_KHR_shader_draw_parameters",
+               "VK_KHR_shader_float_controls",
+               "VK_KHR_shader_float16_int8",
                "VK_KHR_maintenance1",
                "VK_KHR_push_descriptor",
                "VK_KHR_descriptor_update_template",
@@ -758,13 +753,51 @@ void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>&
                "VK_KHR_multiview",
                "VK_KHR_maintenance3",
                "VK_KHR_draw_indirect_count",
-               "VK_KHR_create_renderpass2"
+               "VK_KHR_create_renderpass2",
+               "VK_KHR_depth_stencil_resolve",
+               "VK_KHR_driver_properties",
+               "VK_KHR_swapchain_mutable_format",
+               "VK_KHR_shader_atomic_int64",
+               "VK_KHR_vulkan_memory_model",
+               "VK_KHR_swapchain_mutable_format",
        };
 
        checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions);
        checkDuplicateExtensions(results, extensions);
 }
 
+void checkInstanceExtensionDependencies(tcu::ResultCollector& results,
+                                                                               int dependencyLength,
+                                                                               const std::pair<const char*, const char*>* dependencies,
+                                                                               const vector<VkExtensionProperties>& extensionProperties)
+{
+       for (int ndx = 0; ndx < dependencyLength; ndx++)
+       {
+               if (isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].first)) &&
+                       !isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].second)))
+               {
+                       results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
+               }
+       }
+}
+
+void checkDeviceExtensionDependencies(tcu::ResultCollector& results,
+                                                                         int dependencyLength,
+                                                                         const std::pair<const char*, const char*>* dependencies,
+                                                                         const vector<VkExtensionProperties>& instanceExtensionProperties,
+                                                                         const vector<VkExtensionProperties>& deviceExtensionProperties)
+{
+       for (int ndx = 0; ndx < dependencyLength; ndx++)
+       {
+               if (isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].first)) &&
+                       !isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].second)) &&
+                       !isExtensionSupported(instanceExtensionProperties, RequiredExtension(dependencies[ndx].second)))
+               {
+                       results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
+               }
+       }
+}
+
 tcu::TestStatus enumerateInstanceLayers (Context& context)
 {
        TestLog&                                                log                                     = context.getTestContext().getLog();
@@ -804,6 +837,19 @@ tcu::TestStatus enumerateInstanceExtensions (Context& context)
 
                checkInstanceExtensions(results, extensionNames);
                CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size());
+
+               if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
+               {
+                       checkInstanceExtensionDependencies(results,
+                                                                                          DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_1),
+                                                                                          instanceExtensionDependencies_1_1, properties);
+               }
+               else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
+               {
+                       checkInstanceExtensionDependencies(results,
+                                                                                          DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_0),
+                                                                                          instanceExtensionDependencies_1_0, properties);
+               }
        }
 
        {
@@ -830,6 +876,48 @@ tcu::TestStatus enumerateInstanceExtensions (Context& context)
        return tcu::TestStatus(results.getResult(), results.getMessage());
 }
 
+tcu::TestStatus testNoKhxExtensions (Context& context)
+{
+       VkPhysicalDevice                        physicalDevice  = context.getPhysicalDevice();
+       const PlatformInterface&        vkp                             = context.getPlatformInterface();
+       const InstanceInterface&        vki                             = context.getInstanceInterface();
+
+       tcu::ResultCollector            results(context.getTestContext().getLog());
+       bool                                            testSucceeded = true;
+       deUint32                                        instanceExtensionsCount;
+       deUint32                                        deviceExtensionsCount;
+
+       // grab number of instance and device extensions
+       vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, DE_NULL);
+       vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, DE_NULL);
+       vector<VkExtensionProperties> extensionsProperties(instanceExtensionsCount + deviceExtensionsCount);
+
+       // grab instance and device extensions into single vector
+       if (instanceExtensionsCount)
+               vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, &extensionsProperties[0]);
+       if (deviceExtensionsCount)
+               vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, &extensionsProperties[instanceExtensionsCount]);
+
+       // iterate over all extensions and verify their names
+       vector<VkExtensionProperties>::const_iterator extension = extensionsProperties.begin();
+       while (extension != extensionsProperties.end())
+       {
+               // KHX author ID is no longer used, all KHX extensions have been promoted to KHR status
+               std::string extensionName(extension->extensionName);
+               bool caseFailed = de::beginsWith(extensionName, "VK_KHX_");
+               if (caseFailed)
+               {
+                       results.fail("Invalid extension name " + extensionName);
+                       testSucceeded = false;
+               }
+               ++extension;
+       }
+
+       if (testSucceeded)
+               return tcu::TestStatus::pass("No extensions begining with \"VK_KHX\"");
+       return tcu::TestStatus::fail("One or more extensions begins with \"VK_KHX\"");
+}
+
 tcu::TestStatus enumerateDeviceLayers (Context& context)
 {
        TestLog&                                                log                     = context.getTestContext().getLog();
@@ -856,19 +944,37 @@ tcu::TestStatus enumerateDeviceExtensions (Context& context)
        tcu::ResultCollector    results (log);
 
        {
-               const ScopedLogSection                          section         (log, "Global", "Global Extensions");
-               const vector<VkExtensionProperties>     properties      = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
-               vector<string>                                          extensionNames;
+               const ScopedLogSection                          section                                         (log, "Global", "Global Extensions");
+               const vector<VkExtensionProperties>     instanceExtensionProperties     = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
+               const vector<VkExtensionProperties>     deviceExtensionProperties       = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
+               vector<string>                                          deviceExtensionNames;
 
-               for (size_t ndx = 0; ndx < properties.size(); ndx++)
+               for (size_t ndx = 0; ndx < deviceExtensionProperties.size(); ndx++)
                {
-                       log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
+                       log << TestLog::Message << ndx << ": " << deviceExtensionProperties[ndx] << TestLog::EndMessage;
 
-                       extensionNames.push_back(properties[ndx].extensionName);
+                       deviceExtensionNames.push_back(deviceExtensionProperties[ndx].extensionName);
                }
 
-               checkDeviceExtensions(results, extensionNames);
-               CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, properties.size());
+               checkDeviceExtensions(results, deviceExtensionNames);
+               CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, deviceExtensionProperties.size());
+
+               if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
+               {
+                       checkDeviceExtensionDependencies(results,
+                                                                                        DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_1),
+                                                                                        deviceExtensionDependencies_1_1,
+                                                                                        instanceExtensionProperties,
+                                                                                        deviceExtensionProperties);
+               }
+               else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
+               {
+                       checkDeviceExtensionDependencies(results,
+                                                                                        DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_0),
+                                                                                        deviceExtensionDependencies_1_0,
+                                                                                        instanceExtensionProperties,
+                                                                                        deviceExtensionProperties);
+               }
        }
 
        {
@@ -1383,8 +1489,8 @@ tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
                DE_NULL,                                                                                                                //pEnabledFeatures;
        };
 
-       Move<VkDevice>          deviceGroup = createDevice(vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
-       const DeviceDriver      vk      (vki, *deviceGroup);
+       Move<VkDevice>          deviceGroup = createDevice(vkp, *instance, vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
+       const DeviceDriver      vk      (vkp, *instance, *deviceGroup);
        context.getInstanceInterface().getPhysicalDeviceMemoryProperties(deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &memProps);
 
        peerMemFeatures = reinterpret_cast<VkPeerMemoryFeatureFlags*>(buffer);
@@ -1430,195 +1536,84 @@ tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
        return tcu::TestStatus::pass("Querying deviceGroup peer memory features succeeded");
 }
 
-// \todo [2016-01-22 pyry] Optimize by doing format -> flags mapping instead
-
 VkFormatFeatureFlags getRequiredOptimalTilingFeatures (VkFormat format)
 {
-       static const VkFormat s_requiredSampledImageBlitSrcFormats[] =
-       {
-               VK_FORMAT_B4G4R4A4_UNORM_PACK16,
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8_SNORM,
-               VK_FORMAT_R8_UINT,
-               VK_FORMAT_R8_SINT,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8_SNORM,
-               VK_FORMAT_R8G8_UINT,
-               VK_FORMAT_R8G8_SINT,
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SNORM,
-               VK_FORMAT_R8G8B8A8_UINT,
-               VK_FORMAT_R8G8B8A8_SINT,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_UINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_UINT_PACK32,
-               VK_FORMAT_R16_UINT,
-               VK_FORMAT_R16_SINT,
-               VK_FORMAT_R16_SFLOAT,
-               VK_FORMAT_R16G16_UINT,
-               VK_FORMAT_R16G16_SINT,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R16G16B16A16_UINT,
-               VK_FORMAT_R16G16B16A16_SINT,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32_SINT,
-               VK_FORMAT_R32_SFLOAT,
-               VK_FORMAT_R32G32_UINT,
-               VK_FORMAT_R32G32_SINT,
-               VK_FORMAT_R32G32_SFLOAT,
-               VK_FORMAT_R32G32B32A32_UINT,
-               VK_FORMAT_R32G32B32A32_SINT,
-               VK_FORMAT_R32G32B32A32_SFLOAT,
-               VK_FORMAT_B10G11R11_UFLOAT_PACK32,
-               VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
-               VK_FORMAT_D16_UNORM,
-               VK_FORMAT_D32_SFLOAT
-       };
-       static const VkFormat s_requiredSampledImageFilterLinearFormats[] =
+       struct Formatpair
        {
-               VK_FORMAT_B4G4R4A4_UNORM_PACK16,
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8_SNORM,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8_SNORM,
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SNORM,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_R16_SFLOAT,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_B10G11R11_UFLOAT_PACK32,
-               VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
+               VkFormat                                format;
+               VkFormatFeatureFlags    flags;
        };
-       static const VkFormat s_requiredStorageImageFormats[] =
-       {
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SNORM,
-               VK_FORMAT_R8G8B8A8_UINT,
-               VK_FORMAT_R8G8B8A8_SINT,
-               VK_FORMAT_R16G16B16A16_UINT,
-               VK_FORMAT_R16G16B16A16_SINT,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32_SINT,
-               VK_FORMAT_R32_SFLOAT,
-               VK_FORMAT_R32G32_UINT,
-               VK_FORMAT_R32G32_SINT,
-               VK_FORMAT_R32G32_SFLOAT,
-               VK_FORMAT_R32G32B32A32_UINT,
-               VK_FORMAT_R32G32B32A32_SINT,
-               VK_FORMAT_R32G32B32A32_SFLOAT
-       };
-       static const VkFormat s_requiredStorageImageAtomicFormats[] =
-       {
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32_SINT
-       };
-       static const VkFormat s_requiredColorAttachmentBlitDstFormats[] =
-       {
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8_UINT,
-               VK_FORMAT_R8_SINT,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8_UINT,
-               VK_FORMAT_R8G8_SINT,
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_UINT,
-               VK_FORMAT_R8G8B8A8_SINT,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_UINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_UINT_PACK32,
-               VK_FORMAT_R16_UINT,
-               VK_FORMAT_R16_SINT,
-               VK_FORMAT_R16_SFLOAT,
-               VK_FORMAT_R16G16_UINT,
-               VK_FORMAT_R16G16_SINT,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R16G16B16A16_UINT,
-               VK_FORMAT_R16G16B16A16_SINT,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32_SINT,
-               VK_FORMAT_R32_SFLOAT,
-               VK_FORMAT_R32G32_UINT,
-               VK_FORMAT_R32G32_SINT,
-               VK_FORMAT_R32G32_SFLOAT,
-               VK_FORMAT_R32G32B32A32_UINT,
-               VK_FORMAT_R32G32B32A32_SINT,
-               VK_FORMAT_R32G32B32A32_SFLOAT
-       };
-       static const VkFormat s_requiredColorAttachmentBlendFormats[] =
-       {
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_R16_SFLOAT,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R16G16B16A16_SFLOAT
-       };
-       static const VkFormat s_requiredDepthStencilAttachmentFormats[] =
-       {
-               VK_FORMAT_D16_UNORM
-       };
-
-       VkFormatFeatureFlags    flags   = (VkFormatFeatureFlags)0;
-
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageBlitSrcFormats), DE_ARRAY_END(s_requiredSampledImageBlitSrcFormats), format))
-               flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT;
-
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterLinearFormats), DE_ARRAY_END(s_requiredSampledImageFilterLinearFormats), format))
-               flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
-
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageFormats), DE_ARRAY_END(s_requiredStorageImageFormats), format))
-               flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
-
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageAtomicFormats), DE_ARRAY_END(s_requiredStorageImageAtomicFormats), format))
-               flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
 
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlitDstFormats), DE_ARRAY_END(s_requiredColorAttachmentBlitDstFormats), format))
-               flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_BLIT_DST_BIT;
+       enum
+       {
+               SAIM = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,
+               BLSR = VK_FORMAT_FEATURE_BLIT_SRC_BIT,
+               SIFL = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT,
+               COAT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT,
+               BLDS = VK_FORMAT_FEATURE_BLIT_DST_BIT,
+               CABL = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT,
+               STIM = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
+               STIA = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT,
+               DSAT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
+       };
 
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlendFormats), DE_ARRAY_END(s_requiredColorAttachmentBlendFormats), format))
-               flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+       static const Formatpair formatflags[] =
+       {
+               { VK_FORMAT_B4G4R4A4_UNORM_PACK16,              SAIM | BLSR |               SIFL },
+               { VK_FORMAT_R5G6B5_UNORM_PACK16,                SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_A1R5G5B5_UNORM_PACK16,              SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_R8_UNORM,                                   SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_R8_SNORM,                                   SAIM | BLSR |               SIFL },
+               { VK_FORMAT_R8_UINT,                                    SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R8_SINT,                                    SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R8G8_UNORM,                                 SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_R8G8_SNORM,                                 SAIM | BLSR |               SIFL },
+               { VK_FORMAT_R8G8_UINT,                                  SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R8G8_SINT,                                  SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R8G8B8A8_UNORM,                             SAIM | BLSR | COAT | BLDS | SIFL | STIM | CABL },
+               { VK_FORMAT_R8G8B8A8_SNORM,                             SAIM | BLSR |               SIFL | STIM },
+               { VK_FORMAT_R8G8B8A8_UINT,                              SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R8G8B8A8_SINT,                              SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R8G8B8A8_SRGB,                              SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_B8G8R8A8_UNORM,                             SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_B8G8R8A8_SRGB,                              SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_A8B8G8R8_UNORM_PACK32,              SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_A8B8G8R8_SNORM_PACK32,              SAIM | BLSR |               SIFL },
+               { VK_FORMAT_A8B8G8R8_UINT_PACK32,               SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_A8B8G8R8_SINT_PACK32,               SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_A8B8G8R8_SRGB_PACK32,               SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_A2B10G10R10_UNORM_PACK32,   SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_A2B10G10R10_UINT_PACK32,    SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R16_UINT,                                   SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R16_SINT,                                   SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R16_SFLOAT,                                 SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_R16G16_UINT,                                SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R16G16_SINT,                                SAIM | BLSR | COAT | BLDS },
+               { VK_FORMAT_R16G16_SFLOAT,                              SAIM | BLSR | COAT | BLDS | SIFL |        CABL },
+               { VK_FORMAT_R16G16B16A16_UINT,                  SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R16G16B16A16_SINT,                  SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R16G16B16A16_SFLOAT,                SAIM | BLSR | COAT | BLDS | SIFL | STIM | CABL },
+               { VK_FORMAT_R32_UINT,                                   SAIM | BLSR | COAT | BLDS |        STIM |        STIA },
+               { VK_FORMAT_R32_SINT,                                   SAIM | BLSR | COAT | BLDS |        STIM |        STIA },
+               { VK_FORMAT_R32_SFLOAT,                                 SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32_UINT,                                SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32_SINT,                                SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32_SFLOAT,                              SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32B32A32_UINT,                  SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32B32A32_SINT,                  SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_R32G32B32A32_SFLOAT,                SAIM | BLSR | COAT | BLDS |        STIM },
+               { VK_FORMAT_B10G11R11_UFLOAT_PACK32,    SAIM | BLSR |               SIFL },
+               { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,             SAIM | BLSR |               SIFL },
+               { VK_FORMAT_D16_UNORM,                                  SAIM | BLSR |                                           DSAT },
+               { VK_FORMAT_D32_SFLOAT,                                 SAIM | BLSR }
+       };
 
-       if (de::contains(DE_ARRAY_BEGIN(s_requiredDepthStencilAttachmentFormats), DE_ARRAY_END(s_requiredDepthStencilAttachmentFormats), format))
-               flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+       size_t formatpairs = sizeof(formatflags) / sizeof(Formatpair);
 
-       return flags;
+       for (unsigned int i = 0; i < formatpairs; i++)
+               if (formatflags[i].format == format)
+                       return formatflags[i].flags;
+       return 0;
 }
 
 VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context, VkFormat format, VkFormatFeatureFlags queriedFlags)
@@ -1669,7 +1664,7 @@ VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context,
                                        vk.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &physicalDeviceProperties);
                                }
 
-                               if (physicalDeviceSamplerMinMaxProperties.filterMinmaxImageComponentMapping)
+                               if (physicalDeviceSamplerMinMaxProperties.filterMinmaxSingleComponentFormats)
                                {
                                        flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
                                }
@@ -1889,8 +1884,12 @@ VkPhysicalDeviceSamplerYcbcrConversionFeatures getPhysicalDeviceSamplerYcbcrConv
        return ycbcrFeatures;
 }
 
-void checkYcbcrConversionSupport (Context& context)
+void checkYcbcrApiSupport (Context& context)
 {
+       // check if YCbcr API and are supported by implementation
+
+       // the support for formats and YCbCr may still be optional - see isYcbcrConversionSupported below
+
        if (!vk::isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
        {
                if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_sampler_ycbcr_conversion"))
@@ -1899,13 +1898,15 @@ void checkYcbcrConversionSupport (Context& context)
                // Hard dependency for ycbcr
                TCU_CHECK(de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_KHR_get_physical_device_properties2"));
        }
+}
 
-       {
-               const VkPhysicalDeviceSamplerYcbcrConversionFeatures    ycbcrFeatures   = getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
+bool isYcbcrConversionSupported (Context& context)
+{
+       checkYcbcrApiSupport(context);
 
-               if (ycbcrFeatures.samplerYcbcrConversion == VK_FALSE)
-                       TCU_THROW(NotSupportedError, "samplerYcbcrConversion is not supported");
-       }
+       const VkPhysicalDeviceSamplerYcbcrConversionFeatures    ycbcrFeatures   = getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
+
+       return (ycbcrFeatures.samplerYcbcrConversion == VK_TRUE);
 }
 
 VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
@@ -1925,7 +1926,7 @@ VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
        flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT;
        flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT;
        flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT;
-    flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
+       flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
 
        // multi-plane formats *may* support DISJOINT_BIT
        if (getPlaneCount(format) >= 2)
@@ -1940,7 +1941,8 @@ VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
 tcu::TestStatus ycbcrFormatProperties (Context& context, VkFormat format)
 {
        DE_ASSERT(isYCbCrFormat(format));
-       checkYcbcrConversionSupport(context);
+       // check if Ycbcr format enums are valid given the version and extensions
+       checkYcbcrApiSupport(context);
 
        TestLog&                                        log                                             = context.getTestContext().getLog();
        const VkFormatProperties        properties                              = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
@@ -1964,7 +1966,8 @@ tcu::TestStatus ycbcrFormatProperties (Context& context, VkFormat format)
                VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
        };
-       const bool                                      isRequiredBaseFormat    (de::contains(DE_ARRAY_BEGIN(s_requiredBaseFormats), DE_ARRAY_END(s_requiredBaseFormats), format));
+       const bool                                      isRequiredBaseFormat    = isYcbcrConversionSupported(context) &&
+                                                                                                                 de::contains(DE_ARRAY_BEGIN(s_requiredBaseFormats), DE_ARRAY_END(s_requiredBaseFormats), format);
 
        log << TestLog::Message << properties << TestLog::EndMessage;
 
@@ -2266,7 +2269,7 @@ bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
        return usage != 0;
 }
 
-VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat, VkFormatFeatureFlags, VkImageType type, VkImageUsageFlags usage)
+VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat format, VkFormatFeatureFlags formatFeatures, VkImageType type, VkImageUsageFlags usage)
 {
        VkImageCreateFlags      flags   = (VkImageCreateFlags)0;
 
@@ -2274,8 +2277,16 @@ VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& dev
        {
                flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
 
-               if (type == VK_IMAGE_TYPE_2D)
+               if (type == VK_IMAGE_TYPE_2D && !isYCbCrFormat(format))
+               {
                        flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+               }
+       }
+
+       if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
+       {
+               if (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT_KHR)
+                       flags |= VK_IMAGE_CREATE_DISJOINT_BIT_KHR;
        }
 
        if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
@@ -2328,6 +2339,9 @@ bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures& device
        DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
        DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);
 
+       if (isYCbCrFormat(format) && (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)))
+               return false;
+
        if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
        {
                if (isCompressedFormat(format))
@@ -2448,44 +2462,12 @@ struct ImageFormatPropertyCase
        {}
 };
 
-tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
-{
-       return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
-}
-
-void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
-{
-       DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
-
-       for (deUint32 formatNdx = VK_FORMAT_UNDEFINED+1; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
-       {
-               const VkFormat          format                  = (VkFormat)formatNdx;
-               const char* const       enumName                = getFormatName(format);
-               const string            caseName                = de::toLower(string(enumName).substr(10));
-
-               params.format = format;
-
-               addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
-       }
-}
-
-void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
-{
-       DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);
-
-       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",     "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
-       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",      "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
-}
-
-void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
-{
-       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
-       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
-       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
-}
-
 tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
 {
+       if (isYCbCrFormat(format))
+               // check if Ycbcr format enums are valid given the version and extensions
+               checkYcbcrApiSupport(context);
+
        TestLog&                                                log                                     = context.getTestContext().getLog();
        const VkPhysicalDeviceFeatures& deviceFeatures          = context.getDeviceFeatures();
        const VkPhysicalDeviceLimits&   deviceLimits            = context.getDeviceProperties().limits;
@@ -2503,6 +2485,16 @@ tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format,
                                          "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
        }
 
+       if (isYcbcrConversionSupported(context) && (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR || format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR))
+       {
+               VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
+               if (tiling == VK_IMAGE_TILING_OPTIMAL)
+                       requiredFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
+
+               results.check((supportedFeatures & requiredFeatures) == requiredFeatures,
+                                         getFormatName(format) + string(" must support ") + de::toString(getFormatFeatureFlagsStr(requiredFeatures)));
+       }
+
        for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
        {
                if ((curUsageFlags & ~usageFlagSet) != 0 ||
@@ -2619,80 +2611,6 @@ tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format,
 
 // VK_KHR_get_physical_device_properties2
 
-Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName, Context& context)
-{
-       const vector<VkExtensionProperties>     instanceExts    = enumerateInstanceExtensionProperties(vkp, DE_NULL);
-       vector<string>                                          enabledExts;
-
-       const deUint32                                          instanceVersion         = context.getUsedApiVersion();
-
-       if (!isCoreInstanceExtension(instanceVersion, extensionName))
-       {
-               if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
-                       TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
-               else
-                       enabledExts.push_back(extensionName);
-       }
-
-       return createDefaultInstance(vkp, context.getUsedApiVersion(), vector<string>() /* layers */, enabledExts);
-}
-
-string toString (const VkPhysicalDevice16BitStorageFeatures& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDevice16BitStorageFeatures = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
-       s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
-       s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
-       s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceMultiviewFeatures& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceMultiviewFeatures = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tmultiview = " << value.multiview << '\n';
-       s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
-       s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceProtectedMemoryFeatures& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceProtectedMemoryFeatures = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tprotectedMemory = " << value.protectedMemory << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceSamplerYcbcrConversionFeatures& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceSamplerYcbcrConversionFeatures = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceVariablePointerFeatures& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceVariablePointerFeatures = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
-       s << "\tvariablePointers = " << value.variablePointers << '\n';
-       s << '}';
-       return s.str();
-}
-
 bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
 {
        for (size_t ndx = 0; ndx < properties.size(); ++ndx)
@@ -2707,7 +2625,7 @@ tcu::TestStatus deviceFeatures2 (Context& context)
 {
        const PlatformInterface&        vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>        instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>        instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver            vki                             (vkp, *instance);
        TestLog&                                        log                             = context.getTestContext().getLog();
        VkPhysicalDeviceFeatures        coreFeatures;
@@ -2732,12 +2650,14 @@ tcu::TestStatus deviceFeatures2 (Context& context)
        log << TestLog::Message << extFeatures << TestLog::EndMessage;
 
        vector<VkExtensionProperties>   properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
-       const bool khr_8bit_storage             = checkExtension(properties,"VK_KHR_8bit_storage");;
-       bool khr_16bit_storage                  = true;
-       bool khr_multiview                              = true;
-       bool deviceProtectedMemory              = true;
-       bool sampler_ycbcr_conversion   = true;
-       bool variable_pointers                  = true;
+       const bool khr_8bit_storage                             = checkExtension(properties,"VK_KHR_8bit_storage");
+       const bool ext_conditional_rendering    = checkExtension(properties,"VK_EXT_conditional_rendering");
+       const bool scalar_block_layout                  = checkExtension(properties,"VK_EXT_scalar_block_layout");
+       bool khr_16bit_storage                                  = true;
+       bool khr_multiview                                              = true;
+       bool deviceProtectedMemory                              = true;
+       bool sampler_ycbcr_conversion                   = true;
+       bool variable_pointers                                  = true;
        if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1)
        {
                khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
@@ -2749,23 +2669,30 @@ tcu::TestStatus deviceFeatures2 (Context& context)
 
        const int count = 2u;
        VkPhysicalDevice8BitStorageFeaturesKHR                          device8BitStorageFeatures[count];
+       VkPhysicalDeviceConditionalRenderingFeaturesEXT         deviceConditionalRenderingFeatures[count];
        VkPhysicalDevice16BitStorageFeatures                            device16BitStorageFeatures[count];
        VkPhysicalDeviceMultiviewFeatures                                       deviceMultiviewFeatures[count];
        VkPhysicalDeviceProtectedMemoryFeatures                         protectedMemoryFeatures[count];
        VkPhysicalDeviceSamplerYcbcrConversionFeatures          samplerYcbcrConversionFeatures[count];
        VkPhysicalDeviceVariablePointerFeatures                         variablePointerFeatures[count];
+       VkPhysicalDeviceScalarBlockLayoutFeaturesEXT            scalarBlockLayoutFeatures[count];
 
        for (int ndx = 0; ndx < count; ++ndx)
        {
-               deMemset(&device8BitStorageFeatures[ndx],               0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
-               deMemset(&device16BitStorageFeatures[ndx],              0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
-               deMemset(&deviceMultiviewFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
-               deMemset(&protectedMemoryFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
-               deMemset(&samplerYcbcrConversionFeatures[ndx],  0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
-               deMemset(&variablePointerFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
+               deMemset(&device8BitStorageFeatures[ndx],                       0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
+               deMemset(&deviceConditionalRenderingFeatures[ndx],      0xFF*ndx, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT));
+               deMemset(&device16BitStorageFeatures[ndx],                      0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
+               deMemset(&deviceMultiviewFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
+               deMemset(&protectedMemoryFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
+               deMemset(&samplerYcbcrConversionFeatures[ndx],          0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
+               deMemset(&variablePointerFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
+               deMemset(&scalarBlockLayoutFeatures[ndx],                       0xFF*ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT));
 
                device8BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
-               device8BitStorageFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];
+               device8BitStorageFeatures[ndx].pNext = &deviceConditionalRenderingFeatures[ndx];
+
+               deviceConditionalRenderingFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
+               deviceConditionalRenderingFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];
 
                device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
                device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];
@@ -2777,10 +2704,13 @@ tcu::TestStatus deviceFeatures2 (Context& context)
                protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];
 
                samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
-               samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx].sType;
+               samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx];
 
                variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
-               variablePointerFeatures[ndx].pNext = DE_NULL;
+               variablePointerFeatures[ndx].pNext = &scalarBlockLayoutFeatures[ndx];
+
+               scalarBlockLayoutFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
+               scalarBlockLayoutFeatures[ndx].pNext = DE_NULL;
 
                deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
                extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
@@ -2798,6 +2728,14 @@ tcu::TestStatus deviceFeatures2 (Context& context)
                TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
        }
 
+       if ( ext_conditional_rendering &&
+               (deviceConditionalRenderingFeatures[0].conditionalRendering                             != deviceConditionalRenderingFeatures[1].conditionalRendering ||
+               deviceConditionalRenderingFeatures[0].inheritedConditionalRendering             != deviceConditionalRenderingFeatures[1].inheritedConditionalRendering )
+               )
+       {
+               TCU_FAIL("Mismatch between VkPhysicalDeviceConditionalRenderingFeaturesEXT");
+       }
+
        if ( khr_16bit_storage &&
                (device16BitStorageFeatures[0].storageBuffer16BitAccess                         != device16BitStorageFeatures[1].storageBuffer16BitAccess ||
                device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess        != device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
@@ -2834,98 +2772,37 @@ tcu::TestStatus deviceFeatures2 (Context& context)
        {
                TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointerFeatures");
        }
+       if (scalar_block_layout &&
+               (scalarBlockLayoutFeatures[0].scalarBlockLayout != scalarBlockLayoutFeatures[1].scalarBlockLayout))
+       {
+               TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeaturesEXT");
+       }
        if (khr_8bit_storage)
                log << TestLog::Message << device8BitStorageFeatures[0]         << TestLog::EndMessage;
+       if (ext_conditional_rendering)
+               log << TestLog::Message << deviceConditionalRenderingFeatures[0]                << TestLog::EndMessage;
        if (khr_16bit_storage)
-               log << TestLog::Message << toString(device16BitStorageFeatures[0])              << TestLog::EndMessage;
+               log << TestLog::Message << device16BitStorageFeatures[0]                << TestLog::EndMessage;
        if (khr_multiview)
-               log << TestLog::Message << toString(deviceMultiviewFeatures[0])                 << TestLog::EndMessage;
+               log << TestLog::Message << deviceMultiviewFeatures[0]                   << TestLog::EndMessage;
        if (deviceProtectedMemory)
-               log << TestLog::Message << toString(protectedMemoryFeatures[0])                 << TestLog::EndMessage;
+               log << TestLog::Message << protectedMemoryFeatures[0]                   << TestLog::EndMessage;
        if (sampler_ycbcr_conversion)
-               log << TestLog::Message << toString(samplerYcbcrConversionFeatures[0])  << TestLog::EndMessage;
-       if(variable_pointers)
-               log << TestLog::Message << toString(variablePointerFeatures[0])                 << TestLog::EndMessage;
+               log << TestLog::Message << samplerYcbcrConversionFeatures[0]    << TestLog::EndMessage;
+       if (variable_pointers)
+               log << TestLog::Message << variablePointerFeatures[0]                   << TestLog::EndMessage;
+       if (scalar_block_layout)
+               log << TestLog::Message << scalarBlockLayoutFeatures[0]                 << TestLog::EndMessage;
 
        return tcu::TestStatus::pass("Querying device features succeeded");
 }
 
 
-string toString (const VkPhysicalDeviceIDProperties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceIDProperties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
-       s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
-       s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
-       s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
-       s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceMaintenance3Properties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceMaintenance3Properties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
-       s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceMultiviewProperties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceMultiviewProperties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
-       s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDevicePointClippingProperties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDevicePointClippingProperties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
-       s << '}';
-       return s.str();
-}
-
-string toString (const VkPhysicalDeviceProtectedMemoryProperties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceProtectedMemoryProperties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
-       s << '}';
-       return s.str();
-}
-
-
-string toString (const VkPhysicalDeviceSubgroupProperties& value)
-{
-       std::ostringstream      s;
-       s << "VkPhysicalDeviceSubgroupProperties = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tsubgroupSize = " << value.subgroupSize << '\n';
-       s << "\tsupportedStages = " << getShaderStageFlagsStr(value.supportedStages) << '\n';
-       s << "\tsupportedOperations = " << getSubgroupFeatureFlagsStr(value.supportedOperations) << '\n';
-       s << "\tquadOperationsInAllStages = " << value.quadOperationsInAllStages << '\n';
-       s << '}';
-       return s.str();
-}
-
 tcu::TestStatus deviceProperties2 (Context& context)
 {
        const PlatformInterface&                vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                    vki                             (vkp, *instance);
        TestLog&                                                log                             = context.getTestContext().getLog();
        VkPhysicalDeviceProperties              coreProperties;
@@ -2957,75 +2834,211 @@ tcu::TestStatus deviceProperties2 (Context& context)
 
        log << TestLog::Message << extProperties.properties << TestLog::EndMessage;
 
-       if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion >= VK_API_VERSION_1_1)
+       const int count = 2u;
+
+       bool khr_external_memory_capabilities           = true;
+       bool khr_multiview                                                      = true;
+       bool khr_maintenance2                                           = true;
+       bool khr_maintenance3                                           = true;
+       bool apiVersionSmallerThen_1_1                          = (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1);
+       if (apiVersionSmallerThen_1_1)
+       {
+               vector<VkExtensionProperties> properties        = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+               khr_external_memory_capabilities                        = checkExtension(properties,"VK_KHR_external_memory_capabilities");
+               khr_multiview                                                           = checkExtension(properties,"VK_KHR_multiview");
+               khr_maintenance2                                                        = checkExtension(properties,"VK_KHR_maintenance2");
+               khr_maintenance3                                                        = checkExtension(properties,"VK_KHR_maintenance3");
+       }
+
+       VkPhysicalDeviceIDProperties                            IDProperties[count];
+       VkPhysicalDeviceMaintenance3Properties          maintenance3Properties[count];
+       VkPhysicalDeviceMultiviewProperties                     multiviewProperties[count];
+       VkPhysicalDevicePointClippingProperties         pointClippingProperties[count];
+       VkPhysicalDeviceProtectedMemoryProperties       protectedMemoryPropertiesKHR[count];
+       VkPhysicalDeviceSubgroupProperties                      subgroupProperties[count];
+
+       for (int ndx = 0; ndx < count; ++ndx)
+       {
+               deMemset(&IDProperties[ndx],                                    0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties                           ));
+               deMemset(&maintenance3Properties[ndx],                  0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties         ));
+               deMemset(&multiviewProperties[ndx],                             0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties            ));
+               deMemset(&pointClippingProperties[ndx],                 0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties        ));
+               deMemset(&protectedMemoryPropertiesKHR[ndx],    0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties      ));
+               deMemset(&subgroupProperties[ndx],                              0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties                     ));
+
+               IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
+               IDProperties[ndx].pNext = &maintenance3Properties[ndx];
+
+               maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
+               maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
+
+               multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
+               multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
+
+               pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
+               pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
+
+               protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
+               protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
+
+               subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
+               subgroupProperties[ndx].pNext = DE_NULL;
+
+               extProperties.pNext = &IDProperties[ndx];
+
+               vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+
+               IDProperties[ndx].pNext                                         = DE_NULL;
+               maintenance3Properties[ndx].pNext                       = DE_NULL;
+               multiviewProperties[ndx].pNext                          = DE_NULL;
+               pointClippingProperties[ndx].pNext                      = DE_NULL;
+               protectedMemoryPropertiesKHR[ndx].pNext         = DE_NULL;
+               subgroupProperties[ndx].pNext                           = DE_NULL;
+       }
+
+       if (khr_external_memory_capabilities)
+       {
+               if ((deMemCmp(IDProperties[0].deviceUUID, IDProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
+                       (deMemCmp(IDProperties[0].driverUUID, IDProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
+                       (IDProperties[0].deviceLUIDValid        != IDProperties[1].deviceLUIDValid))
+               {
+                       TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
+               }
+               else if (IDProperties[0].deviceLUIDValid)
+               {
+                       // If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
+                       // so thay can only be compared when deviceLUIDValid is VK_TRUE.
+                       if ((deMemCmp(IDProperties[0].deviceLUID, IDProperties[1].deviceLUID, VK_UUID_SIZE) != 0) ||
+                               (IDProperties[0].deviceNodeMask         != IDProperties[1].deviceNodeMask))
+                       {
+                               TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
+                       }
+               }
+       }
+       if (khr_maintenance3 &&
+               ((maintenance3Properties[0].maxPerSetDescriptors        != maintenance3Properties[1].maxPerSetDescriptors) ||
+               (maintenance3Properties[0].maxMemoryAllocationSize      != maintenance3Properties[1].maxMemoryAllocationSize))
+               )
+       {
+               TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
+       }
+       if (khr_multiview &&
+               ((multiviewProperties[0].maxMultiviewViewCount          != multiviewProperties[1].maxMultiviewViewCount) ||
+               (multiviewProperties[0].maxMultiviewInstanceIndex       != multiviewProperties[1].maxMultiviewInstanceIndex))
+               )
+       {
+               TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties");
+       }
+       if (khr_maintenance2 &&
+               (pointClippingProperties[0].pointClippingBehavior != pointClippingProperties[1].pointClippingBehavior))
+       {
+               TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties");
+       }
+       if (!apiVersionSmallerThen_1_1)
+       {
+               if(protectedMemoryPropertiesKHR[0].protectedNoFault != protectedMemoryPropertiesKHR[1].protectedNoFault)
+               {
+                       TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
+               }
+               if ((subgroupProperties[0].subgroupSize                                 != subgroupProperties[1].subgroupSize) ||
+                       (subgroupProperties[0].supportedStages                          != subgroupProperties[1].supportedStages) ||
+                       (subgroupProperties[0].supportedOperations                      != subgroupProperties[1].supportedOperations) ||
+                       (subgroupProperties[0].quadOperationsInAllStages        != subgroupProperties[1].quadOperationsInAllStages))
+               {
+                       TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
+               }
+       }
+
+       if (khr_external_memory_capabilities)
+               log << TestLog::Message << IDProperties[0]                                      << TestLog::EndMessage;
+       if (khr_maintenance3)
+               log << TestLog::Message << maintenance3Properties[0]                    << TestLog::EndMessage;
+       if (khr_multiview)
+               log << TestLog::Message << multiviewProperties[0]                               << TestLog::EndMessage;
+       if (khr_maintenance2)
+               log << TestLog::Message << pointClippingProperties[0]                   << TestLog::EndMessage;
+       if (!apiVersionSmallerThen_1_1)
+       {
+               log << TestLog::Message << protectedMemoryPropertiesKHR[0]      << TestLog::EndMessage
+                       << TestLog::Message << subgroupProperties[0]                            << TestLog::EndMessage;
+       }
+
+       const vector<VkExtensionProperties>     extensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
+
+       if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_push_descriptor")))
        {
-               const int count = 2u;
-               VkPhysicalDeviceIDProperties                                                            IDProperties[count];
-               VkPhysicalDeviceMaintenance3Properties                                          maintenance3Properties[count];
-               VkPhysicalDeviceMultiviewProperties                                                     multiviewProperties[count];
-               VkPhysicalDevicePointClippingProperties                                         pointClippingProperties[count];
-               VkPhysicalDeviceProtectedMemoryProperties                                       protectedMemoryPropertiesKHR[count];
-               VkPhysicalDeviceSubgroupProperties                                                      subgroupProperties[count];
+               VkPhysicalDevicePushDescriptorPropertiesKHR             pushDescriptorProperties[count];
 
                for (int ndx = 0; ndx < count; ++ndx)
                {
+                       deMemset(&pushDescriptorProperties[ndx], 0, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
 
-                       deMemset(&IDProperties[ndx],                                    0xFF, sizeof(VkPhysicalDeviceIDProperties                                               ));
-                       deMemset(&maintenance3Properties[ndx],                  0xFF, sizeof(VkPhysicalDeviceMaintenance3Properties                             ));
-                       deMemset(&multiviewProperties[ndx],                             0xFF, sizeof(VkPhysicalDeviceMultiviewProperties                                ));
-                       deMemset(&pointClippingProperties[ndx],                 0xFF, sizeof(VkPhysicalDevicePointClippingProperties                    ));
-                       deMemset(&protectedMemoryPropertiesKHR[ndx],    0xFF, sizeof(VkPhysicalDeviceProtectedMemoryProperties                  ));
-                       deMemset(&subgroupProperties[ndx],                              0xFF, sizeof(VkPhysicalDeviceSubgroupProperties                                 ));
+                       pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
+                       pushDescriptorProperties[ndx].pNext     = DE_NULL;
 
+                       extProperties.pNext = &pushDescriptorProperties[ndx];
 
-                       IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
-                       IDProperties[ndx].pNext = &maintenance3Properties[ndx];
+                       vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
 
-                       maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
-                       maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
+                       pushDescriptorProperties[ndx].pNext = DE_NULL;
+               }
 
-                       multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
-                       multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
+               if (deMemCmp(&pushDescriptorProperties[0], &pushDescriptorProperties[1], sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)) != 0)
+               {
+                       TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2 in VkPhysicalDevicePushDescriptorPropertiesKHR ");
+               }
 
-                       pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
-                       pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
+               log << TestLog::Message << pushDescriptorProperties[0] << TestLog::EndMessage;
 
-                       protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
-                       protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
+               if (pushDescriptorProperties[0].maxPushDescriptors < 32)
+               {
+                       TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
+               }
+       }
+       if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_shader_float_controls")))
+       {
+               VkPhysicalDeviceFloatControlsPropertiesKHR floatControlsProperties[count];
 
-                       subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
-                       subgroupProperties[ndx].pNext = DE_NULL;
+               for (int ndx = 0; ndx < count; ++ndx)
+               {
+                       deMemset(&floatControlsProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
+                       floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
+                       floatControlsProperties[ndx].pNext = DE_NULL;
 
-                       extProperties.pNext = &IDProperties[ndx];
+                       extProperties.pNext = &floatControlsProperties[ndx];
 
                        vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
+               }
+
+               if (deMemCmp(&floatControlsProperties[0], &floatControlsProperties[1], sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)) != 0)
+               {
+                       TCU_FAIL("Mismatch in VkPhysicalDeviceFloatControlsPropertiesKHR");
+               }
+
+               log << TestLog::Message << floatControlsProperties[0] << TestLog::EndMessage;
+       }
+
+       if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_depth_stencil_resolve")))
+       {
+               VkPhysicalDeviceDepthStencilResolvePropertiesKHR  dsResolveProperties[count];
+
+               for (int ndx = 0; ndx < count; ++ndx)
+               {
+                       deMemset(&dsResolveProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
+                       dsResolveProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
+                       dsResolveProperties[ndx].pNext = DE_NULL;
 
-                       IDProperties[ndx].pNext                                         = DE_NULL;
-                       maintenance3Properties[ndx].pNext                       = DE_NULL;
-                       multiviewProperties[ndx].pNext                          = DE_NULL;
-                       pointClippingProperties[ndx].pNext                      = DE_NULL;
-                       protectedMemoryPropertiesKHR[ndx].pNext         = DE_NULL;
-                       subgroupProperties[ndx].pNext                           = DE_NULL;
+                       extProperties.pNext = &dsResolveProperties[ndx];
+
+                       vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
                }
 
-               if (
-                       deMemCmp(&IDProperties[0],                                      &IDProperties[1],                                       sizeof(VkPhysicalDeviceIDProperties     ))                                                      != 0 ||
-                       deMemCmp(&maintenance3Properties[0],            &maintenance3Properties[1],                     sizeof(VkPhysicalDeviceMaintenance3Properties))                                 != 0 ||
-                       deMemCmp(&multiviewProperties[0],                       &multiviewProperties[1],                        sizeof(VkPhysicalDeviceMultiviewProperties))                                    != 0 ||
-                       deMemCmp(&pointClippingProperties[0],           &pointClippingProperties[1],            sizeof(VkPhysicalDevicePointClippingProperties))                                != 0 ||
-                       deMemCmp(&protectedMemoryPropertiesKHR[0],      &protectedMemoryPropertiesKHR[1],       sizeof(VkPhysicalDeviceProtectedMemoryProperties))                              != 0 ||
-                       deMemCmp(&subgroupProperties[0],                        &subgroupProperties[1],                         sizeof(VkPhysicalDeviceSubgroupProperties))                                             != 0
-                       )
+               if (deMemCmp(&dsResolveProperties[0], &dsResolveProperties[1], sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)) != 0)
                {
-                       TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2");
+                       TCU_FAIL("Mismatch in VkPhysicalDeviceDepthStencilResolvePropertiesKHR");
                }
 
-               log << TestLog::Message << toString(IDProperties[0])                            << TestLog::EndMessage
-               << TestLog::Message             << toString(maintenance3Properties[0])                  << TestLog::EndMessage
-               << TestLog::Message             << toString(multiviewProperties[0])                             << TestLog::EndMessage
-               << TestLog::Message             << toString(pointClippingProperties[0])                 << TestLog::EndMessage
-               << TestLog::Message             << toString(protectedMemoryPropertiesKHR[0])    << TestLog::EndMessage
-               << TestLog::Message             << toString(subgroupProperties[0])                              << TestLog::EndMessage;
+               log << TestLog::Message << dsResolveProperties[0] << TestLog::EndMessage;
        }
 
        return tcu::TestStatus::pass("Querying device properties succeeded");
@@ -3049,7 +3062,7 @@ tcu::TestStatus deviceFormatProperties2 (Context& context)
 {
        const PlatformInterface&                vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                    vki                             (vkp, *instance);
        TestLog&                                                log                             = context.getTestContext().getLog();
 
@@ -3080,21 +3093,11 @@ tcu::TestStatus deviceFormatProperties2 (Context& context)
        return tcu::TestStatus::pass("Querying device format properties succeeded");
 }
 
-string toString (const VkQueueFamilyProperties2& value)
-{
-       std::ostringstream      s;
-       s << "VkQueueFamilyProperties2 = {\n";
-       s << "\tsType = " << value.sType << '\n';
-       s << "\tqueueFamilyProperties = " << value.queueFamilyProperties << '\n';
-       s << '}';
-       return s.str();
-}
-
 tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
 {
        const PlatformInterface&                vkp                                             = context.getPlatformInterface();
        const VkPhysicalDevice                  physicalDevice                  = context.getPhysicalDevice();
-       const Unique<VkInstance>                instance                                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                instance                                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                    vki                                             (vkp, *instance);
        TestLog&                                                log                                             = context.getTestContext().getLog();
        deUint32                                                numCoreQueueFamilies    = ~0u;
@@ -3135,7 +3138,7 @@ tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
                                TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");
 
                        log << TestLog::Message << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
-                       << TestLog::Message << toString(extProperties[ndx]) << TestLog::EndMessage;
+                       << TestLog::Message << extProperties[ndx] << TestLog::EndMessage;
                }
        }
 
@@ -3146,7 +3149,7 @@ tcu::TestStatus deviceMemoryProperties2 (Context& context)
 {
        const PlatformInterface&                        vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice                          physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>                        instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                        instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                            vki                             (vkp, *instance);
        TestLog&                                                        log                             = context.getTestContext().getLog();
        VkPhysicalDeviceMemoryProperties        coreProperties;
@@ -3174,13 +3177,18 @@ tcu::TestStatus deviceMemoryProperties2 (Context& context)
 
 tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
 {
+       if (isYCbCrFormat(format))
+               // check if Ycbcr format enums are valid given the version and extensions
+               checkYcbcrApiSupport(context);
+
        TestLog&                                                log                             = context.getTestContext().getLog();
 
        const PlatformInterface&                vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                    vki                             (vkp, *instance);
 
+       const VkImageCreateFlags                ycbcrFlags              = isYCbCrFormat(format) ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (VkImageCreateFlags)0u;
        const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
                                                                                                        | VK_IMAGE_USAGE_TRANSFER_DST_BIT
                                                                                                        | VK_IMAGE_USAGE_SAMPLED_BIT
@@ -3193,7 +3201,8 @@ tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format,
                                                                                                        | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
                                                                                                        | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
                                                                                                        | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
-                                                                                                       | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+                                                                                                       | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
+                                                                                                       | ycbcrFlags;
 
        for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
        {
@@ -3247,7 +3256,7 @@ tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat f
 
        const PlatformInterface&                vkp                             = context.getPlatformInterface();
        const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
-       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
+       const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
        const InstanceDriver                    vki                             (vkp, *instance);
 
        const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
@@ -3327,6 +3336,71 @@ tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat f
        return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
 }
 
+tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
+{
+       return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
+}
+
+void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
+{
+       DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
+
+       static const struct
+       {
+               VkFormat                                                                begin;
+               VkFormat                                                                end;
+               ImageFormatPropertyCase                                 params;
+       } s_formatRanges[] =
+       {
+               // core formats
+               { (VkFormat)(VK_FORMAT_UNDEFINED + 1),  VK_CORE_FORMAT_LAST,                                                                            params },
+
+               // YCbCr formats
+               { VK_FORMAT_G8B8G8R8_422_UNORM_KHR,             (VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR + 1),     params }
+       };
+
+       for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
+       {
+               const VkFormat                                                          rangeBegin              = s_formatRanges[rangeNdx].begin;
+               const VkFormat                                                          rangeEnd                = s_formatRanges[rangeNdx].end;
+
+               for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
+               {
+                       const bool                      isYCbCr         = isYCbCrFormat(format);
+                       const bool                      isSparse        = (params.testFunction == sparseImageFormatProperties2);
+
+                       if (isYCbCr && isSparse)
+                               continue;
+
+                       if (isYCbCr && params.imageType != VK_IMAGE_TYPE_2D)
+                               continue;
+
+                       const char* const       enumName        = getFormatName(format);
+                       const string            caseName        = de::toLower(string(enumName).substr(10));
+
+                       params.format = format;
+
+                       addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
+               }
+       }
+}
+
+void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
+{
+       DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);
+
+       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",     "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
+       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",      "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
+}
+
+void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
+{
+       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
+       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
+       testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
+}
+
+
 // Android CTS -specific tests
 
 namespace android
@@ -3337,8 +3411,7 @@ void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedE
        for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
        {
                const string    extensionName   (extension->extensionName);
-               const bool              mustBeKnown             = de::beginsWith(extensionName, "VK_KHX_")              ||
-                                                                                 de::beginsWith(extensionName, "VK_GOOGLE_")   ||
+               const bool              mustBeKnown             = de::beginsWith(extensionName, "VK_GOOGLE_")   ||
                                                                                  de::beginsWith(extensionName, "VK_ANDROID_");
 
                if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
@@ -3355,6 +3428,7 @@ tcu::TestStatus testNoUnknownExtensions (Context& context)
 
        // All known extensions should be added to allowedExtensions:
        // allowedExtensions.insert("VK_GOOGLE_extension1");
+       allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
        allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");
 
        // Instance extensions
@@ -3482,6 +3556,7 @@ tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
                addFunctionCase(deviceInfoTests.get(), "memory_properties",                     "Memory properties",            deviceMemoryProperties);
                addFunctionCase(deviceInfoTests.get(), "layers",                                        "Layers",                                       enumerateDeviceLayers);
                addFunctionCase(deviceInfoTests.get(), "extensions",                            "Extensions",                           enumerateDeviceExtensions);
+               addFunctionCase(deviceInfoTests.get(), "no_khx_extensions",                     "KHX extensions",                       testNoKhxExtensions);
 
                infoTests->addChild(deviceInfoTests.release());
        }