• 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 #include "vktCustomInstancesDevices.hpp"
26 
27 #include "vkRef.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkDebugReportUtil.hpp"
34 #include "vkDeviceFeatures.hpp"
35 #include "vkDeviceProperties.hpp"
36 
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include "deSTLUtil.hpp"
41 #include "deMemory.h"
42 
43 #include <set>
44 
45 struct vk_executor;
46 
47 namespace vkt
48 {
49 
50 // Default device utilities
51 
52 using std::vector;
53 using std::string;
54 using std::set;
55 using namespace vk;
56 
57 namespace
58 {
59 
filterExtensions(const vector<VkExtensionProperties> & extensions)60 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
61 {
62 	vector<string>	enabledExtensions;
63 	const char*		extensionGroups[] =
64 	{
65 		"VK_KHR_",
66 		"VK_EXT_",
67 		"VK_KHX_",
68 		"VK_NV_cooperative_matrix",
69 		"VK_NV_shading_rate_image",
70 		"VK_NV_ray_tracing",
71 		"VK_AMD_mixed_attachment_samples",
72 		"VK_AMD_shader_fragment_mask",
73 		"VK_AMD_buffer_marker",
74 	};
75 
76 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
77 	{
78 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
79 		{
80 			if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
81 				enabledExtensions.push_back(extensions[extNdx].extensionName);
82 		}
83 	}
84 
85 	return enabledExtensions;
86 }
87 
addExtensions(const vector<string> & a,const vector<const char * > & b)88 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
89 {
90 	vector<string>	res		(a);
91 
92 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
93 	{
94 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
95 			res.push_back(string(*bIter));
96 	}
97 
98 	return res;
99 }
100 
removeExtensions(const vector<string> & a,const vector<const char * > & b)101 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
102 {
103 	vector<string>	res;
104 	set<string>		removeExts	(b.begin(), b.end());
105 
106 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
107 	{
108 		if (!de::contains(removeExts, *aIter))
109 			res.push_back(*aIter);
110 	}
111 
112 	return res;
113 }
114 
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)115 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
116 {
117 	vector<const char*> coreExtensions;
118 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
119 	return addExtensions(extensions, coreExtensions);
120 }
121 
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)122 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
123 {
124 	vector<const char*> coreExtensions;
125 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
126 	return addExtensions(extensions, coreExtensions);
127 }
128 
getTargetInstanceVersion(const PlatformInterface & vkp)129 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
130 {
131 	deUint32 version = pack(ApiVersion(1, 0, 0));
132 
133 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
134 		TCU_THROW(InternalError, "Enumerate instance version error");
135 	return version;
136 }
137 
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)138 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
139 {
140 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion);
141 	InstanceDriver							preinterface			(vkp, preinstance.get());
142 
143 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
144 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
145 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
146 	{
147 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
148 		if (props.apiVersion < lowestDeviceVersion)
149 			lowestDeviceVersion = props.apiVersion;
150 	}
151 
152 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
153 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
154 	const deUint32							choosenDeviceVersion	= props.apiVersion;
155 
156 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
157 }
158 
159 
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)160 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
161 {
162 	const bool								isValidationEnabled	= cmdLine.isValidationEnabled();
163 	vector<const char*>						enabledLayers;
164 
165 	// \note Extensions in core are not explicitly enabled even though
166 	//		 they are in the extension list advertised to tests.
167 	vector<const char*>						coreExtensions;
168 	getCoreInstanceExtensions(apiVersion, coreExtensions);
169 	vector<string>							nonCoreExtensions	(removeExtensions(enabledExtensions, coreExtensions));
170 
171 	if (isValidationEnabled)
172 	{
173 		if (!isDebugReportSupported(vkp))
174 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
175 
176 		enabledLayers = vkt::getValidationLayers(vkp);
177 		if (enabledLayers.empty())
178 			TCU_THROW(NotSupportedError, "No validation layers found");
179 	}
180 
181 	return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions);
182 }
183 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)184 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
185 {
186 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
187 
188 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
189 	{
190 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
191 			return (deUint32)queueNdx;
192 	}
193 
194 	TCU_THROW(NotSupportedError, "No matching queue found");
195 }
196 
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const deUint32 apiVersion,deUint32 queueIndex,deUint32 sparseQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)197 Move<VkDevice> createDefaultDevice (const PlatformInterface&			vkp,
198 									VkInstance							instance,
199 									const InstanceInterface&			vki,
200 									VkPhysicalDevice					physicalDevice,
201 									const deUint32						apiVersion,
202 									deUint32							queueIndex,
203 									deUint32							sparseQueueIndex,
204 									const VkPhysicalDeviceFeatures2&	enabledFeatures,
205 									const vector<string>&				enabledExtensions,
206 									const tcu::CommandLine&				cmdLine)
207 {
208 	VkDeviceQueueCreateInfo		queueInfo[2];
209 	VkDeviceCreateInfo			deviceInfo;
210 	vector<const char*>			enabledLayers;
211 	vector<const char*>			extensionPtrs;
212 	const float					queuePriority	= 1.0f;
213 	const deUint32				numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
214 
215 	deMemset(&queueInfo,	0, sizeof(queueInfo));
216 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
217 
218 	if (cmdLine.isValidationEnabled())
219 	{
220 		enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
221 		if (enabledLayers.empty())
222 			TCU_THROW(NotSupportedError, "No validation layers found");
223 	}
224 
225 	// \note Extensions in core are not explicitly enabled even though
226 	//		 they are in the extension list advertised to tests.
227 	vector<const char*> coreExtensions;
228 	getCoreDeviceExtensions(apiVersion, coreExtensions);
229 	vector<string>	nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
230 
231 	extensionPtrs.resize(nonCoreExtensions.size());
232 
233 	for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
234 		extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
235 
236 	queueInfo[0].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
237 	queueInfo[0].pNext						= DE_NULL;
238 	queueInfo[0].flags						= (VkDeviceQueueCreateFlags)0u;
239 	queueInfo[0].queueFamilyIndex			= queueIndex;
240 	queueInfo[0].queueCount					= 1u;
241 	queueInfo[0].pQueuePriorities			= &queuePriority;
242 
243 	if (numQueues > 1)
244 	{
245 		queueInfo[1].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
246 		queueInfo[1].pNext						= DE_NULL;
247 		queueInfo[1].flags						= (VkDeviceQueueCreateFlags)0u;
248 		queueInfo[1].queueFamilyIndex			= sparseQueueIndex;
249 		queueInfo[1].queueCount					= 1u;
250 		queueInfo[1].pQueuePriorities			= &queuePriority;
251 	}
252 
253 	// VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
254 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
255 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
256 	deviceInfo.queueCreateInfoCount			= numQueues;
257 	deviceInfo.pQueueCreateInfos			= queueInfo;
258 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
259 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
260 	deviceInfo.enabledLayerCount			= (deUint32)enabledLayers.size();
261 	deviceInfo.ppEnabledLayerNames			= (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
262 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
263 
264 	return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
265 };
266 
267 } // anonymous
268 
269 class DefaultDevice
270 {
271 public:
272 																	DefaultDevice							(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
273 																	~DefaultDevice							(void);
274 
getInstance(void) const275 	VkInstance														getInstance								(void) const { return *m_instance;										}
getInstanceInterface(void) const276 	const InstanceInterface&										getInstanceInterface					(void) const { return m_instanceInterface;								}
getMaximumFrameworkVulkanVersion(void) const277 	deUint32														getMaximumFrameworkVulkanVersion		(void) const { return m_maximumFrameworkVulkanVersion;					}
getAvailableInstanceVersion(void) const278 	deUint32														getAvailableInstanceVersion				(void) const { return m_availableInstanceVersion;						}
getUsedInstanceVersion(void) const279 	deUint32														getUsedInstanceVersion					(void) const { return m_usedInstanceVersion;							}
getInstanceExtensions(void) const280 	const vector<string>&											getInstanceExtensions					(void) const { return m_instanceExtensions;								}
281 
getPhysicalDevice(void) const282 	VkPhysicalDevice												getPhysicalDevice						(void) const { return m_physicalDevice;									}
getDeviceVersion(void) const283 	deUint32														getDeviceVersion						(void) const { return m_deviceVersion;									}
284 
isDeviceFeatureInitialized(VkStructureType sType) const285 	bool															isDeviceFeatureInitialized				(VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);		}
getDeviceFeatures(void) const286 	const VkPhysicalDeviceFeatures&									getDeviceFeatures						(void) const { return m_deviceFeatures.getCoreFeatures2().features;		}
getDeviceFeatures2(void) const287 	const VkPhysicalDeviceFeatures2&								getDeviceFeatures2						(void) const { return m_deviceFeatures.getCoreFeatures2();				}
getVulkan11Features(void) const288 	const VkPhysicalDeviceVulkan11Features&							getVulkan11Features						(void) const { return m_deviceFeatures.getVulkan11Features(); }
getVulkan12Features(void) const289 	const VkPhysicalDeviceVulkan12Features&							getVulkan12Features						(void) const { return m_deviceFeatures.getVulkan12Features(); }
290 
291 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
292 
isDevicePropertyInitialized(VkStructureType sType) const293 	bool															isDevicePropertyInitialized				(VkStructureType sType) const { return m_devicePropertiesFull.isDevicePropertyInitialized(sType);	}
getDeviceProperties(void) const294 	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties;									}
getDeviceProperties2(void) const295 	const VkPhysicalDeviceProperties2&								getDeviceProperties2					(void) const { return m_devicePropertiesFull.getCoreProperties2();			}
296 
297 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
298 
getDevice(void) const299 	VkDevice														getDevice								(void) const { return *m_device;											}
getDeviceInterface(void) const300 	const DeviceInterface&											getDeviceInterface						(void) const { return m_deviceInterface;									}
getDeviceExtensions(void) const301 	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;									}
getUsedApiVersion(void) const302 	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;										}
getUniversalQueueFamilyIndex(void) const303 	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;							}
304 	VkQueue															getUniversalQueue						(void) const;
getSparseQueueFamilyIndex(void) const305 	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;								}
306 	VkQueue															getSparseQueue							(void) const;
307 
308 private:
309 
310 	const deUint32						m_maximumFrameworkVulkanVersion;
311 	const deUint32						m_availableInstanceVersion;
312 	const deUint32						m_usedInstanceVersion;
313 
314 	const std::pair<deUint32, deUint32> m_deviceVersions;
315 	const deUint32						m_usedApiVersion;
316 
317 	const vector<string>				m_instanceExtensions;
318 	const Unique<VkInstance>			m_instance;
319 	const InstanceDriver				m_instanceInterface;
320 
321 	const VkPhysicalDevice				m_physicalDevice;
322 	const deUint32						m_deviceVersion;
323 
324 	const vector<string>				m_deviceExtensions;
325 	const DeviceFeatures				m_deviceFeatures;
326 
327 	const deUint32						m_universalQueueFamilyIndex;
328 	const deUint32						m_sparseQueueFamilyIndex;
329 	const VkPhysicalDeviceProperties	m_deviceProperties;
330 	const DeviceProperties				m_devicePropertiesFull;
331 
332 	const Unique<VkDevice>				m_device;
333 	const DeviceDriver					m_deviceInterface;
334 };
335 
sanitizeApiVersion(deUint32 v)336 static deUint32 sanitizeApiVersion(deUint32 v)
337 {
338 	return VK_MAKE_VERSION( VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), 0 );
339 }
340 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)341 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
342 	: m_maximumFrameworkVulkanVersion	(VK_API_MAX_FRAMEWORK_VERSION)
343 	, m_availableInstanceVersion		(getTargetInstanceVersion(vkPlatform))
344 	, m_usedInstanceVersion				(sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
345 	, m_deviceVersions					(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
346 	, m_usedApiVersion					(sanitizeApiVersion(deMinu32(m_usedInstanceVersion, m_deviceVersions.first)))
347 
348 	, m_instanceExtensions				(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
349 	, m_instance						(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
350 
351 	, m_instanceInterface				(vkPlatform, *m_instance)
352 	, m_physicalDevice					(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
353 	, m_deviceVersion					(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
354 
355 	, m_deviceExtensions				(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
356 	, m_deviceFeatures					(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
357 	, m_universalQueueFamilyIndex		(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
358 	, m_sparseQueueFamilyIndex			(m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
359 	, m_deviceProperties				(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
360 	, m_devicePropertiesFull			(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
361 	, m_device							(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
362 	, m_deviceInterface					(vkPlatform, *m_instance, *m_device)
363 {
364 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
365 }
366 
~DefaultDevice(void)367 DefaultDevice::~DefaultDevice (void)
368 {
369 }
370 
getUniversalQueue(void) const371 VkQueue DefaultDevice::getUniversalQueue (void) const
372 {
373 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
374 }
375 
getSparseQueue(void) const376 VkQueue DefaultDevice::getSparseQueue (void) const
377 {
378 	if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
379 		TCU_THROW(NotSupportedError, "Sparse binding not supported.");
380 
381 	return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
382 }
383 
384 namespace
385 {
386 // Allocator utilities
387 
createAllocator(DefaultDevice * device)388 vk::Allocator* createAllocator (DefaultDevice* device)
389 {
390 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
391 
392 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
393 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
394 }
395 
396 } // anonymous
397 
398 // Context
399 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection)400 Context::Context (tcu::TestContext&				testCtx,
401 				  const vk::PlatformInterface&	platformInterface,
402 				  vk::BinaryCollection&			progCollection)
403 	: m_testCtx					(testCtx)
404 	, m_platformInterface		(platformInterface)
405 	, m_progCollection			(progCollection)
406 	, m_device					(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
407 	, m_allocator				(createAllocator(m_device.get()))
408 	, m_resultSetOnValidation	(false)
409 {
410 }
411 
~Context(void)412 Context::~Context (void)
413 {
414 }
415 
getMaximumFrameworkVulkanVersion(void) const416 deUint32								Context::getMaximumFrameworkVulkanVersion	(void) const { return m_device->getMaximumFrameworkVulkanVersion();		}
getAvailableInstanceVersion(void) const417 deUint32								Context::getAvailableInstanceVersion		(void) const { return m_device->getAvailableInstanceVersion();	}
getInstanceExtensions(void) const418 const vector<string>&					Context::getInstanceExtensions				(void) const { return m_device->getInstanceExtensions();		}
getInstance(void) const419 vk::VkInstance							Context::getInstance						(void) const { return m_device->getInstance();					}
getInstanceInterface(void) const420 const vk::InstanceInterface&			Context::getInstanceInterface				(void) const { return m_device->getInstanceInterface();			}
getPhysicalDevice(void) const421 vk::VkPhysicalDevice					Context::getPhysicalDevice					(void) const { return m_device->getPhysicalDevice();			}
getDeviceVersion(void) const422 deUint32								Context::getDeviceVersion					(void) const { return m_device->getDeviceVersion();				}
getDeviceFeatures(void) const423 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures					(void) const { return m_device->getDeviceFeatures();			}
getDeviceFeatures2(void) const424 const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2					(void) const { return m_device->getDeviceFeatures2();			}
425 
isDeviceFunctionalitySupported(const std::string & extension) const426 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
427 {
428 	// check if extension was promoted to core
429 	deUint32 apiVersion = getUsedApiVersion();
430 	if (isCoreDeviceExtension(getUsedApiVersion(), extension))
431 	{
432 		// all folowing checks are for vk12 and can be skipped for previous versions
433 		if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
434 			return true;
435 
436 		// handle promoted functionality that was provided under feature bit
437 		const auto& vk11Features = m_device->getVulkan11Features();
438 		if (extension == "VK_KHR_multiview")
439 			return !!vk11Features.multiview;
440 		if (extension == "VK_KHR_variable_pointers")
441 			return !!vk11Features.variablePointersStorageBuffer;
442 		if (extension == "VK_KHR_sampler_ycbcr_conversion")
443 			return !!vk11Features.samplerYcbcrConversion;
444 		if (extension == "VK_KHR_shader_draw_parameters")
445 			return !!vk11Features.shaderDrawParameters;
446 
447 		const auto& vk12Features = m_device->getVulkan12Features();
448 		if (extension == "VK_KHR_timeline_semaphore")
449 			return !!vk12Features.timelineSemaphore;
450 		if (extension == "VK_KHR_buffer_device_address")
451 			return !!vk12Features.bufferDeviceAddress;
452 		if (extension == "VK_EXT_descriptor_indexing")
453 			return !!vk12Features.descriptorIndexing;
454 		if (extension == "VK_KHR_draw_indirect_count")
455 			return !!vk12Features.drawIndirectCount;
456 		if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
457 			return !!vk12Features.samplerMirrorClampToEdge;
458 		if (extension == "VK_EXT_sampler_filter_minmax")
459 			return !!vk12Features.samplerFilterMinmax;
460 		if (extension == "VK_EXT_shader_viewport_index_layer")
461 			return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
462 
463 		// no feature flags to check
464 		return true;
465 	}
466 
467 	// check if extension is on the lits of extensions for current device
468 	const auto& extensions = getDeviceExtensions();
469 	if (de::contains(extensions.begin(), extensions.end(), extension))
470 	{
471 		if (extension == "VK_KHR_timeline_semaphore")
472 			return !!getTimelineSemaphoreFeatures().timelineSemaphore;
473 
474 		return true;
475 	}
476 
477 	return false;
478 }
479 
isInstanceFunctionalitySupported(const std::string & extension) const480 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
481 {
482 	// NOTE: current implementation uses isInstanceExtensionSupported but
483 	// this will change when some instance extensions will be promoted to the
484 	// core; don't use isInstanceExtensionSupported directly, use this method instead
485 	return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
486 }
487 
488 #include "vkDeviceFeaturesForContextDefs.inl"
489 
getDeviceProperties(void) const490 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();			}
getDeviceProperties2(void) const491 const vk::VkPhysicalDeviceProperties2&	Context::getDeviceProperties2				(void) const { return m_device->getDeviceProperties2();			}
492 
493 #include "vkDevicePropertiesForContextDefs.inl"
494 
getDeviceExtensions(void) const495 const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();			}
getDevice(void) const496 vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const497 const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const498 deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const499 vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();			}
getSparseQueueFamilyIndex(void) const500 deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();	}
getSparseQueue(void) const501 vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();				}
getDefaultAllocator(void) const502 vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;								}
getUsedApiVersion(void) const503 deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();			}
contextSupports(const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const504 bool									Context::contextSupports					(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
505 																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
contextSupports(const ApiVersion version) const506 bool									Context::contextSupports					(const ApiVersion version) const
507 																							{ return m_device->getUsedApiVersion() >= pack(version); }
contextSupports(const deUint32 requiredApiVersionBits) const508 bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
509 																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
isDeviceFeatureInitialized(vk::VkStructureType sType) const510 bool									Context::isDeviceFeatureInitialized			(vk::VkStructureType sType) const
511 																							{ return m_device->isDeviceFeatureInitialized(sType);	}
isDevicePropertyInitialized(vk::VkStructureType sType) const512 bool									Context::isDevicePropertyInitialized		(vk::VkStructureType sType) const
513 																							{ return m_device->isDevicePropertyInitialized(sType);	}
514 
requireDeviceFunctionality(const std::string & required) const515 bool Context::requireDeviceFunctionality (const std::string& required) const
516 {
517 	if (!isDeviceFunctionalitySupported(required))
518 		TCU_THROW(NotSupportedError, required + " is not supported");
519 
520 	return true;
521 }
522 
requireInstanceFunctionality(const std::string & required) const523 bool Context::requireInstanceFunctionality (const std::string& required) const
524 {
525 	if (!isInstanceFunctionalitySupported(required))
526 		TCU_THROW(NotSupportedError, required + " is not supported");
527 
528 	return true;
529 }
530 
531 struct DeviceCoreFeaturesTable
532 {
533 	const char*		featureName;
534 	const deUint32	featureArrayIndex;
535 	const deUint32	featureArrayOffset;
536 };
537 
538 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
539 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)	{ #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
540 
541 const DeviceCoreFeaturesTable	deviceCoreFeaturesTable[] =
542 {
543 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS							,	robustBufferAccess						),
544 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32						,	fullDrawIndexUint32						),
545 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY								,	imageCubeArray							),
546 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND								,	independentBlend						),
547 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER								,	geometryShader							),
548 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER							,	tessellationShader						),
549 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING							,	sampleRateShading						),
550 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND								,	dualSrcBlend							),
551 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP										,	logicOp									),
552 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT							,	multiDrawIndirect						),
553 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE					,	drawIndirectFirstInstance				),
554 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP									,	depthClamp								),
555 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP								,	depthBiasClamp							),
556 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID							,	fillModeNonSolid						),
557 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS									,	depthBounds								),
558 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES									,	wideLines								),
559 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS									,	largePoints								),
560 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE									,	alphaToOne								),
561 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT								,	multiViewport							),
562 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY							,	samplerAnisotropy						),
563 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2						,	textureCompressionETC2					),
564 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR					,	textureCompressionASTC_LDR				),
565 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC						,	textureCompressionBC					),
566 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE						,	occlusionQueryPrecise					),
567 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY						,	pipelineStatisticsQuery					),
568 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			,	vertexPipelineStoresAndAtomics			),
569 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS					,	fragmentStoresAndAtomics				),
570 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	,	shaderTessellationAndGeometryPointSize	),
571 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED					,	shaderImageGatherExtended				),
572 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS			,	shaderStorageImageExtendedFormats		),
573 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE				,	shaderStorageImageMultisample			),
574 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT		,	shaderStorageImageReadWithoutFormat		),
575 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT		,	shaderStorageImageWriteWithoutFormat	),
576 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderUniformBufferArrayDynamicIndexing	),
577 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderSampledImageArrayDynamicIndexing	),
578 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderStorageBufferArrayDynamicIndexing	),
579 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderStorageImageArrayDynamicIndexing	),
580 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE							,	shaderClipDistance						),
581 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE							,	shaderCullDistance						),
582 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64								,	shaderFloat64							),
583 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64									,	shaderInt64								),
584 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16									,	shaderInt16								),
585 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY						,	shaderResourceResidency					),
586 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD						,	shaderResourceMinLod					),
587 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING								,	sparseBinding							),
588 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER						,	sparseResidencyBuffer					),
589 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D						,	sparseResidencyImage2D					),
590 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D						,	sparseResidencyImage3D					),
591 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES						,	sparseResidency2Samples					),
592 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES						,	sparseResidency4Samples					),
593 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES						,	sparseResidency8Samples					),
594 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES					,	sparseResidency16Samples				),
595 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED						,	sparseResidencyAliased					),
596 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE						,	variableMultisampleRate					),
597 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES								,	inheritedQueries						),
598 };
599 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)600 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
601 {
602 	const vk::VkPhysicalDeviceFeatures& featuresAvailable		= getDeviceFeatures();
603 	const vk::VkBool32*					featuresAvailableArray	= (vk::VkBool32*)(&featuresAvailable);
604 	const deUint32						requiredFeatureIndex	= static_cast<deUint32>(requiredFeature);
605 
606 	DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
607 	DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
608 
609 	if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
610 		TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
611 
612 	return true;
613 }
614 
getInstanceProcAddr()615 void* Context::getInstanceProcAddr	()
616 {
617 	return (void*)m_platformInterface.getGetInstanceProcAddr();
618 }
619 
isBufferDeviceAddressSupported(void) const620 bool Context::isBufferDeviceAddressSupported(void) const
621 {
622 	return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
623 		   isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
624 }
625 
626 // TestCase
627 
initPrograms(SourceCollections &) const628 void TestCase::initPrograms (SourceCollections&) const
629 {
630 }
631 
checkSupport(Context &) const632 void TestCase::checkSupport (Context&) const
633 {
634 }
635 
delayedInit(void)636 void TestCase::delayedInit (void)
637 {
638 }
639 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)640 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
641 {
642 	// \note We are not logging INFORMATION and DEBUG messages
643 	static const vk::VkDebugReportFlagsEXT			errorFlags		= vk::VK_DEBUG_REPORT_ERROR_BIT_EXT;
644 	static const vk::VkDebugReportFlagsEXT			logFlags		= errorFlags
645 																	| vk::VK_DEBUG_REPORT_WARNING_BIT_EXT
646 																	| vk::VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
647 
648 	typedef vk::DebugReportRecorder::MessageList	DebugMessages;
649 
650 	const DebugMessages&	messages	= debugReportRecorder.getMessages();
651 	tcu::TestLog&			log			= context.getTestContext().getLog();
652 
653 	if (messages.begin() != messages.end())
654 	{
655 		const tcu::ScopedLogSection	section		(log, "DebugMessages", "Debug Messages");
656 		int							numErrors	= 0;
657 
658 		for (DebugMessages::const_iterator curMsg = messages.begin(); curMsg != messages.end(); ++curMsg)
659 		{
660 			if ((curMsg->flags & logFlags) != 0)
661 				log << tcu::TestLog::Message << *curMsg << tcu::TestLog::EndMessage;
662 
663 			if ((curMsg->flags & errorFlags) != 0)
664 				numErrors += 1;
665 		}
666 
667 		debugReportRecorder.clearMessages();
668 
669 		if (numErrors > 0)
670 		{
671 			string errorMsg = de::toString(numErrors) + " API usage errors found";
672 			context.resultSetOnValidation(true);
673 			context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
674 		}
675 	}
676 }
677 
678 } // vkt
679