/* WARNING: This is auto-generated file. Do not modify, since changes will
 * be lost! Modify the generating script instead.
 * This file was generated by /scripts/gen_framework.py
 */


tcu::TestStatus createDeviceWithUnsupportedFeaturesTest16BitStorageFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevice16BitStorageFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevice16BitStorageFeatures, storageBuffer16BitAccess),
		FEATURE_ITEM (VkPhysicalDevice16BitStorageFeatures, uniformAndStorageBuffer16BitAccess),
		FEATURE_ITEM (VkPhysicalDevice16BitStorageFeatures, storagePushConstant16),
		FEATURE_ITEM (VkPhysicalDevice16BitStorageFeatures, storageInputOutput16),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevice16BitStorageFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 4, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMultiviewFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMultiviewFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMultiviewFeatures, multiview),
		FEATURE_ITEM (VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader),
		FEATURE_ITEM (VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMultiviewFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVariablePointersFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVariablePointersFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVariablePointersFeatures, variablePointersStorageBuffer),
		FEATURE_ITEM (VkPhysicalDeviceVariablePointersFeatures, variablePointers),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVariablePointersFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestProtectedMemoryFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceProtectedMemoryFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceProtectedMemoryFeatures, protectedMemory),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceProtectedMemoryFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestSamplerYcbcrConversionFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceSamplerYcbcrConversionFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceSamplerYcbcrConversionFeatures, samplerYcbcrConversion),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderDrawParametersFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderDrawParametersFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderDrawParametersFeatures, shaderDrawParameters),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderDrawParametersFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVulkan11Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVulkan11Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, storageBuffer16BitAccess),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, uniformAndStorageBuffer16BitAccess),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, storagePushConstant16),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, storageInputOutput16),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, multiview),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, multiviewGeometryShader),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, multiviewTessellationShader),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, variablePointers),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, protectedMemory),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, samplerYcbcrConversion),
		FEATURE_ITEM (VkPhysicalDeviceVulkan11Features, shaderDrawParameters),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVulkan11Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 12, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, DE_NULL, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVulkan12Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVulkan12Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, samplerMirrorClampToEdge),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, drawIndirectCount),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, storageBuffer8BitAccess),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, uniformAndStorageBuffer8BitAccess),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, storagePushConstant8),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderBufferInt64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderSharedInt64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderFloat16),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderInt8),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderUniformBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderSampledImageArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderStorageBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderStorageImageArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingUniformBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingSampledImageUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingStorageImageUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingStorageBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingUniformTexelBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingStorageTexelBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingUpdateUnusedWhilePending),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingPartiallyBound),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, descriptorBindingVariableDescriptorCount),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, runtimeDescriptorArray),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, samplerFilterMinmax),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, scalarBlockLayout),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, imagelessFramebuffer),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, uniformBufferStandardLayout),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderSubgroupExtendedTypes),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, separateDepthStencilLayouts),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, hostQueryReset),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, timelineSemaphore),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, bufferDeviceAddress),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, bufferDeviceAddressCaptureReplay),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, bufferDeviceAddressMultiDevice),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, vulkanMemoryModel),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, vulkanMemoryModelDeviceScope),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, vulkanMemoryModelAvailabilityVisibilityChains),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderOutputViewportIndex),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, shaderOutputLayer),
		FEATURE_ITEM (VkPhysicalDeviceVulkan12Features, subgroupBroadcastDynamicId),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVulkan12Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 47, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, DE_NULL, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTest8BitStorageFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevice8BitStorageFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevice8BitStorageFeatures, storageBuffer8BitAccess),
		FEATURE_ITEM (VkPhysicalDevice8BitStorageFeatures, uniformAndStorageBuffer8BitAccess),
		FEATURE_ITEM (VkPhysicalDevice8BitStorageFeatures, storagePushConstant8),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevice8BitStorageFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderAtomicInt64Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderAtomicInt64Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicInt64Features, shaderBufferInt64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicInt64Features, shaderSharedInt64Atomics),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderAtomicInt64Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderFloat16Int8Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderFloat16Int8Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderFloat16Int8Features, shaderFloat16),
		FEATURE_ITEM (VkPhysicalDeviceShaderFloat16Int8Features, shaderInt8),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderFloat16Int8Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDescriptorIndexingFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDescriptorIndexingFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderInputAttachmentArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderUniformTexelBufferArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderStorageTexelBufferArrayDynamicIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderUniformBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderSampledImageArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderStorageBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderStorageImageArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderInputAttachmentArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderUniformTexelBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, shaderStorageTexelBufferArrayNonUniformIndexing),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingUniformBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingSampledImageUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingStorageImageUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingStorageBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingUniformTexelBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingStorageTexelBufferUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingUpdateUnusedWhilePending),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingPartiallyBound),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, descriptorBindingVariableDescriptorCount),
		FEATURE_ITEM (VkPhysicalDeviceDescriptorIndexingFeatures, runtimeDescriptorArray),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDescriptorIndexingFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 20, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestScalarBlockLayoutFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceScalarBlockLayoutFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceScalarBlockLayoutFeatures, scalarBlockLayout),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceScalarBlockLayoutFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVulkanMemoryModelFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVulkanMemoryModelFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVulkanMemoryModelFeatures, vulkanMemoryModel),
		FEATURE_ITEM (VkPhysicalDeviceVulkanMemoryModelFeatures, vulkanMemoryModelDeviceScope),
		FEATURE_ITEM (VkPhysicalDeviceVulkanMemoryModelFeatures, vulkanMemoryModelAvailabilityVisibilityChains),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVulkanMemoryModelFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestImagelessFramebufferFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceImagelessFramebufferFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceImagelessFramebufferFeatures, imagelessFramebuffer),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceImagelessFramebufferFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestUniformBufferStandardLayoutFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceUniformBufferStandardLayoutFeatures, uniformBufferStandardLayout),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceUniformBufferStandardLayoutFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderSubgroupExtendedTypesFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures, shaderSubgroupExtendedTypes),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestSeparateDepthStencilLayoutsFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures, separateDepthStencilLayouts),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestHostQueryResetFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceHostQueryResetFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceHostQueryResetFeatures, hostQueryReset),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceHostQueryResetFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestTimelineSemaphoreFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceTimelineSemaphoreFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceTimelineSemaphoreFeatures, timelineSemaphore),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceTimelineSemaphoreFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceBufferDeviceAddressFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeatures, bufferDeviceAddress),
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeatures, bufferDeviceAddressCaptureReplay),
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeatures, bufferDeviceAddressMultiDevice),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceBufferDeviceAddressFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVulkan13Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVulkan13Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, robustImageAccess),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, inlineUniformBlock),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, descriptorBindingInlineUniformBlockUpdateAfterBind),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, pipelineCreationCacheControl),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, privateData),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, shaderDemoteToHelperInvocation),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, shaderTerminateInvocation),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, subgroupSizeControl),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, computeFullSubgroups),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, synchronization2),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, textureCompressionASTC_HDR),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, shaderZeroInitializeWorkgroupMemory),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, dynamicRendering),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, shaderIntegerDotProduct),
		FEATURE_ITEM (VkPhysicalDeviceVulkan13Features, maintenance4),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVulkan13Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 15, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, DE_NULL, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderTerminateInvocationFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderTerminateInvocationFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderTerminateInvocationFeatures, shaderTerminateInvocation),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderTerminateInvocationFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderDemoteToHelperInvocationFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures, shaderDemoteToHelperInvocation),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPrivateDataFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePrivateDataFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePrivateDataFeatures, privateData),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePrivateDataFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPipelineCreationCacheControlFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePipelineCreationCacheControlFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePipelineCreationCacheControlFeatures, pipelineCreationCacheControl),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePipelineCreationCacheControlFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestSynchronization2Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceSynchronization2Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceSynchronization2Features, synchronization2),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceSynchronization2Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestZeroInitializeWorkgroupMemoryFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures, shaderZeroInitializeWorkgroupMemory),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestImageRobustnessFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceImageRobustnessFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceImageRobustnessFeatures, robustImageAccess),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceImageRobustnessFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestSubgroupSizeControlFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceSubgroupSizeControlFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceSubgroupSizeControlFeatures, subgroupSizeControl),
		FEATURE_ITEM (VkPhysicalDeviceSubgroupSizeControlFeatures, computeFullSubgroups),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceSubgroupSizeControlFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestInlineUniformBlockFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceInlineUniformBlockFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceInlineUniformBlockFeatures, inlineUniformBlock),
		FEATURE_ITEM (VkPhysicalDeviceInlineUniformBlockFeatures, descriptorBindingInlineUniformBlockUpdateAfterBind),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceInlineUniformBlockFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestTextureCompressionASTCHDRFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceTextureCompressionASTCHDRFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceTextureCompressionASTCHDRFeatures, textureCompressionASTC_HDR),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceTextureCompressionASTCHDRFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDynamicRenderingFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDynamicRenderingFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDynamicRenderingFeatures, dynamicRendering),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDynamicRenderingFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderIntegerDotProductFeatures (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderIntegerDotProductFeatures>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderIntegerDotProductFeatures, shaderIntegerDotProduct),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderIntegerDotProductFeatures*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMaintenance4Features (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMaintenance4Features>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMaintenance4Features, maintenance4),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMaintenance4Features*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPerformanceQueryFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePerformanceQueryFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePerformanceQueryFeaturesKHR, performanceCounterQueryPools),
		FEATURE_ITEM (VkPhysicalDevicePerformanceQueryFeaturesKHR, performanceCounterMultipleQueryPools),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePerformanceQueryFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderClockFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderClockFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderClockFeaturesKHR, shaderSubgroupClock),
		FEATURE_ITEM (VkPhysicalDeviceShaderClockFeaturesKHR, shaderDeviceClock),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderClockFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestGlobalPriorityQueryFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR, globalPriorityQuery),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentShadingRateFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateFeaturesKHR, pipelineFragmentShadingRate),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateFeaturesKHR, primitiveFragmentShadingRate),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateFeaturesKHR, attachmentFragmentShadingRate),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentShadingRateFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPresentWaitFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePresentWaitFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePresentWaitFeaturesKHR, presentWait),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePresentWaitFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPipelineExecutablePropertiesFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR, pipelineExecutableInfo),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPresentIdFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePresentIdFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePresentIdFeaturesKHR, presentId),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePresentIdFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderSubgroupUniformControlFlowFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR, shaderSubgroupUniformControlFlow),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestWorkgroupMemoryExplicitLayoutFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, workgroupMemoryExplicitLayout),
		FEATURE_ITEM (VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, workgroupMemoryExplicitLayoutScalarBlockLayout),
		FEATURE_ITEM (VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, workgroupMemoryExplicitLayout8BitAccess),
		FEATURE_ITEM (VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, workgroupMemoryExplicitLayout16BitAccess),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 4, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestTransformFeedbackFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceTransformFeedbackFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceTransformFeedbackFeaturesEXT, transformFeedback),
		FEATURE_ITEM (VkPhysicalDeviceTransformFeedbackFeaturesEXT, geometryStreams),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceTransformFeedbackFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestCornerSampledImageFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceCornerSampledImageFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceCornerSampledImageFeaturesNV, cornerSampledImage),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceCornerSampledImageFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestASTCDecodeFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceASTCDecodeFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceASTCDecodeFeaturesEXT, decodeModeSharedExponent),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceASTCDecodeFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestConditionalRenderingFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceConditionalRenderingFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceConditionalRenderingFeaturesEXT, conditionalRendering),
		FEATURE_ITEM (VkPhysicalDeviceConditionalRenderingFeaturesEXT, inheritedConditionalRendering),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceConditionalRenderingFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDepthClipEnableFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDepthClipEnableFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDepthClipEnableFeaturesEXT, depthClipEnable),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestBlendOperationAdvancedFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT, advancedBlendCoherentOperations),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderSMBuiltinsFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderSMBuiltinsFeaturesNV, shaderSMBuiltins),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderSMBuiltinsFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShadingRateImageFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShadingRateImageFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShadingRateImageFeaturesNV, shadingRateImage),
		FEATURE_ITEM (VkPhysicalDeviceShadingRateImageFeaturesNV, shadingRateCoarseSampleOrder),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShadingRateImageFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRepresentativeFragmentTestFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV, representativeFragmentTest),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVertexAttributeDivisorFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateDivisor),
		FEATURE_ITEM (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateZeroDivisor),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestComputeShaderDerivativesFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceComputeShaderDerivativesFeaturesNV, computeDerivativeGroupQuads),
		FEATURE_ITEM (VkPhysicalDeviceComputeShaderDerivativesFeaturesNV, computeDerivativeGroupLinear),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceComputeShaderDerivativesFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMeshShaderFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMeshShaderFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMeshShaderFeaturesNV, taskShader),
		FEATURE_ITEM (VkPhysicalDeviceMeshShaderFeaturesNV, meshShader),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMeshShaderFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentShaderBarycentricFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV, fragmentShaderBarycentric),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderImageFootprintFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderImageFootprintFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderImageFootprintFeaturesNV, imageFootprint),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderImageFootprintFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestExclusiveScissorFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceExclusiveScissorFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceExclusiveScissorFeaturesNV, exclusiveScissor),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceExclusiveScissorFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderIntegerFunctions2FeaturesINTEL (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL, shaderIntegerFunctions2),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentDensityMapFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentDensityMapFeaturesEXT, fragmentDensityMap),
		FEATURE_ITEM (VkPhysicalDeviceFragmentDensityMapFeaturesEXT, fragmentDensityMapDynamic),
		FEATURE_ITEM (VkPhysicalDeviceFragmentDensityMapFeaturesEXT, fragmentDensityMapNonSubsampledImages),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentDensityMapFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestCoherentMemoryFeaturesAMD (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceCoherentMemoryFeaturesAMD>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceCoherentMemoryFeaturesAMD, deviceCoherentMemory),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceCoherentMemoryFeaturesAMD*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderImageAtomicInt64FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMemoryPriorityFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMemoryPriorityFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMemoryPriorityFeaturesEXT, memoryPriority),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMemoryPriorityFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDedicatedAllocationImageAliasingFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV, dedicatedAllocationImageAliasing),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT, bufferDeviceAddress),
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT, bufferDeviceAddressCaptureReplay),
		FEATURE_ITEM (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT, bufferDeviceAddressMultiDevice),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestCooperativeMatrixFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceCooperativeMatrixFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceCooperativeMatrixFeaturesNV, cooperativeMatrix),
		FEATURE_ITEM (VkPhysicalDeviceCooperativeMatrixFeaturesNV, cooperativeMatrixRobustBufferAccess),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceCooperativeMatrixFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestCoverageReductionModeFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceCoverageReductionModeFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceCoverageReductionModeFeaturesNV, coverageReductionMode),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceCoverageReductionModeFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentShaderInterlockFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT, fragmentShaderSampleInterlock),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT, fragmentShaderPixelInterlock),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT, fragmentShaderShadingRateInterlock),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestYcbcrImageArraysFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT, ycbcrImageArrays),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceYcbcrImageArraysFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestProvokingVertexFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceProvokingVertexFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceProvokingVertexFeaturesEXT, provokingVertexLast),
		FEATURE_ITEM (VkPhysicalDeviceProvokingVertexFeaturesEXT, transformFeedbackPreservesProvokingVertex),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceProvokingVertexFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestLineRasterizationFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceLineRasterizationFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, rectangularLines),
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, bresenhamLines),
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, smoothLines),
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, stippledRectangularLines),
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, stippledBresenhamLines),
		FEATURE_ITEM (VkPhysicalDeviceLineRasterizationFeaturesEXT, stippledSmoothLines),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceLineRasterizationFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 6, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderAtomicFloatFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderBufferFloat32Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderBufferFloat32AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderBufferFloat64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderBufferFloat64AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderSharedFloat32Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderSharedFloat32AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderSharedFloat64Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderSharedFloat64AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderAtomicFloatFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 12, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestIndexTypeUint8FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceIndexTypeUint8FeaturesEXT, indexTypeUint8),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceIndexTypeUint8FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestExtendedDynamicStateFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceExtendedDynamicStateFeaturesEXT, extendedDynamicState),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceExtendedDynamicStateFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestShaderAtomicFloat2FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderBufferFloat16Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderBufferFloat16AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderBufferFloat16AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderBufferFloat32AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderBufferFloat64AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderSharedFloat16Atomics),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderSharedFloat16AtomicAdd),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderSharedFloat16AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderSharedFloat32AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderSharedFloat64AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax),
		FEATURE_ITEM (VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 12, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDeviceGeneratedCommandsFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV, deviceGeneratedCommands),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestInheritedViewportScissorFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceInheritedViewportScissorFeaturesNV, inheritedViewportScissor2D),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceInheritedViewportScissorFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestTexelBufferAlignmentFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT, texelBufferAlignment),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDeviceMemoryReportFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDeviceMemoryReportFeaturesEXT, deviceMemoryReport),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDeviceMemoryReportFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRobustness2FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRobustness2FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2),
		FEATURE_ITEM (VkPhysicalDeviceRobustness2FeaturesEXT, robustImageAccess2),
		FEATURE_ITEM (VkPhysicalDeviceRobustness2FeaturesEXT, nullDescriptor),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRobustness2FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestCustomBorderColorFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceCustomBorderColorFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceCustomBorderColorFeaturesEXT, customBorderColors),
		FEATURE_ITEM (VkPhysicalDeviceCustomBorderColorFeaturesEXT, customBorderColorWithoutFormat),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceCustomBorderColorFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDiagnosticsConfigFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDiagnosticsConfigFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDiagnosticsConfigFeaturesNV, diagnosticsConfig),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDiagnosticsConfigFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentShadingRateEnumsFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV, fragmentShadingRateEnums),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV, supersampleFragmentShadingRates),
		FEATURE_ITEM (VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV, noInvocationFragmentShadingRates),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRayTracingMotionBlurFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRayTracingMotionBlurFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRayTracingMotionBlurFeaturesNV, rayTracingMotionBlur),
		FEATURE_ITEM (VkPhysicalDeviceRayTracingMotionBlurFeaturesNV, rayTracingMotionBlurPipelineTraceRaysIndirect),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRayTracingMotionBlurFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestYcbcr2Plane444FormatsFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT, ycbcr2plane444Formats),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentDensityMap2FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentDensityMap2FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentDensityMap2FeaturesEXT, fragmentDensityMapDeferred),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentDensityMap2FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTest4444FormatsFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevice4444FormatsFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevice4444FormatsFeaturesEXT, formatA4R4G4B4),
		FEATURE_ITEM (VkPhysicalDevice4444FormatsFeaturesEXT, formatA4B4G4R4),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevice4444FormatsFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRasterizationOrderAttachmentAccessFeaturesARM (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM, rasterizationOrderColorAttachmentAccess),
		FEATURE_ITEM (VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM, rasterizationOrderDepthAttachmentAccess),
		FEATURE_ITEM (VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM, rasterizationOrderStencilAttachmentAccess),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRGBA10X6FormatsFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT, formatRgba10x6WithoutYCbCrSampler),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMutableDescriptorTypeFeaturesVALVE (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE, mutableDescriptorType),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestVertexInputDynamicStateFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT, vertexInputDynamicState),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestDepthClipControlFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceDepthClipControlFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceDepthClipControlFeaturesEXT, depthClipControl),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceDepthClipControlFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPrimitiveTopologyListRestartFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, primitiveTopologyListRestart),
		FEATURE_ITEM (VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, primitiveTopologyPatchListRestart),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestSubpassShadingFeaturesHUAWEI (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceSubpassShadingFeaturesHUAWEI>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceSubpassShadingFeaturesHUAWEI, subpassShading),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceSubpassShadingFeaturesHUAWEI*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestInvocationMaskFeaturesHUAWEI (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceInvocationMaskFeaturesHUAWEI>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceInvocationMaskFeaturesHUAWEI, invocationMask),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceInvocationMaskFeaturesHUAWEI*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestExternalMemoryRDMAFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceExternalMemoryRDMAFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceExternalMemoryRDMAFeaturesNV, externalMemoryRDMA),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceExternalMemoryRDMAFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestExtendedDynamicState2FeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT, extendedDynamicState2),
		FEATURE_ITEM (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT, extendedDynamicState2LogicOp),
		FEATURE_ITEM (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT, extendedDynamicState2PatchControlPoints),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceExtendedDynamicState2FeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 3, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestColorWriteEnableFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceColorWriteEnableFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceColorWriteEnableFeaturesEXT, colorWriteEnable),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceColorWriteEnableFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestImageViewMinLodFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceImageViewMinLodFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceImageViewMinLodFeaturesEXT, minLod),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceImageViewMinLodFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestMultiDrawFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceMultiDrawFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceMultiDrawFeaturesEXT, multiDraw),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceMultiDrawFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestBorderColorSwizzleFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceBorderColorSwizzleFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceBorderColorSwizzleFeaturesEXT, borderColorSwizzle),
		FEATURE_ITEM (VkPhysicalDeviceBorderColorSwizzleFeaturesEXT, borderColorSwizzleFromImage),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceBorderColorSwizzleFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 2, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPageableDeviceLocalMemoryFeaturesEXT (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT, pageableDeviceLocalMemory),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestFragmentDensityMapOffsetFeaturesQCOM (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM, fragmentDensityMapOffset),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestLinearColorAttachmentFeaturesNV (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceLinearColorAttachmentFeaturesNV>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceLinearColorAttachmentFeaturesNV, linearColorAttachment),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceLinearColorAttachmentFeaturesNV*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestAccelerationStructureFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceAccelerationStructureFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceAccelerationStructureFeaturesKHR, accelerationStructure),
		FEATURE_ITEM (VkPhysicalDeviceAccelerationStructureFeaturesKHR, accelerationStructureCaptureReplay),
		FEATURE_ITEM (VkPhysicalDeviceAccelerationStructureFeaturesKHR, accelerationStructureIndirectBuild),
		FEATURE_ITEM (VkPhysicalDeviceAccelerationStructureFeaturesKHR, accelerationStructureHostCommands),
		FEATURE_ITEM (VkPhysicalDeviceAccelerationStructureFeaturesKHR, descriptorBindingAccelerationStructureUpdateAfterBind),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceAccelerationStructureFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 5, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRayTracingPipelineFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipeline),
		FEATURE_ITEM (VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay),
		FEATURE_ITEM (VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed),
		FEATURE_ITEM (VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineTraceRaysIndirect),
		FEATURE_ITEM (VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTraversalPrimitiveCulling),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRayTracingPipelineFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 5, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestRayQueryFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDeviceRayQueryFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDeviceRayQueryFeaturesKHR, rayQuery),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDeviceRayQueryFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 1, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


tcu::TestStatus createDeviceWithUnsupportedFeaturesTestPortabilitySubsetFeaturesKHR (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	int										numErrors				= 0;

	VkPhysicalDeviceFeatures emptyDeviceFeatures;
	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<VkPhysicalDevicePortabilitySubsetFeaturesKHR>()))
	{
		static const Feature features[] =
		{
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, constantAlphaColorBlendFactors),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, events),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, imageViewFormatReinterpretation),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, imageViewFormatSwizzle),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, imageView2DOn3DImage),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, multisampleArrayImage),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, mutableComparisonSamplers),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, pointPolygons),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, samplerMipLodBias),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, separateStencilMaskRef),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, shaderSampleRateInterpolationFunctions),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, tessellationIsolines),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, tessellationPointMode),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, triangleFans),
		FEATURE_ITEM (VkPhysicalDevicePortabilitySubsetFeaturesKHR, vertexAttributeAccessBeyondStride),
		};
		auto* supportedFeatures = reinterpret_cast<const VkPhysicalDevicePortabilitySubsetFeaturesKHR*>(featuresStruct);
		checkFeatures(vkp, instance, instanceDriver, physicalDevice, 15, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, &extensionNames, emptyDeviceFeatures);
	}

	if (numErrors > 0)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}


void addSeparateUnsupportedFeatureTests (tcu::TestCaseGroup* testGroup)
{

	addFunctionCase(testGroup, "16_bit_storage_features", "createDeviceWithUnsupportedFeaturesTest16BitStorageFeatures", createDeviceWithUnsupportedFeaturesTest16BitStorageFeatures);
	addFunctionCase(testGroup, "multiview_features", "createDeviceWithUnsupportedFeaturesTestMultiviewFeatures", createDeviceWithUnsupportedFeaturesTestMultiviewFeatures);
	addFunctionCase(testGroup, "variable_pointers_features", "createDeviceWithUnsupportedFeaturesTestVariablePointersFeatures", createDeviceWithUnsupportedFeaturesTestVariablePointersFeatures);
	addFunctionCase(testGroup, "protected_memory_features", "createDeviceWithUnsupportedFeaturesTestProtectedMemoryFeatures", createDeviceWithUnsupportedFeaturesTestProtectedMemoryFeatures);
	addFunctionCase(testGroup, "sampler_ycbcr_conversion_features", "createDeviceWithUnsupportedFeaturesTestSamplerYcbcrConversionFeatures", createDeviceWithUnsupportedFeaturesTestSamplerYcbcrConversionFeatures);
	addFunctionCase(testGroup, "shader_draw_parameters_features", "createDeviceWithUnsupportedFeaturesTestShaderDrawParametersFeatures", createDeviceWithUnsupportedFeaturesTestShaderDrawParametersFeatures);
	addFunctionCase(testGroup, "vulkan11_features", "createDeviceWithUnsupportedFeaturesTestVulkan11Features", createDeviceWithUnsupportedFeaturesTestVulkan11Features);
	addFunctionCase(testGroup, "vulkan12_features", "createDeviceWithUnsupportedFeaturesTestVulkan12Features", createDeviceWithUnsupportedFeaturesTestVulkan12Features);
	addFunctionCase(testGroup, "8_bit_storage_features", "createDeviceWithUnsupportedFeaturesTest8BitStorageFeatures", createDeviceWithUnsupportedFeaturesTest8BitStorageFeatures);
	addFunctionCase(testGroup, "shader_atomic_int64_features", "createDeviceWithUnsupportedFeaturesTestShaderAtomicInt64Features", createDeviceWithUnsupportedFeaturesTestShaderAtomicInt64Features);
	addFunctionCase(testGroup, "shader_float16_int8_features", "createDeviceWithUnsupportedFeaturesTestShaderFloat16Int8Features", createDeviceWithUnsupportedFeaturesTestShaderFloat16Int8Features);
	addFunctionCase(testGroup, "descriptor_indexing_features", "createDeviceWithUnsupportedFeaturesTestDescriptorIndexingFeatures", createDeviceWithUnsupportedFeaturesTestDescriptorIndexingFeatures);
	addFunctionCase(testGroup, "scalar_block_layout_features", "createDeviceWithUnsupportedFeaturesTestScalarBlockLayoutFeatures", createDeviceWithUnsupportedFeaturesTestScalarBlockLayoutFeatures);
	addFunctionCase(testGroup, "vulkan_memory_model_features", "createDeviceWithUnsupportedFeaturesTestVulkanMemoryModelFeatures", createDeviceWithUnsupportedFeaturesTestVulkanMemoryModelFeatures);
	addFunctionCase(testGroup, "imageless_framebuffer_features", "createDeviceWithUnsupportedFeaturesTestImagelessFramebufferFeatures", createDeviceWithUnsupportedFeaturesTestImagelessFramebufferFeatures);
	addFunctionCase(testGroup, "uniform_buffer_standard_layout_features", "createDeviceWithUnsupportedFeaturesTestUniformBufferStandardLayoutFeatures", createDeviceWithUnsupportedFeaturesTestUniformBufferStandardLayoutFeatures);
	addFunctionCase(testGroup, "shader_subgroup_extended_types_features", "createDeviceWithUnsupportedFeaturesTestShaderSubgroupExtendedTypesFeatures", createDeviceWithUnsupportedFeaturesTestShaderSubgroupExtendedTypesFeatures);
	addFunctionCase(testGroup, "separate_depth_stencil_layouts_features", "createDeviceWithUnsupportedFeaturesTestSeparateDepthStencilLayoutsFeatures", createDeviceWithUnsupportedFeaturesTestSeparateDepthStencilLayoutsFeatures);
	addFunctionCase(testGroup, "host_query_reset_features", "createDeviceWithUnsupportedFeaturesTestHostQueryResetFeatures", createDeviceWithUnsupportedFeaturesTestHostQueryResetFeatures);
	addFunctionCase(testGroup, "timeline_semaphore_features", "createDeviceWithUnsupportedFeaturesTestTimelineSemaphoreFeatures", createDeviceWithUnsupportedFeaturesTestTimelineSemaphoreFeatures);
	addFunctionCase(testGroup, "buffer_device_address_features", "createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeatures", createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeatures);
	addFunctionCase(testGroup, "vulkan13_features", "createDeviceWithUnsupportedFeaturesTestVulkan13Features", createDeviceWithUnsupportedFeaturesTestVulkan13Features);
	addFunctionCase(testGroup, "shader_terminate_invocation_features", "createDeviceWithUnsupportedFeaturesTestShaderTerminateInvocationFeatures", createDeviceWithUnsupportedFeaturesTestShaderTerminateInvocationFeatures);
	addFunctionCase(testGroup, "shader_demote_to_helper_invocation_features", "createDeviceWithUnsupportedFeaturesTestShaderDemoteToHelperInvocationFeatures", createDeviceWithUnsupportedFeaturesTestShaderDemoteToHelperInvocationFeatures);
	addFunctionCase(testGroup, "private_data_features", "createDeviceWithUnsupportedFeaturesTestPrivateDataFeatures", createDeviceWithUnsupportedFeaturesTestPrivateDataFeatures);
	addFunctionCase(testGroup, "pipeline_creation_cache_control_features", "createDeviceWithUnsupportedFeaturesTestPipelineCreationCacheControlFeatures", createDeviceWithUnsupportedFeaturesTestPipelineCreationCacheControlFeatures);
	addFunctionCase(testGroup, "synchronization2_features", "createDeviceWithUnsupportedFeaturesTestSynchronization2Features", createDeviceWithUnsupportedFeaturesTestSynchronization2Features);
	addFunctionCase(testGroup, "zero_initialize_workgroup_memory_features", "createDeviceWithUnsupportedFeaturesTestZeroInitializeWorkgroupMemoryFeatures", createDeviceWithUnsupportedFeaturesTestZeroInitializeWorkgroupMemoryFeatures);
	addFunctionCase(testGroup, "image_robustness_features", "createDeviceWithUnsupportedFeaturesTestImageRobustnessFeatures", createDeviceWithUnsupportedFeaturesTestImageRobustnessFeatures);
	addFunctionCase(testGroup, "subgroup_size_control_features", "createDeviceWithUnsupportedFeaturesTestSubgroupSizeControlFeatures", createDeviceWithUnsupportedFeaturesTestSubgroupSizeControlFeatures);
	addFunctionCase(testGroup, "inline_uniform_block_features", "createDeviceWithUnsupportedFeaturesTestInlineUniformBlockFeatures", createDeviceWithUnsupportedFeaturesTestInlineUniformBlockFeatures);
	addFunctionCase(testGroup, "texture_compression_astchdr_features", "createDeviceWithUnsupportedFeaturesTestTextureCompressionASTCHDRFeatures", createDeviceWithUnsupportedFeaturesTestTextureCompressionASTCHDRFeatures);
	addFunctionCase(testGroup, "dynamic_rendering_features", "createDeviceWithUnsupportedFeaturesTestDynamicRenderingFeatures", createDeviceWithUnsupportedFeaturesTestDynamicRenderingFeatures);
	addFunctionCase(testGroup, "shader_integer_dot_product_features", "createDeviceWithUnsupportedFeaturesTestShaderIntegerDotProductFeatures", createDeviceWithUnsupportedFeaturesTestShaderIntegerDotProductFeatures);
	addFunctionCase(testGroup, "maintenance4_features", "createDeviceWithUnsupportedFeaturesTestMaintenance4Features", createDeviceWithUnsupportedFeaturesTestMaintenance4Features);
	addFunctionCase(testGroup, "performance_query_features_khr", "createDeviceWithUnsupportedFeaturesTestPerformanceQueryFeaturesKHR", createDeviceWithUnsupportedFeaturesTestPerformanceQueryFeaturesKHR);
	addFunctionCase(testGroup, "shader_clock_features_khr", "createDeviceWithUnsupportedFeaturesTestShaderClockFeaturesKHR", createDeviceWithUnsupportedFeaturesTestShaderClockFeaturesKHR);
	addFunctionCase(testGroup, "global_priority_query_features_khr", "createDeviceWithUnsupportedFeaturesTestGlobalPriorityQueryFeaturesKHR", createDeviceWithUnsupportedFeaturesTestGlobalPriorityQueryFeaturesKHR);
	addFunctionCase(testGroup, "fragment_shading_rate_features_khr", "createDeviceWithUnsupportedFeaturesTestFragmentShadingRateFeaturesKHR", createDeviceWithUnsupportedFeaturesTestFragmentShadingRateFeaturesKHR);
	addFunctionCase(testGroup, "present_wait_features_khr", "createDeviceWithUnsupportedFeaturesTestPresentWaitFeaturesKHR", createDeviceWithUnsupportedFeaturesTestPresentWaitFeaturesKHR);
	addFunctionCase(testGroup, "pipeline_executable_properties_features_khr", "createDeviceWithUnsupportedFeaturesTestPipelineExecutablePropertiesFeaturesKHR", createDeviceWithUnsupportedFeaturesTestPipelineExecutablePropertiesFeaturesKHR);
	addFunctionCase(testGroup, "present_id_features_khr", "createDeviceWithUnsupportedFeaturesTestPresentIdFeaturesKHR", createDeviceWithUnsupportedFeaturesTestPresentIdFeaturesKHR);
	addFunctionCase(testGroup, "shader_subgroup_uniform_control_flow_features_khr", "createDeviceWithUnsupportedFeaturesTestShaderSubgroupUniformControlFlowFeaturesKHR", createDeviceWithUnsupportedFeaturesTestShaderSubgroupUniformControlFlowFeaturesKHR);
	addFunctionCase(testGroup, "workgroup_memory_explicit_layout_features_khr", "createDeviceWithUnsupportedFeaturesTestWorkgroupMemoryExplicitLayoutFeaturesKHR", createDeviceWithUnsupportedFeaturesTestWorkgroupMemoryExplicitLayoutFeaturesKHR);
	addFunctionCase(testGroup, "transform_feedback_features_ext", "createDeviceWithUnsupportedFeaturesTestTransformFeedbackFeaturesEXT", createDeviceWithUnsupportedFeaturesTestTransformFeedbackFeaturesEXT);
	addFunctionCase(testGroup, "corner_sampled_image_features_nv", "createDeviceWithUnsupportedFeaturesTestCornerSampledImageFeaturesNV", createDeviceWithUnsupportedFeaturesTestCornerSampledImageFeaturesNV);
	addFunctionCase(testGroup, "astc_decode_features_ext", "createDeviceWithUnsupportedFeaturesTestASTCDecodeFeaturesEXT", createDeviceWithUnsupportedFeaturesTestASTCDecodeFeaturesEXT);
	addFunctionCase(testGroup, "conditional_rendering_features_ext", "createDeviceWithUnsupportedFeaturesTestConditionalRenderingFeaturesEXT", createDeviceWithUnsupportedFeaturesTestConditionalRenderingFeaturesEXT);
	addFunctionCase(testGroup, "depth_clip_enable_features_ext", "createDeviceWithUnsupportedFeaturesTestDepthClipEnableFeaturesEXT", createDeviceWithUnsupportedFeaturesTestDepthClipEnableFeaturesEXT);
	addFunctionCase(testGroup, "blend_operation_advanced_features_ext", "createDeviceWithUnsupportedFeaturesTestBlendOperationAdvancedFeaturesEXT", createDeviceWithUnsupportedFeaturesTestBlendOperationAdvancedFeaturesEXT);
	addFunctionCase(testGroup, "shader_sm_builtins_features_nv", "createDeviceWithUnsupportedFeaturesTestShaderSMBuiltinsFeaturesNV", createDeviceWithUnsupportedFeaturesTestShaderSMBuiltinsFeaturesNV);
	addFunctionCase(testGroup, "shading_rate_image_features_nv", "createDeviceWithUnsupportedFeaturesTestShadingRateImageFeaturesNV", createDeviceWithUnsupportedFeaturesTestShadingRateImageFeaturesNV);
	addFunctionCase(testGroup, "representative_fragment_test_features_nv", "createDeviceWithUnsupportedFeaturesTestRepresentativeFragmentTestFeaturesNV", createDeviceWithUnsupportedFeaturesTestRepresentativeFragmentTestFeaturesNV);
	addFunctionCase(testGroup, "vertex_attribute_divisor_features_ext", "createDeviceWithUnsupportedFeaturesTestVertexAttributeDivisorFeaturesEXT", createDeviceWithUnsupportedFeaturesTestVertexAttributeDivisorFeaturesEXT);
	addFunctionCase(testGroup, "compute_shader_derivatives_features_nv", "createDeviceWithUnsupportedFeaturesTestComputeShaderDerivativesFeaturesNV", createDeviceWithUnsupportedFeaturesTestComputeShaderDerivativesFeaturesNV);
	addFunctionCase(testGroup, "mesh_shader_features_nv", "createDeviceWithUnsupportedFeaturesTestMeshShaderFeaturesNV", createDeviceWithUnsupportedFeaturesTestMeshShaderFeaturesNV);
	addFunctionCase(testGroup, "fragment_shader_barycentric_features_nv", "createDeviceWithUnsupportedFeaturesTestFragmentShaderBarycentricFeaturesNV", createDeviceWithUnsupportedFeaturesTestFragmentShaderBarycentricFeaturesNV);
	addFunctionCase(testGroup, "shader_image_footprint_features_nv", "createDeviceWithUnsupportedFeaturesTestShaderImageFootprintFeaturesNV", createDeviceWithUnsupportedFeaturesTestShaderImageFootprintFeaturesNV);
	addFunctionCase(testGroup, "exclusive_scissor_features_nv", "createDeviceWithUnsupportedFeaturesTestExclusiveScissorFeaturesNV", createDeviceWithUnsupportedFeaturesTestExclusiveScissorFeaturesNV);
	addFunctionCase(testGroup, "shader_integer_functions2_features_intel", "createDeviceWithUnsupportedFeaturesTestShaderIntegerFunctions2FeaturesINTEL", createDeviceWithUnsupportedFeaturesTestShaderIntegerFunctions2FeaturesINTEL);
	addFunctionCase(testGroup, "fragment_density_map_features_ext", "createDeviceWithUnsupportedFeaturesTestFragmentDensityMapFeaturesEXT", createDeviceWithUnsupportedFeaturesTestFragmentDensityMapFeaturesEXT);
	addFunctionCase(testGroup, "coherent_memory_features_amd", "createDeviceWithUnsupportedFeaturesTestCoherentMemoryFeaturesAMD", createDeviceWithUnsupportedFeaturesTestCoherentMemoryFeaturesAMD);
	addFunctionCase(testGroup, "shader_image_atomic_int64_features_ext", "createDeviceWithUnsupportedFeaturesTestShaderImageAtomicInt64FeaturesEXT", createDeviceWithUnsupportedFeaturesTestShaderImageAtomicInt64FeaturesEXT);
	addFunctionCase(testGroup, "memory_priority_features_ext", "createDeviceWithUnsupportedFeaturesTestMemoryPriorityFeaturesEXT", createDeviceWithUnsupportedFeaturesTestMemoryPriorityFeaturesEXT);
	addFunctionCase(testGroup, "dedicated_allocation_image_aliasing_features_nv", "createDeviceWithUnsupportedFeaturesTestDedicatedAllocationImageAliasingFeaturesNV", createDeviceWithUnsupportedFeaturesTestDedicatedAllocationImageAliasingFeaturesNV);
	addFunctionCase(testGroup, "buffer_device_address_features_ext", "createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeaturesEXT", createDeviceWithUnsupportedFeaturesTestBufferDeviceAddressFeaturesEXT);
	addFunctionCase(testGroup, "cooperative_matrix_features_nv", "createDeviceWithUnsupportedFeaturesTestCooperativeMatrixFeaturesNV", createDeviceWithUnsupportedFeaturesTestCooperativeMatrixFeaturesNV);
	addFunctionCase(testGroup, "coverage_reduction_mode_features_nv", "createDeviceWithUnsupportedFeaturesTestCoverageReductionModeFeaturesNV", createDeviceWithUnsupportedFeaturesTestCoverageReductionModeFeaturesNV);
	addFunctionCase(testGroup, "fragment_shader_interlock_features_ext", "createDeviceWithUnsupportedFeaturesTestFragmentShaderInterlockFeaturesEXT", createDeviceWithUnsupportedFeaturesTestFragmentShaderInterlockFeaturesEXT);
	addFunctionCase(testGroup, "ycbcr_image_arrays_features_ext", "createDeviceWithUnsupportedFeaturesTestYcbcrImageArraysFeaturesEXT", createDeviceWithUnsupportedFeaturesTestYcbcrImageArraysFeaturesEXT);
	addFunctionCase(testGroup, "provoking_vertex_features_ext", "createDeviceWithUnsupportedFeaturesTestProvokingVertexFeaturesEXT", createDeviceWithUnsupportedFeaturesTestProvokingVertexFeaturesEXT);
	addFunctionCase(testGroup, "line_rasterization_features_ext", "createDeviceWithUnsupportedFeaturesTestLineRasterizationFeaturesEXT", createDeviceWithUnsupportedFeaturesTestLineRasterizationFeaturesEXT);
	addFunctionCase(testGroup, "shader_atomic_float_features_ext", "createDeviceWithUnsupportedFeaturesTestShaderAtomicFloatFeaturesEXT", createDeviceWithUnsupportedFeaturesTestShaderAtomicFloatFeaturesEXT);
	addFunctionCase(testGroup, "index_type_uint8_features_ext", "createDeviceWithUnsupportedFeaturesTestIndexTypeUint8FeaturesEXT", createDeviceWithUnsupportedFeaturesTestIndexTypeUint8FeaturesEXT);
	addFunctionCase(testGroup, "extended_dynamic_state_features_ext", "createDeviceWithUnsupportedFeaturesTestExtendedDynamicStateFeaturesEXT", createDeviceWithUnsupportedFeaturesTestExtendedDynamicStateFeaturesEXT);
	addFunctionCase(testGroup, "shader_atomic_float2_features_ext", "createDeviceWithUnsupportedFeaturesTestShaderAtomicFloat2FeaturesEXT", createDeviceWithUnsupportedFeaturesTestShaderAtomicFloat2FeaturesEXT);
	addFunctionCase(testGroup, "device_generated_commands_features_nv", "createDeviceWithUnsupportedFeaturesTestDeviceGeneratedCommandsFeaturesNV", createDeviceWithUnsupportedFeaturesTestDeviceGeneratedCommandsFeaturesNV);
	addFunctionCase(testGroup, "inherited_viewport_scissor_features_nv", "createDeviceWithUnsupportedFeaturesTestInheritedViewportScissorFeaturesNV", createDeviceWithUnsupportedFeaturesTestInheritedViewportScissorFeaturesNV);
	addFunctionCase(testGroup, "texel_buffer_alignment_features_ext", "createDeviceWithUnsupportedFeaturesTestTexelBufferAlignmentFeaturesEXT", createDeviceWithUnsupportedFeaturesTestTexelBufferAlignmentFeaturesEXT);
	addFunctionCase(testGroup, "device_memory_report_features_ext", "createDeviceWithUnsupportedFeaturesTestDeviceMemoryReportFeaturesEXT", createDeviceWithUnsupportedFeaturesTestDeviceMemoryReportFeaturesEXT);
	addFunctionCase(testGroup, "robustness2_features_ext", "createDeviceWithUnsupportedFeaturesTestRobustness2FeaturesEXT", createDeviceWithUnsupportedFeaturesTestRobustness2FeaturesEXT);
	addFunctionCase(testGroup, "custom_border_color_features_ext", "createDeviceWithUnsupportedFeaturesTestCustomBorderColorFeaturesEXT", createDeviceWithUnsupportedFeaturesTestCustomBorderColorFeaturesEXT);
	addFunctionCase(testGroup, "diagnostics_config_features_nv", "createDeviceWithUnsupportedFeaturesTestDiagnosticsConfigFeaturesNV", createDeviceWithUnsupportedFeaturesTestDiagnosticsConfigFeaturesNV);
	addFunctionCase(testGroup, "fragment_shading_rate_enums_features_nv", "createDeviceWithUnsupportedFeaturesTestFragmentShadingRateEnumsFeaturesNV", createDeviceWithUnsupportedFeaturesTestFragmentShadingRateEnumsFeaturesNV);
	addFunctionCase(testGroup, "ray_tracing_motion_blur_features_nv", "createDeviceWithUnsupportedFeaturesTestRayTracingMotionBlurFeaturesNV", createDeviceWithUnsupportedFeaturesTestRayTracingMotionBlurFeaturesNV);
	addFunctionCase(testGroup, "ycbcr2_plane444_formats_features_ext", "createDeviceWithUnsupportedFeaturesTestYcbcr2Plane444FormatsFeaturesEXT", createDeviceWithUnsupportedFeaturesTestYcbcr2Plane444FormatsFeaturesEXT);
	addFunctionCase(testGroup, "fragment_density_map2_features_ext", "createDeviceWithUnsupportedFeaturesTestFragmentDensityMap2FeaturesEXT", createDeviceWithUnsupportedFeaturesTestFragmentDensityMap2FeaturesEXT);
	addFunctionCase(testGroup, "4444_formats_features_ext", "createDeviceWithUnsupportedFeaturesTest4444FormatsFeaturesEXT", createDeviceWithUnsupportedFeaturesTest4444FormatsFeaturesEXT);
	addFunctionCase(testGroup, "rasterization_order_attachment_access_features_arm", "createDeviceWithUnsupportedFeaturesTestRasterizationOrderAttachmentAccessFeaturesARM", createDeviceWithUnsupportedFeaturesTestRasterizationOrderAttachmentAccessFeaturesARM);
	addFunctionCase(testGroup, "rgba10_x6_formats_features_ext", "createDeviceWithUnsupportedFeaturesTestRGBA10X6FormatsFeaturesEXT", createDeviceWithUnsupportedFeaturesTestRGBA10X6FormatsFeaturesEXT);
	addFunctionCase(testGroup, "mutable_descriptor_type_features_valve", "createDeviceWithUnsupportedFeaturesTestMutableDescriptorTypeFeaturesVALVE", createDeviceWithUnsupportedFeaturesTestMutableDescriptorTypeFeaturesVALVE);
	addFunctionCase(testGroup, "vertex_input_dynamic_state_features_ext", "createDeviceWithUnsupportedFeaturesTestVertexInputDynamicStateFeaturesEXT", createDeviceWithUnsupportedFeaturesTestVertexInputDynamicStateFeaturesEXT);
	addFunctionCase(testGroup, "depth_clip_control_features_ext", "createDeviceWithUnsupportedFeaturesTestDepthClipControlFeaturesEXT", createDeviceWithUnsupportedFeaturesTestDepthClipControlFeaturesEXT);
	addFunctionCase(testGroup, "primitive_topology_list_restart_features_ext", "createDeviceWithUnsupportedFeaturesTestPrimitiveTopologyListRestartFeaturesEXT", createDeviceWithUnsupportedFeaturesTestPrimitiveTopologyListRestartFeaturesEXT);
	addFunctionCase(testGroup, "subpass_shading_features_huawei", "createDeviceWithUnsupportedFeaturesTestSubpassShadingFeaturesHUAWEI", createDeviceWithUnsupportedFeaturesTestSubpassShadingFeaturesHUAWEI);
	addFunctionCase(testGroup, "invocation_mask_features_huawei", "createDeviceWithUnsupportedFeaturesTestInvocationMaskFeaturesHUAWEI", createDeviceWithUnsupportedFeaturesTestInvocationMaskFeaturesHUAWEI);
	addFunctionCase(testGroup, "external_memory_rdma_features_nv", "createDeviceWithUnsupportedFeaturesTestExternalMemoryRDMAFeaturesNV", createDeviceWithUnsupportedFeaturesTestExternalMemoryRDMAFeaturesNV);
	addFunctionCase(testGroup, "extended_dynamic_state2_features_ext", "createDeviceWithUnsupportedFeaturesTestExtendedDynamicState2FeaturesEXT", createDeviceWithUnsupportedFeaturesTestExtendedDynamicState2FeaturesEXT);
	addFunctionCase(testGroup, "color_write_enable_features_ext", "createDeviceWithUnsupportedFeaturesTestColorWriteEnableFeaturesEXT", createDeviceWithUnsupportedFeaturesTestColorWriteEnableFeaturesEXT);
	addFunctionCase(testGroup, "image_view_min_lod_features_ext", "createDeviceWithUnsupportedFeaturesTestImageViewMinLodFeaturesEXT", createDeviceWithUnsupportedFeaturesTestImageViewMinLodFeaturesEXT);
	addFunctionCase(testGroup, "multi_draw_features_ext", "createDeviceWithUnsupportedFeaturesTestMultiDrawFeaturesEXT", createDeviceWithUnsupportedFeaturesTestMultiDrawFeaturesEXT);
	addFunctionCase(testGroup, "border_color_swizzle_features_ext", "createDeviceWithUnsupportedFeaturesTestBorderColorSwizzleFeaturesEXT", createDeviceWithUnsupportedFeaturesTestBorderColorSwizzleFeaturesEXT);
	addFunctionCase(testGroup, "pageable_device_local_memory_features_ext", "createDeviceWithUnsupportedFeaturesTestPageableDeviceLocalMemoryFeaturesEXT", createDeviceWithUnsupportedFeaturesTestPageableDeviceLocalMemoryFeaturesEXT);
	addFunctionCase(testGroup, "fragment_density_map_offset_features_qcom", "createDeviceWithUnsupportedFeaturesTestFragmentDensityMapOffsetFeaturesQCOM", createDeviceWithUnsupportedFeaturesTestFragmentDensityMapOffsetFeaturesQCOM);
	addFunctionCase(testGroup, "linear_color_attachment_features_nv", "createDeviceWithUnsupportedFeaturesTestLinearColorAttachmentFeaturesNV", createDeviceWithUnsupportedFeaturesTestLinearColorAttachmentFeaturesNV);
	addFunctionCase(testGroup, "acceleration_structure_features_khr", "createDeviceWithUnsupportedFeaturesTestAccelerationStructureFeaturesKHR", createDeviceWithUnsupportedFeaturesTestAccelerationStructureFeaturesKHR);
	addFunctionCase(testGroup, "ray_tracing_pipeline_features_khr", "createDeviceWithUnsupportedFeaturesTestRayTracingPipelineFeaturesKHR", createDeviceWithUnsupportedFeaturesTestRayTracingPipelineFeaturesKHR);
	addFunctionCase(testGroup, "ray_query_features_khr", "createDeviceWithUnsupportedFeaturesTestRayQueryFeaturesKHR", createDeviceWithUnsupportedFeaturesTestRayQueryFeaturesKHR);
	addFunctionCase(testGroup, "portability_subset_features_khr", "createDeviceWithUnsupportedFeaturesTestPortabilitySubsetFeaturesKHR", createDeviceWithUnsupportedFeaturesTestPortabilitySubsetFeaturesKHR);
}

