Home | History | Annotate | Download | only in vulkan
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Vulkan test case base classes
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktTestCase.hpp"
     25 
     26 #include "vkRef.hpp"
     27 #include "vkRefUtil.hpp"
     28 #include "vkQueryUtil.hpp"
     29 #include "vkDeviceUtil.hpp"
     30 #include "vkMemUtil.hpp"
     31 #include "vkPlatform.hpp"
     32 #include "vkDebugReportUtil.hpp"
     33 
     34 #include "tcuCommandLine.hpp"
     35 #include "tcuTestLog.hpp"
     36 
     37 #include "deSTLUtil.hpp"
     38 #include "deMemory.h"
     39 
     40 #if defined(DEQP_HAVE_VKRUNNER)
     41 #include <vkrunner/vkrunner.h>
     42 #endif
     43 
     44 #include <set>
     45 
     46 struct vk_executor;
     47 
     48 namespace vkt
     49 {
     50 
     51 // Default device utilities
     52 
     53 using std::vector;
     54 using std::string;
     55 using std::set;
     56 using namespace vk;
     57 
     58 namespace
     59 {
     60 
     61 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
     62 {
     63 	static const char*	s_magicLayer		= "VK_LAYER_LUNARG_standard_validation";
     64 	static const char*	s_defaultLayers[]	=
     65 	{
     66 		"VK_LAYER_GOOGLE_threading",
     67 		"VK_LAYER_LUNARG_parameter_validation",
     68 		"VK_LAYER_LUNARG_device_limits",
     69 		"VK_LAYER_LUNARG_object_tracker",
     70 		"VK_LAYER_LUNARG_image",
     71 		"VK_LAYER_LUNARG_core_validation",
     72 		"VK_LAYER_LUNARG_swapchain",
     73 		"VK_LAYER_GOOGLE_unique_objects"
     74 	};
     75 
     76 	vector<string>		enabledLayers;
     77 
     78 	if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
     79 		enabledLayers.push_back(s_magicLayer);
     80 	else
     81 	{
     82 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
     83 		{
     84 			if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
     85 				enabledLayers.push_back(s_defaultLayers[ndx]);
     86 		}
     87 	}
     88 
     89 	return enabledLayers;
     90 }
     91 
     92 vector<string> getValidationLayers (const PlatformInterface& vkp)
     93 {
     94 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
     95 }
     96 
     97 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
     98 {
     99 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
    100 }
    101 
    102 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
    103 {
    104 	vector<string>	enabledExtensions;
    105 	const char*		extensionGroups[] =
    106 	{
    107 		"VK_KHR_",
    108 		"VK_EXT_",
    109 		"VK_KHX_"
    110 	};
    111 
    112 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
    113 	{
    114 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
    115 		{
    116 			if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
    117 				enabledExtensions.push_back(extensions[extNdx].extensionName);
    118 		}
    119 	}
    120 
    121 	return enabledExtensions;
    122 }
    123 
    124 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
    125 {
    126 	vector<string>	res		(a);
    127 
    128 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
    129 	{
    130 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
    131 			res.push_back(string(*bIter));
    132 	}
    133 
    134 	return res;
    135 }
    136 
    137 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
    138 {
    139 	vector<string>	res;
    140 	set<string>		removeExts	(b.begin(), b.end());
    141 
    142 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
    143 	{
    144 		if (!de::contains(removeExts, *aIter))
    145 			res.push_back(*aIter);
    146 	}
    147 
    148 	return res;
    149 }
    150 
    151 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
    152 {
    153 	vector<const char*> coreExtensions;
    154 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
    155 	return addExtensions(extensions, coreExtensions);
    156 }
    157 
    158 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
    159 {
    160 	vector<const char*> coreExtensions;
    161 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
    162 	return addExtensions(extensions, coreExtensions);
    163 }
    164 
    165 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
    166 {
    167 	deUint32 version = pack(ApiVersion(1, 0, 0));
    168 
    169 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
    170 		TCU_THROW(InternalError, "Enumerate instance version error");
    171 	return version;
    172 }
    173 
    174 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
    175 {
    176 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion);
    177 	InstanceDriver							preinterface			(vkp, preinstance.get());
    178 
    179 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
    180 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
    181 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
    182 	{
    183 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
    184 		if (props.apiVersion < lowestDeviceVersion)
    185 			lowestDeviceVersion = props.apiVersion;
    186 	}
    187 
    188 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
    189 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
    190 	const deUint32							choosenDeviceVersion	= props.apiVersion;
    191 
    192 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
    193 }
    194 
    195 
    196 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
    197 {
    198 	const bool								isValidationEnabled	= cmdLine.isValidationEnabled();
    199 	vector<string>							enabledLayers;
    200 
    201 	// \note Extensions in core are not explicitly enabled even though
    202 	//		 they are in the extension list advertised to tests.
    203 	vector<const char*>						coreExtensions;
    204 	getCoreInstanceExtensions(apiVersion, coreExtensions);
    205 	vector<string>							nonCoreExtensions	(removeExtensions(enabledExtensions, coreExtensions));
    206 
    207 	if (isValidationEnabled)
    208 	{
    209 		if (!isDebugReportSupported(vkp))
    210 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
    211 
    212 		enabledLayers = getValidationLayers(vkp);
    213 		if (enabledLayers.empty())
    214 			TCU_THROW(NotSupportedError, "No validation layers found");
    215 	}
    216 
    217 	return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions);
    218 }
    219 
    220 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
    221 {
    222 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
    223 
    224 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
    225 	{
    226 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
    227 			return (deUint32)queueNdx;
    228 	}
    229 
    230 	TCU_THROW(NotSupportedError, "No matching queue found");
    231 }
    232 
    233 Move<VkDevice> createDefaultDevice (const PlatformInterface&			vkp,
    234 									VkInstance							instance,
    235 									const InstanceInterface&			vki,
    236 									VkPhysicalDevice					physicalDevice,
    237 									const deUint32						apiVersion,
    238 									deUint32							queueIndex,
    239 									deUint32							sparseQueueIndex,
    240 									const VkPhysicalDeviceFeatures2&	enabledFeatures,
    241 									const vector<string>&				enabledExtensions,
    242 									const tcu::CommandLine&				cmdLine)
    243 {
    244 	VkDeviceQueueCreateInfo		queueInfo[2];
    245 	VkDeviceCreateInfo			deviceInfo;
    246 	vector<string>				enabledLayers;
    247 	vector<const char*>			layerPtrs;
    248 	vector<const char*>			extensionPtrs;
    249 	const float					queuePriority	= 1.0f;
    250 	const deUint32				numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
    251 
    252 	deMemset(&queueInfo,	0, sizeof(queueInfo));
    253 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
    254 
    255 	if (cmdLine.isValidationEnabled())
    256 	{
    257 		enabledLayers = getValidationLayers(vki, physicalDevice);
    258 		if (enabledLayers.empty())
    259 			TCU_THROW(NotSupportedError, "No validation layers found");
    260 	}
    261 
    262 	layerPtrs.resize(enabledLayers.size());
    263 
    264 	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
    265 		layerPtrs[ndx] = enabledLayers[ndx].c_str();
    266 
    267 	// \note Extensions in core are not explicitly enabled even though
    268 	//		 they are in the extension list advertised to tests.
    269 	vector<const char*> coreExtensions;
    270 	getCoreDeviceExtensions(apiVersion, coreExtensions);
    271 	vector<string>	nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
    272 
    273 	extensionPtrs.resize(nonCoreExtensions.size());
    274 
    275 	for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
    276 		extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
    277 
    278 	queueInfo[0].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    279 	queueInfo[0].pNext						= DE_NULL;
    280 	queueInfo[0].flags						= (VkDeviceQueueCreateFlags)0u;
    281 	queueInfo[0].queueFamilyIndex			= queueIndex;
    282 	queueInfo[0].queueCount					= 1u;
    283 	queueInfo[0].pQueuePriorities			= &queuePriority;
    284 
    285 	if (numQueues > 1)
    286 	{
    287 		queueInfo[1].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    288 		queueInfo[1].pNext						= DE_NULL;
    289 		queueInfo[1].flags						= (VkDeviceQueueCreateFlags)0u;
    290 		queueInfo[1].queueFamilyIndex			= sparseQueueIndex;
    291 		queueInfo[1].queueCount					= 1u;
    292 		queueInfo[1].pQueuePriorities			= &queuePriority;
    293 	}
    294 
    295 	// VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
    296 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    297 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
    298 	deviceInfo.queueCreateInfoCount			= numQueues;
    299 	deviceInfo.pQueueCreateInfos			= queueInfo;
    300 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
    301 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
    302 	deviceInfo.enabledLayerCount			= (deUint32)layerPtrs.size();
    303 	deviceInfo.ppEnabledLayerNames			= (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
    304 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
    305 
    306 	return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
    307 };
    308 
    309 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions)
    310 {
    311 	return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2");
    312 }
    313 
    314 class DeviceFeatures
    315 {
    316 public:
    317 	VkPhysicalDeviceFeatures2							coreFeatures;
    318 	VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYCbCrConversionFeatures;
    319 	VkPhysicalDevice8BitStorageFeaturesKHR				eightBitStorageFeatures;
    320 	VkPhysicalDevice16BitStorageFeatures				sixteenBitStorageFeatures;
    321 	VkPhysicalDeviceVariablePointerFeatures				variablePointerFeatures;
    322 	VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT	vertexAttributeDivisorFeatures;
    323 	VkPhysicalDeviceDescriptorIndexingFeaturesEXT		descriptorIndexingFeatures;
    324 	VkPhysicalDeviceInlineUniformBlockFeaturesEXT		inlineUniformBlockFeatures;
    325 	VkPhysicalDeviceVulkanMemoryModelFeaturesKHR		vulkanMemoryModelFeatures;
    326 	VkPhysicalDeviceShaderAtomicInt64FeaturesKHR		shaderAtomicInt64Features;
    327 	VkPhysicalDeviceConditionalRenderingFeaturesEXT		conditionalRenderingFeatures;
    328 	VkPhysicalDeviceScalarBlockLayoutFeaturesEXT		scalarBlockLayoutFeatures;
    329 	VkPhysicalDeviceFloat16Int8FeaturesKHR				float16Int8Features;
    330 
    331 	DeviceFeatures (const InstanceInterface&	vki,
    332 					const deUint32				apiVersion,
    333 					const VkPhysicalDevice&		physicalDevice,
    334 					const vector<string>&		instanceExtensions,
    335 					const vector<string>&		deviceExtensions)
    336 	{
    337 		deMemset(&coreFeatures, 0, sizeof(coreFeatures));
    338 		deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
    339 		deMemset(&eightBitStorageFeatures, 0, sizeof(eightBitStorageFeatures));
    340 		deMemset(&sixteenBitStorageFeatures, 0, sizeof(sixteenBitStorageFeatures));
    341 		deMemset(&variablePointerFeatures, 0, sizeof(variablePointerFeatures));
    342 		deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures));
    343 		deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures));
    344 		deMemset(&float16Int8Features, 0, sizeof(float16Int8Features));
    345 		deMemset(&vertexAttributeDivisorFeatures, 0, sizeof(vertexAttributeDivisorFeatures));
    346 		deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures));
    347 		deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures));
    348 		deMemset(&vulkanMemoryModelFeatures, 0, sizeof(vulkanMemoryModelFeatures));
    349 		deMemset(&shaderAtomicInt64Features, 0, sizeof(shaderAtomicInt64Features));
    350 		deMemset(&conditionalRenderingFeatures, 0, sizeof(conditionalRenderingFeatures));
    351 		deMemset(&scalarBlockLayoutFeatures, 0, sizeof(scalarBlockLayoutFeatures));
    352 
    353 		coreFeatures.sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    354 		samplerYCbCrConversionFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
    355 		eightBitStorageFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
    356 		sixteenBitStorageFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
    357 		variablePointerFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
    358 		descriptorIndexingFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
    359 		inlineUniformBlockFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
    360 		float16Int8Features.sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
    361 		vertexAttributeDivisorFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
    362 		descriptorIndexingFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
    363 		inlineUniformBlockFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
    364 		vulkanMemoryModelFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
    365 		shaderAtomicInt64Features.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
    366 		conditionalRenderingFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
    367 		scalarBlockLayoutFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
    368 
    369 		vector<VkExtensionProperties> deviceExtensionProperties =
    370 			enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
    371 
    372 		if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions))
    373 		{
    374 			void** nextPtr = &coreFeatures.pNext;
    375 
    376 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
    377 			{
    378 				*nextPtr	= &samplerYCbCrConversionFeatures;
    379 				nextPtr		= &samplerYCbCrConversionFeatures.pNext;
    380 			}
    381 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_8bit_storage"))
    382 			{
    383 				*nextPtr	= &eightBitStorageFeatures;
    384 				nextPtr		= &eightBitStorageFeatures.pNext;
    385 			}
    386 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_16bit_storage"))
    387 			{
    388 				*nextPtr	= &sixteenBitStorageFeatures;
    389 				nextPtr		= &sixteenBitStorageFeatures.pNext;
    390 			}
    391 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_variable_pointers"))
    392 			{
    393 				*nextPtr	= &variablePointerFeatures;
    394 				nextPtr		= &variablePointerFeatures.pNext;
    395 			}
    396 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_descriptor_indexing"))
    397 			{
    398 				*nextPtr	= &descriptorIndexingFeatures;
    399 				nextPtr		= &descriptorIndexingFeatures.pNext;
    400 			}
    401 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_inline_uniform_block"))
    402 			{
    403 				*nextPtr	= &inlineUniformBlockFeatures;
    404 				nextPtr		= &inlineUniformBlockFeatures.pNext;
    405 			}
    406 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_float16_int8"))
    407 			{
    408 				*nextPtr	= &float16Int8Features;
    409 				nextPtr		= &float16Int8Features.pNext;
    410 			}
    411 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_vertex_attribute_divisor"))
    412 			{
    413 				*nextPtr	= &vertexAttributeDivisorFeatures;
    414 				nextPtr		= &vertexAttributeDivisorFeatures.pNext;
    415 			}
    416 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_vulkan_memory_model"))
    417 			{
    418 				for (size_t i = 0; i < deviceExtensionProperties.size(); ++i)
    419 				{
    420 					if (deStringEqual(deviceExtensionProperties[i].extensionName, "VK_KHR_vulkan_memory_model"))
    421 					{
    422 						if (deviceExtensionProperties[i].specVersion == VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION)
    423 						{
    424 							*nextPtr	= &vulkanMemoryModelFeatures;
    425 							nextPtr		= &vulkanMemoryModelFeatures.pNext;
    426 						}
    427 						break;
    428 					}
    429 				}
    430 			}
    431 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_atomic_int64"))
    432 			{
    433 				*nextPtr	= &shaderAtomicInt64Features;
    434 				nextPtr		= &shaderAtomicInt64Features.pNext;
    435 			}
    436 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_conditional_rendering"))
    437 			{
    438 				*nextPtr	= &conditionalRenderingFeatures;
    439 				nextPtr		= &conditionalRenderingFeatures.pNext;
    440 			}
    441 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_scalar_block_layout"))
    442 			{
    443 				*nextPtr	= &scalarBlockLayoutFeatures;
    444 				nextPtr		= &scalarBlockLayoutFeatures.pNext;
    445 			}
    446 
    447 			vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
    448 		}
    449 		else
    450 			coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
    451 
    452 		// Disable robustness by default, as it has an impact on performance on some HW.
    453 		coreFeatures.features.robustBufferAccess = false;
    454 	}
    455 };
    456 
    457 } // anonymous
    458 
    459 class DefaultDevice
    460 {
    461 public:
    462 															DefaultDevice						(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
    463 															~DefaultDevice						(void);
    464 
    465 	VkInstance												getInstance							(void) const	{ return *m_instance;										}
    466 	const InstanceInterface&								getInstanceInterface				(void) const	{ return m_instanceInterface;								}
    467 	deUint32												getAvailableInstanceVersion			(void) const	{ return m_availableInstanceVersion;						}
    468 	const vector<string>&									getInstanceExtensions				(void) const	{ return m_instanceExtensions;								}
    469 
    470 	VkPhysicalDevice										getPhysicalDevice					(void) const	{ return m_physicalDevice;									}
    471 	deUint32												getDeviceVersion					(void) const	{ return m_deviceVersion;									}
    472 	const VkPhysicalDeviceFeatures&							getDeviceFeatures					(void) const	{ return m_deviceFeatures.coreFeatures.features;			}
    473 	const VkPhysicalDeviceFeatures2&						getDeviceFeatures2					(void) const	{ return m_deviceFeatures.coreFeatures; }
    474 	const VkPhysicalDeviceSamplerYcbcrConversionFeatures&	getSamplerYCbCrConversionFeatures	(void) const	{ return m_deviceFeatures.samplerYCbCrConversionFeatures;	}
    475 	const VkPhysicalDevice8BitStorageFeaturesKHR&			get8BitStorageFeatures				(void) const	{ return m_deviceFeatures.eightBitStorageFeatures;			}
    476 	const VkPhysicalDevice16BitStorageFeatures&				get16BitStorageFeatures				(void) const	{ return m_deviceFeatures.sixteenBitStorageFeatures;		}
    477 	const VkPhysicalDeviceVariablePointerFeatures&			getVariablePointerFeatures			(void) const	{ return m_deviceFeatures.variablePointerFeatures;			}
    478 	const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&getVertexAttributeDivisorFeatures	(void) const	{ return m_deviceFeatures.vertexAttributeDivisorFeatures;	}
    479 	const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR&		getVulkanMemoryModelFeatures		(void) const	{ return m_deviceFeatures.vulkanMemoryModelFeatures;	}
    480 	const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR&		getShaderAtomicInt64Features		(void) const	{ return m_deviceFeatures.shaderAtomicInt64Features;	}
    481 	const VkPhysicalDeviceConditionalRenderingFeaturesEXT&	getConditionalRenderingFeatures		(void) const	{ return m_deviceFeatures.conditionalRenderingFeatures;	}
    482 	const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT&		getScalarBlockLayoutFeatures		(void) const	{ return m_deviceFeatures.scalarBlockLayoutFeatures;	}
    483 	const VkPhysicalDeviceFloat16Int8FeaturesKHR&			getFloat16Int8Features				(void) const	{ return m_deviceFeatures.float16Int8Features;				}
    484 	VkDevice												getDevice							(void) const	{ return *m_device;											}
    485 	const DeviceInterface&									getDeviceInterface					(void) const	{ return m_deviceInterface;									}
    486 	const VkPhysicalDeviceProperties&						getDeviceProperties					(void) const	{ return m_deviceProperties;								}
    487 	const vector<string>&									getDeviceExtensions					(void) const	{ return m_deviceExtensions;								}
    488 
    489 	deUint32												getUsedApiVersion					(void) const	{ return m_usedApiVersion;									}
    490 
    491 	deUint32												getUniversalQueueFamilyIndex		(void) const	{ return m_universalQueueFamilyIndex;						}
    492 	VkQueue													getUniversalQueue					(void) const;
    493 	deUint32												getSparseQueueFamilyIndex		(void) const	{ return m_sparseQueueFamilyIndex;					}
    494 	VkQueue													getSparseQueue					(void) const;
    495 
    496 private:
    497 
    498 	const deUint32						m_availableInstanceVersion;
    499 
    500 	const std::pair<deUint32, deUint32> m_deviceVersions;
    501 	const deUint32						m_usedApiVersion;
    502 
    503 	const vector<string>				m_instanceExtensions;
    504 	const Unique<VkInstance>			m_instance;
    505 	const InstanceDriver				m_instanceInterface;
    506 
    507 	const VkPhysicalDevice				m_physicalDevice;
    508 	const deUint32						m_deviceVersion;
    509 
    510 	const vector<string>				m_deviceExtensions;
    511 	const DeviceFeatures				m_deviceFeatures;
    512 
    513 	const deUint32						m_universalQueueFamilyIndex;
    514 	const deUint32						m_sparseQueueFamilyIndex;
    515 	const VkPhysicalDeviceProperties	m_deviceProperties;
    516 
    517 	const Unique<VkDevice>				m_device;
    518 	const DeviceDriver					m_deviceInterface;
    519 
    520 };
    521 
    522 static deUint32 sanitizeApiVersion(deUint32 v)
    523 {
    524 	return VK_MAKE_VERSION( VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), 0 );
    525 }
    526 
    527 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
    528 	: m_availableInstanceVersion	(getTargetInstanceVersion(vkPlatform))
    529 	, m_deviceVersions				(determineDeviceVersions(vkPlatform, m_availableInstanceVersion, cmdLine))
    530 	, m_usedApiVersion				(sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_deviceVersions.first)))
    531 
    532 	, m_instanceExtensions			(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
    533 	, m_instance					(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
    534 
    535 	, m_instanceInterface			(vkPlatform, *m_instance)
    536 	, m_physicalDevice				(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
    537 	, m_deviceVersion				(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
    538 
    539 	, m_deviceExtensions			(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
    540 	, m_deviceFeatures				(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
    541 	, m_universalQueueFamilyIndex	(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
    542 	, m_sparseQueueFamilyIndex		(m_deviceFeatures.coreFeatures.features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
    543 	, m_deviceProperties			(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
    544 	, m_device						(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine))
    545 	, m_deviceInterface				(vkPlatform, *m_instance, *m_device)
    546 {
    547 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
    548 }
    549 
    550 DefaultDevice::~DefaultDevice (void)
    551 {
    552 }
    553 
    554 VkQueue DefaultDevice::getUniversalQueue (void) const
    555 {
    556 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
    557 }
    558 
    559 VkQueue DefaultDevice::getSparseQueue (void) const
    560 {
    561 	if (!m_deviceFeatures.coreFeatures.features.sparseBinding)
    562 		TCU_THROW(NotSupportedError, "Sparse binding not supported.");
    563 
    564 	return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
    565 }
    566 
    567 namespace
    568 {
    569 // Allocator utilities
    570 
    571 vk::Allocator* createAllocator (DefaultDevice* device)
    572 {
    573 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
    574 
    575 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
    576 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
    577 }
    578 
    579 } // anonymous
    580 
    581 // Context
    582 
    583 void Context::errorCb(const char* message,
    584 					  void* user_data)
    585 {
    586 	Context* context = (Context*) user_data;
    587 
    588 	context->getTestContext().getLog()
    589 		<< tcu::TestLog::Message
    590 		<< message
    591 		<< "\n"
    592 		<< tcu::TestLog::EndMessage;
    593 }
    594 
    595 Context::Context (tcu::TestContext&				testCtx,
    596 				  const vk::PlatformInterface&	platformInterface,
    597 				  vk::BinaryCollection&			progCollection)
    598 	: m_testCtx				(testCtx)
    599 	, m_platformInterface	(platformInterface)
    600 	, m_progCollection		(progCollection)
    601 	, m_device				(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
    602 	, m_allocator			(createAllocator(m_device.get()))
    603 {
    604 #if defined(DEQP_HAVE_VKRUNNER)
    605 	m_config = vr_config_new();
    606 	vr_config_set_user_data(m_config, this);
    607 	vr_config_set_error_cb(m_config, errorCb);
    608 	m_executor = vr_executor_new(m_config);
    609 	vr_executor_set_device(m_executor,
    610 						   getInstanceProc,
    611 						   this,
    612 						   getPhysicalDevice(),
    613 						   getUniversalQueueFamilyIndex(),
    614 						   getDevice());
    615 #endif
    616 }
    617 
    618 Context::~Context (void)
    619 {
    620 #if defined(DEQP_HAVE_VKRUNNER)
    621 	vr_config_free(m_config);
    622 	vr_executor_free(m_executor);
    623 #endif
    624 }
    625 
    626 deUint32								Context::getAvailableInstanceVersion	(void) const { return m_device->getAvailableInstanceVersion();	}
    627 const vector<string>&					Context::getInstanceExtensions			(void) const { return m_device->getInstanceExtensions();		}
    628 vk::VkInstance							Context::getInstance					(void) const { return m_device->getInstance();					}
    629 const vk::InstanceInterface&			Context::getInstanceInterface			(void) const { return m_device->getInstanceInterface();			}
    630 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
    631 deUint32								Context::getDeviceVersion				(void) const { return m_device->getDeviceVersion();				}
    632 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
    633 const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2				(void) const { return m_device->getDeviceFeatures2();			}
    634 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&
    635 										Context::getSamplerYCbCrConversionFeatures
    636 																				(void) const { return m_device->getSamplerYCbCrConversionFeatures();	}
    637 const vk::VkPhysicalDevice8BitStorageFeaturesKHR&
    638 										Context::get8BitStorageFeatures			(void) const { return m_device->get8BitStorageFeatures();		}
    639 const vk::VkPhysicalDevice16BitStorageFeatures&
    640 										Context::get16BitStorageFeatures		(void) const { return m_device->get16BitStorageFeatures();		}
    641 const vk::VkPhysicalDeviceVariablePointerFeatures&
    642 										Context::getVariablePointerFeatures		(void) const { return m_device->getVariablePointerFeatures();	}
    643 const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&
    644 										Context::getVertexAttributeDivisorFeatures	(void) const { return m_device->getVertexAttributeDivisorFeatures();	}
    645 const vk::VkPhysicalDeviceVulkanMemoryModelFeaturesKHR&
    646 										Context::getVulkanMemoryModelFeatures	(void) const { return m_device->getVulkanMemoryModelFeatures();	}
    647 const vk::VkPhysicalDeviceShaderAtomicInt64FeaturesKHR&
    648 										Context::getShaderAtomicInt64Features	(void) const { return m_device->getShaderAtomicInt64Features();	}
    649 const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT&
    650 										Context::getConditionalRenderingFeatures(void) const { return m_device->getConditionalRenderingFeatures();	}
    651 const vk::VkPhysicalDeviceScalarBlockLayoutFeaturesEXT&
    652 										Context::getScalarBlockLayoutFeatures	(void) const { return m_device->getScalarBlockLayoutFeatures();	}
    653 const vk::VkPhysicalDeviceFloat16Int8FeaturesKHR&
    654 										Context::getFloat16Int8Features			(void) const { return m_device->getFloat16Int8Features();		}
    655 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
    656 const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
    657 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
    658 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
    659 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
    660 vk::VkQueue								Context::getUniversalQueue				(void) const { return m_device->getUniversalQueue();			}
    661 deUint32								Context::getSparseQueueFamilyIndex		(void) const { return m_device->getSparseQueueFamilyIndex();	}
    662 vk::VkQueue								Context::getSparseQueue					(void) const { return m_device->getSparseQueue();				}
    663 vk::Allocator&							Context::getDefaultAllocator			(void) const { return *m_allocator;								}
    664 deUint32								Context::getUsedApiVersion				(void) const { return m_device->getUsedApiVersion();			}
    665 vr_executor*							Context::getExecutor					(void) const
    666 																							{ return m_executor; }
    667 bool									Context::contextSupports				(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
    668 																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
    669 bool									Context::contextSupports				(const ApiVersion version) const
    670 																							{ return m_device->getUsedApiVersion() >= pack(version); }
    671 bool									Context::contextSupports				(const deUint32 requiredApiVersionBits) const
    672 																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
    673 
    674 bool Context::requireDeviceExtension (const std::string& required)
    675 {
    676 	if (!isDeviceExtensionSupported(getUsedApiVersion(), getDeviceExtensions(), required))
    677 		TCU_THROW(NotSupportedError, required + " is not supported");
    678 
    679 	return true;
    680 }
    681 
    682 bool Context::requireInstanceExtension (const std::string& required)
    683 {
    684 	if (!isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), required))
    685 		TCU_THROW(NotSupportedError, required + " is not supported");
    686 
    687 	return true;
    688 }
    689 
    690 struct DeviceCoreFeaturesTable
    691 {
    692 	const char*		featureName;
    693 	const deUint32	featureArrayIndex;
    694 	const deUint32	featureArrayOffset;
    695 };
    696 
    697 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
    698 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)	{ #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
    699 
    700 const DeviceCoreFeaturesTable	deviceCoreFeaturesTable[] =
    701 {
    702 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS							,	robustBufferAccess						),
    703 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32						,	fullDrawIndexUint32						),
    704 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY								,	imageCubeArray							),
    705 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND								,	independentBlend						),
    706 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER								,	geometryShader							),
    707 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER							,	tessellationShader						),
    708 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING							,	sampleRateShading						),
    709 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND								,	dualSrcBlend							),
    710 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP										,	logicOp									),
    711 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT							,	multiDrawIndirect						),
    712 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE					,	drawIndirectFirstInstance				),
    713 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP									,	depthClamp								),
    714 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP								,	depthBiasClamp							),
    715 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID							,	fillModeNonSolid						),
    716 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS									,	depthBounds								),
    717 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES									,	wideLines								),
    718 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS									,	largePoints								),
    719 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE									,	alphaToOne								),
    720 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT								,	multiViewport							),
    721 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY							,	samplerAnisotropy						),
    722 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2						,	textureCompressionETC2					),
    723 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR					,	textureCompressionASTC_LDR				),
    724 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC						,	textureCompressionBC					),
    725 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE						,	occlusionQueryPrecise					),
    726 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY						,	pipelineStatisticsQuery					),
    727 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			,	vertexPipelineStoresAndAtomics			),
    728 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS					,	fragmentStoresAndAtomics				),
    729 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	,	shaderTessellationAndGeometryPointSize	),
    730 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED					,	shaderImageGatherExtended				),
    731 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS			,	shaderStorageImageExtendedFormats		),
    732 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE				,	shaderStorageImageMultisample			),
    733 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT		,	shaderStorageImageReadWithoutFormat		),
    734 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT		,	shaderStorageImageWriteWithoutFormat	),
    735 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderUniformBufferArrayDynamicIndexing	),
    736 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderSampledImageArrayDynamicIndexing	),
    737 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderStorageBufferArrayDynamicIndexing	),
    738 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderStorageImageArrayDynamicIndexing	),
    739 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE							,	shaderClipDistance						),
    740 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE							,	shaderCullDistance						),
    741 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64								,	shaderFloat64							),
    742 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64									,	shaderInt64								),
    743 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16									,	shaderInt16								),
    744 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY						,	shaderResourceResidency					),
    745 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD						,	shaderResourceMinLod					),
    746 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING								,	sparseBinding							),
    747 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER						,	sparseResidencyBuffer					),
    748 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D						,	sparseResidencyImage2D					),
    749 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D						,	sparseResidencyImage3D					),
    750 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES						,	sparseResidency2Samples					),
    751 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES						,	sparseResidency4Samples					),
    752 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES						,	sparseResidency8Samples					),
    753 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES					,	sparseResidency16Samples				),
    754 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED						,	sparseResidencyAliased					),
    755 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE						,	variableMultisampleRate					),
    756 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES								,	inheritedQueries						),
    757 };
    758 
    759 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
    760 {
    761 	const vk::VkPhysicalDeviceFeatures& featuresAvailable		= getDeviceFeatures();
    762 	const vk::VkBool32*					featuresAvailableArray	= (vk::VkBool32*)(&featuresAvailable);
    763 	const deUint32						requiredFeatureIndex	= static_cast<deUint32>(requiredFeature);
    764 
    765 	DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
    766 	DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
    767 
    768 	if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
    769 		TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
    770 
    771 	return true;
    772 }
    773 
    774 void* Context::getInstanceProc (const char* name, void* user_data)
    775 {
    776 	Context *context = (Context*) user_data;
    777 	return (void*) context->m_platformInterface.getInstanceProcAddr(context->getInstance(), name);
    778 }
    779 
    780 // TestCase
    781 
    782 void TestCase::initPrograms (SourceCollections&) const
    783 {
    784 }
    785 
    786 void TestCase::checkSupport (Context&) const
    787 {
    788 }
    789 
    790 } // vkt
    791