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 namespace vkt
     40 {
     41 
     42 // Default device utilities
     43 
     44 using std::vector;
     45 using std::string;
     46 using namespace vk;
     47 
     48 namespace
     49 {
     50 
     51 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
     52 {
     53 	static const char*	s_magicLayer		= "VK_LAYER_LUNARG_standard_validation";
     54 	static const char*	s_defaultLayers[]	=
     55 	{
     56 		"VK_LAYER_GOOGLE_threading",
     57 		"VK_LAYER_LUNARG_parameter_validation",
     58 		"VK_LAYER_LUNARG_device_limits",
     59 		"VK_LAYER_LUNARG_object_tracker",
     60 		"VK_LAYER_LUNARG_image",
     61 		"VK_LAYER_LUNARG_core_validation",
     62 		"VK_LAYER_LUNARG_swapchain",
     63 		"VK_LAYER_GOOGLE_unique_objects"
     64 	};
     65 
     66 	vector<string>		enabledLayers;
     67 
     68 	if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
     69 		enabledLayers.push_back(s_magicLayer);
     70 	else
     71 	{
     72 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
     73 		{
     74 			if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
     75 				enabledLayers.push_back(s_defaultLayers[ndx]);
     76 		}
     77 	}
     78 
     79 	return enabledLayers;
     80 }
     81 
     82 vector<string> getValidationLayers (const PlatformInterface& vkp)
     83 {
     84 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
     85 }
     86 
     87 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
     88 {
     89 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
     90 }
     91 
     92 vector<string> filterExtensions(const vector<VkExtensionProperties>& deviceExtensions)
     93 {
     94 	vector<string>	enabledExtensions;
     95 	const char*		extensionGroups[] =
     96 	{
     97 		"VK_KHR_",
     98 		"VK_EXT_",
     99 		"VK_KHX_"
    100 	};
    101 
    102 	for (size_t deviceExtNdx = 0; deviceExtNdx < deviceExtensions.size(); deviceExtNdx++)
    103 	{
    104 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
    105 		{
    106 			if (deStringBeginsWith(deviceExtensions[deviceExtNdx].extensionName, extensionGroups[extGroupNdx]))
    107 				enabledExtensions.push_back(deviceExtensions[deviceExtNdx].extensionName);
    108 		}
    109 	}
    110 
    111 	return enabledExtensions;
    112 }
    113 
    114 Move<VkInstance> createInstance (const PlatformInterface& vkp, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
    115 {
    116 	const bool							isValidationEnabled	= cmdLine.isValidationEnabled();
    117 	vector<string>						enabledLayers;
    118 
    119 	if (isValidationEnabled)
    120 	{
    121 		if (!isDebugReportSupported(vkp))
    122 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
    123 
    124 		enabledLayers = getValidationLayers(vkp);
    125 		if (enabledLayers.empty())
    126 			TCU_THROW(NotSupportedError, "No validation layers found");
    127 	}
    128 
    129 	return createDefaultInstance(vkp, enabledLayers, enabledExtensions);
    130 }
    131 
    132 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
    133 {
    134 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
    135 
    136 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
    137 	{
    138 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
    139 			return (deUint32)queueNdx;
    140 	}
    141 
    142 	TCU_THROW(NotSupportedError, "No matching queue found");
    143 }
    144 
    145 Move<VkDevice> createDefaultDevice (const InstanceInterface&			vki,
    146 									VkPhysicalDevice					physicalDevice,
    147 									deUint32							queueIndex,
    148 									const VkPhysicalDeviceFeatures2KHR&	enabledFeatures,
    149 									const vector<string>&				enabledExtensions,
    150 									const tcu::CommandLine&				cmdLine)
    151 {
    152 	VkDeviceQueueCreateInfo		queueInfo;
    153 	VkDeviceCreateInfo			deviceInfo;
    154 	vector<string>				enabledLayers;
    155 	vector<const char*>			layerPtrs;
    156 	vector<const char*>			extensionPtrs;
    157 	const float					queuePriority	= 1.0f;
    158 
    159 	deMemset(&queueInfo,	0, sizeof(queueInfo));
    160 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
    161 
    162 	if (cmdLine.isValidationEnabled())
    163 	{
    164 		enabledLayers = getValidationLayers(vki, physicalDevice);
    165 		if (enabledLayers.empty())
    166 			TCU_THROW(NotSupportedError, "No validation layers found");
    167 	}
    168 
    169 	layerPtrs.resize(enabledLayers.size());
    170 
    171 	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
    172 		layerPtrs[ndx] = enabledLayers[ndx].c_str();
    173 
    174 	extensionPtrs.resize(enabledExtensions.size());
    175 
    176 	for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
    177 		extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
    178 
    179 	// VK_KHR_get_physical_device_propeties2 is used if enabledFeatures.pNext != 0
    180 
    181 	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    182 	queueInfo.pNext							= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
    183 	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
    184 	queueInfo.queueFamilyIndex				= queueIndex;
    185 	queueInfo.queueCount					= 1u;
    186 	queueInfo.pQueuePriorities				= &queuePriority;
    187 
    188 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    189 	deviceInfo.pNext						= DE_NULL;
    190 	deviceInfo.queueCreateInfoCount			= 1u;
    191 	deviceInfo.pQueueCreateInfos			= &queueInfo;
    192 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
    193 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
    194 	deviceInfo.enabledLayerCount			= (deUint32)layerPtrs.size();
    195 	deviceInfo.ppEnabledLayerNames			= (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
    196 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
    197 
    198 	return createDevice(vki, physicalDevice, &deviceInfo);
    199 };
    200 
    201 bool isPhysicalDeviceFeatures2Supported (const vector<string>& instanceExtensions)
    202 {
    203 	return de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2");
    204 }
    205 
    206 struct DeviceFeatures
    207 {
    208 	VkPhysicalDeviceFeatures2KHR						coreFeatures;
    209 	VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR	samplerYCbCrConversionFeatures;
    210 
    211 	DeviceFeatures (const InstanceInterface&	vki,
    212 					VkPhysicalDevice			physicalDevice,
    213 					const vector<string>&		instanceExtensions,
    214 					const vector<string>&		deviceExtensions)
    215 	{
    216 		void**	curExtPoint		= &coreFeatures.pNext;
    217 
    218 		deMemset(&coreFeatures, 0, sizeof(coreFeatures));
    219 		deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
    220 
    221 		coreFeatures.sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
    222 		samplerYCbCrConversionFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR;
    223 
    224 		if (isPhysicalDeviceFeatures2Supported(instanceExtensions))
    225 		{
    226 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
    227 			{
    228 				*curExtPoint = &samplerYCbCrConversionFeatures;
    229 				curExtPoint = &samplerYCbCrConversionFeatures.pNext;
    230 			}
    231 
    232 			vki.getPhysicalDeviceFeatures2KHR(physicalDevice, &coreFeatures);
    233 		}
    234 		else
    235 			coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
    236 
    237 		// Disable robustness by default, as it has an impact on performance on some HW.
    238 		coreFeatures.features.robustBufferAccess = false;
    239 	}
    240 };
    241 
    242 } // anonymous
    243 
    244 class DefaultDevice
    245 {
    246 public:
    247 										DefaultDevice					(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
    248 										~DefaultDevice					(void);
    249 
    250 	VkInstance							getInstance						(void) const	{ return *m_instance;								}
    251 	const InstanceInterface&			getInstanceInterface			(void) const	{ return m_instanceInterface;						}
    252 	const vector<string>&				getInstanceExtensions			(void) const	{ return m_instanceExtensions;						}
    253 
    254 	VkPhysicalDevice					getPhysicalDevice				(void) const	{ return m_physicalDevice;							}
    255 	const VkPhysicalDeviceFeatures&		getDeviceFeatures				(void) const	{ return m_deviceFeatures.coreFeatures.features;	}
    256 	const VkPhysicalDeviceFeatures2KHR&	getDeviceFeatures2				(void) const	{ return m_deviceFeatures.coreFeatures;				}
    257 	VkDevice							getDevice						(void) const	{ return *m_device;									}
    258 	const DeviceInterface&				getDeviceInterface				(void) const	{ return m_deviceInterface;							}
    259 	const VkPhysicalDeviceProperties&	getDeviceProperties				(void) const	{ return m_deviceProperties;						}
    260 	const vector<string>&				getDeviceExtensions				(void) const	{ return m_deviceExtensions;						}
    261 
    262 	deUint32							getUniversalQueueFamilyIndex	(void) const	{ return m_universalQueueFamilyIndex;				}
    263 	VkQueue								getUniversalQueue				(void) const;
    264 
    265 private:
    266 	static VkPhysicalDeviceFeatures		filterDefaultDeviceFeatures		(const VkPhysicalDeviceFeatures& deviceFeatures);
    267 
    268 	const vector<string>				m_instanceExtensions;
    269 	const Unique<VkInstance>			m_instance;
    270 	const InstanceDriver				m_instanceInterface;
    271 
    272 	const VkPhysicalDevice				m_physicalDevice;
    273 
    274 	const deUint32						m_universalQueueFamilyIndex;
    275 	const vector<string>				m_deviceExtensions;
    276 	const DeviceFeatures				m_deviceFeatures;
    277 	const VkPhysicalDeviceProperties	m_deviceProperties;
    278 
    279 	const Unique<VkDevice>				m_device;
    280 	const DeviceDriver					m_deviceInterface;
    281 };
    282 
    283 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
    284 	: m_instanceExtensions			(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)))
    285 	, m_instance					(createInstance(vkPlatform, m_instanceExtensions, cmdLine))
    286 	, m_instanceInterface			(vkPlatform, *m_instance)
    287 	, m_physicalDevice				(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
    288 	, m_universalQueueFamilyIndex	(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
    289 	, m_deviceExtensions			(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
    290 	, m_deviceFeatures				(m_instanceInterface, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
    291 	, m_deviceProperties			(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
    292 	, m_device						(createDefaultDevice(m_instanceInterface,
    293 														 m_physicalDevice,
    294 														 m_universalQueueFamilyIndex,
    295 														 m_deviceFeatures.coreFeatures,
    296 														 m_deviceExtensions,
    297 														 cmdLine))
    298 	, m_deviceInterface				(m_instanceInterface, *m_device)
    299 {
    300 }
    301 
    302 DefaultDevice::~DefaultDevice (void)
    303 {
    304 }
    305 
    306 VkQueue DefaultDevice::getUniversalQueue (void) const
    307 {
    308 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
    309 }
    310 
    311 namespace
    312 {
    313 
    314 // Allocator utilities
    315 
    316 vk::Allocator* createAllocator (DefaultDevice* device)
    317 {
    318 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
    319 
    320 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
    321 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
    322 }
    323 
    324 } // anonymous
    325 
    326 // Context
    327 
    328 Context::Context (tcu::TestContext&							testCtx,
    329 				  const vk::PlatformInterface&				platformInterface,
    330 				  vk::ProgramCollection<vk::ProgramBinary>&	progCollection)
    331 	: m_testCtx				(testCtx)
    332 	, m_platformInterface	(platformInterface)
    333 	, m_progCollection		(progCollection)
    334 	, m_device				(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
    335 	, m_allocator			(createAllocator(m_device.get()))
    336 {
    337 }
    338 
    339 Context::~Context (void)
    340 {
    341 }
    342 
    343 const vector<string>&					Context::getInstanceExtensions			(void) const { return m_device->getInstanceExtensions();		}
    344 vk::VkInstance							Context::getInstance					(void) const { return m_device->getInstance();					}
    345 const vk::InstanceInterface&			Context::getInstanceInterface			(void) const { return m_device->getInstanceInterface();			}
    346 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
    347 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
    348 const vk::VkPhysicalDeviceFeatures2KHR&	Context::getDeviceFeatures2				(void) const { return m_device->getDeviceFeatures2();			}
    349 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
    350 const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
    351 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
    352 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
    353 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
    354 vk::VkQueue								Context::getUniversalQueue				(void) const { return m_device->getUniversalQueue();			}
    355 vk::Allocator&							Context::getDefaultAllocator			(void) const { return *m_allocator;								}
    356 
    357 // TestCase
    358 
    359 void TestCase::initPrograms (SourceCollections&) const
    360 {
    361 }
    362 
    363 } // vkt
    364