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 
     36 #include "deSTLUtil.hpp"
     37 #include "deMemory.h"
     38 
     39 #include <set>
     40 
     41 namespace vkt
     42 {
     43 
     44 // Default device utilities
     45 
     46 using std::vector;
     47 using std::string;
     48 using std::set;
     49 using namespace vk;
     50 
     51 namespace
     52 {
     53 
     54 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
     55 {
     56 	static const char*	s_magicLayer		= "VK_LAYER_LUNARG_standard_validation";
     57 	static const char*	s_defaultLayers[]	=
     58 	{
     59 		"VK_LAYER_GOOGLE_threading",
     60 		"VK_LAYER_LUNARG_parameter_validation",
     61 		"VK_LAYER_LUNARG_device_limits",
     62 		"VK_LAYER_LUNARG_object_tracker",
     63 		"VK_LAYER_LUNARG_image",
     64 		"VK_LAYER_LUNARG_core_validation",
     65 		"VK_LAYER_LUNARG_swapchain",
     66 		"VK_LAYER_GOOGLE_unique_objects"
     67 	};
     68 
     69 	vector<string>		enabledLayers;
     70 
     71 	if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
     72 		enabledLayers.push_back(s_magicLayer);
     73 	else
     74 	{
     75 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
     76 		{
     77 			if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
     78 				enabledLayers.push_back(s_defaultLayers[ndx]);
     79 		}
     80 	}
     81 
     82 	return enabledLayers;
     83 }
     84 
     85 vector<string> getValidationLayers (const PlatformInterface& vkp)
     86 {
     87 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
     88 }
     89 
     90 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
     91 {
     92 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
     93 }
     94 
     95 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
     96 {
     97 	vector<string>	enabledExtensions;
     98 	const char*		extensionGroups[] =
     99 	{
    100 		"VK_KHR_",
    101 		"VK_EXT_",
    102 		"VK_KHX_"
    103 	};
    104 
    105 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
    106 	{
    107 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
    108 		{
    109 			if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
    110 				enabledExtensions.push_back(extensions[extNdx].extensionName);
    111 		}
    112 	}
    113 
    114 	return enabledExtensions;
    115 }
    116 
    117 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
    118 {
    119 	vector<string>	res		(a);
    120 
    121 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
    122 	{
    123 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
    124 			res.push_back(string(*bIter));
    125 	}
    126 
    127 	return res;
    128 }
    129 
    130 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
    131 {
    132 	vector<string>	res;
    133 	set<string>		removeExts	(b.begin(), b.end());
    134 
    135 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
    136 	{
    137 		if (!de::contains(removeExts, *aIter))
    138 			res.push_back(*aIter);
    139 	}
    140 
    141 	return res;
    142 }
    143 
    144 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
    145 {
    146 	vector<const char*> coreExtensions;
    147 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
    148 	return addExtensions(extensions, coreExtensions);
    149 }
    150 
    151 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
    152 {
    153 	vector<const char*> coreExtensions;
    154 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
    155 	return addExtensions(extensions, coreExtensions);
    156 }
    157 
    158 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
    159 {
    160 	deUint32 version = pack(ApiVersion(1, 0, 0));
    161 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
    162 		TCU_THROW(InternalError, "Enumerate instance version error");
    163 	return version;
    164 }
    165 
    166 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
    167 {
    168 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion);
    169 	InstanceDriver							preinterface			(vkp, preinstance.get());
    170 
    171 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
    172 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
    173 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
    174 	{
    175 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
    176 		if (props.apiVersion < lowestDeviceVersion)
    177 			lowestDeviceVersion = props.apiVersion;
    178 	}
    179 
    180 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
    181 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
    182 	const deUint32							choosenDeviceVersion	= props.apiVersion;
    183 
    184 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
    185 }
    186 
    187 
    188 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
    189 {
    190 	const bool								isValidationEnabled	= cmdLine.isValidationEnabled();
    191 	vector<string>							enabledLayers;
    192 
    193 	// \note Extensions in core are not explicitly enabled even though
    194 	//		 they are in the extension list advertised to tests.
    195 	vector<const char*>						coreExtensions;
    196 	getCoreInstanceExtensions(apiVersion, coreExtensions);
    197 	vector<string>							nonCoreExtensions	(removeExtensions(enabledExtensions, coreExtensions));
    198 
    199 	if (isValidationEnabled)
    200 	{
    201 		if (!isDebugReportSupported(vkp))
    202 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
    203 
    204 		enabledLayers = getValidationLayers(vkp);
    205 		if (enabledLayers.empty())
    206 			TCU_THROW(NotSupportedError, "No validation layers found");
    207 	}
    208 
    209 	return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions);
    210 }
    211 
    212 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
    213 {
    214 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
    215 
    216 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
    217 	{
    218 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
    219 			return (deUint32)queueNdx;
    220 	}
    221 
    222 	TCU_THROW(NotSupportedError, "No matching queue found");
    223 }
    224 
    225 Move<VkDevice> createDefaultDevice (const InstanceInterface&			vki,
    226 									VkPhysicalDevice					physicalDevice,
    227 									const deUint32						apiVersion,
    228 									deUint32							queueIndex,
    229 									const VkPhysicalDeviceFeatures2&	enabledFeatures,
    230 									const vector<string>&				enabledExtensions,
    231 									const tcu::CommandLine&				cmdLine)
    232 {
    233 	VkDeviceQueueCreateInfo		queueInfo;
    234 	VkDeviceCreateInfo			deviceInfo;
    235 	vector<string>				enabledLayers;
    236 	vector<const char*>			layerPtrs;
    237 	vector<const char*>			extensionPtrs;
    238 	const float					queuePriority	= 1.0f;
    239 
    240 	deMemset(&queueInfo,	0, sizeof(queueInfo));
    241 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
    242 
    243 	if (cmdLine.isValidationEnabled())
    244 	{
    245 		enabledLayers = getValidationLayers(vki, physicalDevice);
    246 		if (enabledLayers.empty())
    247 			TCU_THROW(NotSupportedError, "No validation layers found");
    248 	}
    249 
    250 	layerPtrs.resize(enabledLayers.size());
    251 
    252 	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
    253 		layerPtrs[ndx] = enabledLayers[ndx].c_str();
    254 
    255 	// \note Extensions in core are not explicitly enabled even though
    256 	//		 they are in the extension list advertised to tests.
    257 	vector<const char*> coreExtensions;
    258 	getCoreDeviceExtensions(apiVersion, coreExtensions);
    259 	vector<string>	nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
    260 
    261 	extensionPtrs.resize(nonCoreExtensions.size());
    262 
    263 	for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
    264 		extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
    265 
    266 	// VK_KHR_get_physical_device_propeties2 is used if enabledFeatures.pNext != 0
    267 
    268 	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    269 	queueInfo.pNext							= DE_NULL;
    270 	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
    271 	queueInfo.queueFamilyIndex				= queueIndex;
    272 	queueInfo.queueCount					= 1u;
    273 	queueInfo.pQueuePriorities				= &queuePriority;
    274 
    275 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    276 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
    277 	deviceInfo.queueCreateInfoCount			= 1u;
    278 	deviceInfo.pQueueCreateInfos			= &queueInfo;
    279 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
    280 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
    281 	deviceInfo.enabledLayerCount			= (deUint32)layerPtrs.size();
    282 	deviceInfo.ppEnabledLayerNames			= (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
    283 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
    284 
    285 	return createDevice(vki, physicalDevice, &deviceInfo);
    286 };
    287 
    288 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions)
    289 {
    290 	return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2");
    291 }
    292 
    293 class DeviceFeatures
    294 {
    295 public:
    296 	VkPhysicalDeviceFeatures2						coreFeatures;
    297 	VkPhysicalDeviceSamplerYcbcrConversionFeatures	samplerYCbCrConversionFeatures;
    298 
    299 	DeviceFeatures (const InstanceInterface&	vki,
    300 					const deUint32				apiVersion,
    301 					const VkPhysicalDevice&		physicalDevice,
    302 					const vector<string>&		instanceExtensions,
    303 					const vector<string>&		deviceExtensions)
    304 	{
    305 		deMemset(&coreFeatures, 0, sizeof(coreFeatures));
    306 		deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
    307 
    308 		coreFeatures.sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    309 		samplerYCbCrConversionFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
    310 
    311 		if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions))
    312 		{
    313 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
    314 				coreFeatures.pNext = &samplerYCbCrConversionFeatures;
    315 
    316 			vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
    317 		}
    318 		else
    319 			coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
    320 
    321 		// Disable robustness by default, as it has an impact on performance on some HW.
    322 		coreFeatures.features.robustBufferAccess = false;
    323 	}
    324 };
    325 
    326 } // anonymous
    327 
    328 class DefaultDevice
    329 {
    330 public:
    331 															DefaultDevice						(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
    332 															~DefaultDevice						(void);
    333 
    334 	VkInstance												getInstance							(void) const	{ return *m_instance;										}
    335 	const InstanceInterface&								getInstanceInterface				(void) const	{ return m_instanceInterface;								}
    336 	deUint32												getAvailableInstanceVersion			(void) const	{ return m_availableInstanceVersion;						}
    337 	const vector<string>&									getInstanceExtensions				(void) const	{ return m_instanceExtensions;								}
    338 
    339 	VkPhysicalDevice										getPhysicalDevice					(void) const	{ return m_physicalDevice;									}
    340 	deUint32												getDeviceVersion					(void) const	{ return m_deviceVersion;									}
    341 	const VkPhysicalDeviceFeatures&							getDeviceFeatures					(void) const	{ return m_deviceFeatures.coreFeatures.features;			}
    342 	const VkPhysicalDeviceFeatures2&						getDeviceFeatures2					(void) const	{ return m_deviceFeatures.coreFeatures; }
    343 	const VkPhysicalDeviceSamplerYcbcrConversionFeatures&	getSamplerYCbCrConversionFeatures	(void) const	{ return m_deviceFeatures.samplerYCbCrConversionFeatures;	}
    344 	VkDevice												getDevice							(void) const	{ return *m_device;											}
    345 	const DeviceInterface&									getDeviceInterface					(void) const	{ return m_deviceInterface;									}
    346 	const VkPhysicalDeviceProperties&						getDeviceProperties					(void) const	{ return m_deviceProperties;								}
    347 	const vector<string>&									getDeviceExtensions					(void) const	{ return m_deviceExtensions;								}
    348 
    349 	deUint32												getUsedApiVersion					(void) const	{ return m_usedApiVersion;									}
    350 
    351 	deUint32												getUniversalQueueFamilyIndex		(void) const	{ return m_universalQueueFamilyIndex;						}
    352 	VkQueue													getUniversalQueue					(void) const;
    353 
    354 private:
    355 
    356 	const deUint32						m_availableInstanceVersion;
    357 
    358 	const std::pair<deUint32, deUint32> m_deviceVersions;
    359 	const deUint32						m_usedApiVersion;
    360 
    361 	const vector<string>				m_instanceExtensions;
    362 	const Unique<VkInstance>			m_instance;
    363 	const InstanceDriver				m_instanceInterface;
    364 
    365 	const VkPhysicalDevice				m_physicalDevice;
    366 	const deUint32						m_deviceVersion;
    367 
    368 	const deUint32						m_universalQueueFamilyIndex;
    369 	const VkPhysicalDeviceProperties	m_deviceProperties;
    370 
    371 	const vector<string>				m_deviceExtensions;
    372 	const DeviceFeatures				m_deviceFeatures;
    373 
    374 	const Unique<VkDevice>				m_device;
    375 	const DeviceDriver					m_deviceInterface;
    376 
    377 };
    378 
    379 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
    380 	: m_availableInstanceVersion	(getTargetInstanceVersion(vkPlatform))
    381 	, m_deviceVersions				(determineDeviceVersions(vkPlatform, m_availableInstanceVersion, cmdLine))
    382 	, m_usedApiVersion				(deMinu32(m_availableInstanceVersion, m_deviceVersions.first))
    383 
    384 	, m_instanceExtensions			(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
    385 	, m_instance					(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
    386 
    387 	, m_instanceInterface			(vkPlatform, *m_instance)
    388 	, m_physicalDevice				(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
    389 	, m_deviceVersion				(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
    390 
    391 	, m_universalQueueFamilyIndex	(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
    392 	, m_deviceProperties			(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
    393 	, m_deviceExtensions			(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
    394 	, m_deviceFeatures				(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
    395 	, m_device						(createDefaultDevice(m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine))
    396 	, m_deviceInterface				(m_instanceInterface, *m_device)
    397 {
    398 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
    399 }
    400 
    401 DefaultDevice::~DefaultDevice (void)
    402 {
    403 }
    404 
    405 VkQueue DefaultDevice::getUniversalQueue (void) const
    406 {
    407 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
    408 }
    409 
    410 // Allocator utilities
    411 
    412 vk::Allocator* createAllocator (DefaultDevice* device)
    413 {
    414 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
    415 
    416 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
    417 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
    418 }
    419 
    420 // Context
    421 
    422 Context::Context (tcu::TestContext&				testCtx,
    423 				  const vk::PlatformInterface&	platformInterface,
    424 				  vk::BinaryCollection&			progCollection)
    425 	: m_testCtx				(testCtx)
    426 	, m_platformInterface	(platformInterface)
    427 	, m_progCollection		(progCollection)
    428 	, m_device				(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
    429 	, m_allocator			(createAllocator(m_device.get()))
    430 {
    431 }
    432 
    433 Context::~Context (void)
    434 {
    435 }
    436 
    437 deUint32								Context::getAvailableInstanceVersion	(void) const { return m_device->getAvailableInstanceVersion();	}
    438 const vector<string>&					Context::getInstanceExtensions			(void) const { return m_device->getInstanceExtensions();		}
    439 vk::VkInstance							Context::getInstance					(void) const { return m_device->getInstance();					}
    440 const vk::InstanceInterface&			Context::getInstanceInterface			(void) const { return m_device->getInstanceInterface();			}
    441 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
    442 deUint32								Context::getDeviceVersion				(void) const { return m_device->getDeviceVersion();				}
    443 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
    444 const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2				(void) const { return m_device->getDeviceFeatures2();			}
    445 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&
    446 										Context::getSamplerYCbCrConversionFeatures
    447 																				(void) const { return m_device->getSamplerYCbCrConversionFeatures();	}
    448 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
    449 const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
    450 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
    451 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
    452 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
    453 vk::VkQueue								Context::getUniversalQueue				(void) const { return m_device->getUniversalQueue();			}
    454 vk::Allocator&							Context::getDefaultAllocator			(void) const { return *m_allocator;								}
    455 deUint32								Context::getUsedApiVersion				(void) const { return m_device->getUsedApiVersion();			}
    456 bool									Context::contextSupports				(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
    457 																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
    458 bool									Context::contextSupports				(const ApiVersion version) const
    459 																							{ return m_device->getUsedApiVersion() >= pack(version); }
    460 bool									Context::contextSupports				(const deUint32 requiredApiVersionBits) const
    461 																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
    462 
    463 // TestCase
    464 
    465 void TestCase::initPrograms (SourceCollections&) const
    466 {
    467 }
    468 
    469 } // vkt
    470