• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getValidationLayers(const vector<VkLayerProperties> & supportedLayers)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 
getValidationLayers(const PlatformInterface & vkp)82 vector<string> getValidationLayers (const PlatformInterface& vkp)
83 {
84 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
85 }
86 
getValidationLayers(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)87 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
88 {
89 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
90 }
91 
filterExtensions(const vector<VkExtensionProperties> & deviceExtensions)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 
createInstance(const PlatformInterface & vkp,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)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 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)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 
createDefaultDevice(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueIndex,const VkPhysicalDeviceFeatures2KHR & enabledFeatures,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)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 
isPhysicalDeviceFeatures2Supported(const vector<string> & instanceExtensions)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 
DeviceFeaturesvkt::__anonf5dae72f0111::DeviceFeatures211 	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 
getInstance(void) const250 	VkInstance							getInstance						(void) const	{ return *m_instance;								}
getInstanceInterface(void) const251 	const InstanceInterface&			getInstanceInterface			(void) const	{ return m_instanceInterface;						}
getInstanceExtensions(void) const252 	const vector<string>&				getInstanceExtensions			(void) const	{ return m_instanceExtensions;						}
253 
getPhysicalDevice(void) const254 	VkPhysicalDevice					getPhysicalDevice				(void) const	{ return m_physicalDevice;							}
getDeviceFeatures(void) const255 	const VkPhysicalDeviceFeatures&		getDeviceFeatures				(void) const	{ return m_deviceFeatures.coreFeatures.features;	}
getDeviceFeatures2(void) const256 	const VkPhysicalDeviceFeatures2KHR&	getDeviceFeatures2				(void) const	{ return m_deviceFeatures.coreFeatures;				}
getDevice(void) const257 	VkDevice							getDevice						(void) const	{ return *m_device;									}
getDeviceInterface(void) const258 	const DeviceInterface&				getDeviceInterface				(void) const	{ return m_deviceInterface;							}
getDeviceProperties(void) const259 	const VkPhysicalDeviceProperties&	getDeviceProperties				(void) const	{ return m_deviceProperties;						}
getDeviceExtensions(void) const260 	const vector<string>&				getDeviceExtensions				(void) const	{ return m_deviceExtensions;						}
261 
getUniversalQueueFamilyIndex(void) const262 	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 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)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 
~DefaultDevice(void)302 DefaultDevice::~DefaultDevice (void)
303 {
304 }
305 
getUniversalQueue(void) const306 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 
createAllocator(DefaultDevice * device)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 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::ProgramCollection<vk::ProgramBinary> & progCollection)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 
~Context(void)339 Context::~Context (void)
340 {
341 }
342 
getInstanceExtensions(void) const343 const vector<string>&					Context::getInstanceExtensions			(void) const { return m_device->getInstanceExtensions();		}
getInstance(void) const344 vk::VkInstance							Context::getInstance					(void) const { return m_device->getInstance();					}
getInstanceInterface(void) const345 const vk::InstanceInterface&			Context::getInstanceInterface			(void) const { return m_device->getInstanceInterface();			}
getPhysicalDevice(void) const346 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
getDeviceFeatures(void) const347 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
getDeviceFeatures2(void) const348 const vk::VkPhysicalDeviceFeatures2KHR&	Context::getDeviceFeatures2				(void) const { return m_device->getDeviceFeatures2();			}
getDeviceProperties(void) const349 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
getDeviceExtensions(void) const350 const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
getDevice(void) const351 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const352 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const353 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const354 vk::VkQueue								Context::getUniversalQueue				(void) const { return m_device->getUniversalQueue();			}
getDefaultAllocator(void) const355 vk::Allocator&							Context::getDefaultAllocator			(void) const { return *m_allocator;								}
356 
357 // TestCase
358 
initPrograms(SourceCollections &) const359 void TestCase::initPrograms (SourceCollections&) const
360 {
361 }
362 
363 } // vkt
364