• 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 namespace vkt
46 {
47 
48 // Default device utilities
49 
50 using std::vector;
51 using std::string;
52 using std::set;
53 using namespace vk;
54 
55 namespace
56 {
57 
filterExtensions(const vector<VkExtensionProperties> & extensions)58 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
59 {
60 	vector<string>	enabledExtensions;
61 	bool			khrBufferDeviceAddress	= false;
62 
63 	const char*		extensionGroups[]		=
64 	{
65 		"VK_KHR_",
66 		"VK_EXT_",
67 		"VK_KHX_",
68 		"VK_NV_cooperative_matrix",
69 		"VK_NV_ray_tracing",
70 		"VK_NV_inherited_viewport_scissor",
71 		"VK_NV_mesh_shader",
72 		"VK_AMD_mixed_attachment_samples",
73 		"VK_AMD_shader_fragment_mask",
74 		"VK_AMD_buffer_marker",
75 		"VK_AMD_shader_explicit_vertex_parameter",
76 		"VK_AMD_shader_image_load_store_lod",
77 		"VK_AMD_shader_trinary_minmax",
78 		"VK_AMD_texture_gather_bias_lod",
79 		"VK_ANDROID_external_memory_android_hardware_buffer",
80 		"VK_VALVE_mutable_descriptor_type",
81 		"VK_NV_shader_subgroup_partitioned",
82 		"VK_NV_clip_space_w_scaling",
83 		"VK_NV_scissor_exclusive",
84 		"VK_NV_shading_rate_image",
85 		"VK_GOOGLE_surfaceless_query",
86 	};
87 
88 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
89 	{
90 		if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
91 		{
92 			khrBufferDeviceAddress = true;
93 			break;
94 		}
95 	}
96 
97 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
98 	{
99 		const auto& extName = extensions[extNdx].extensionName;
100 
101 		// Skip enabling VK_KHR_pipeline_library unless needed.
102 		if (deStringEqual(extName, "VK_KHR_pipeline_library"))
103 			continue;
104 
105 		// VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
106 		if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
107 			continue;
108 
109 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
110 		{
111 			if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
112 				enabledExtensions.push_back(extName);
113 		}
114 	}
115 
116 	return enabledExtensions;
117 }
118 
addExtensions(const vector<string> & a,const vector<const char * > & b)119 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
120 {
121 	vector<string>	res		(a);
122 
123 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
124 	{
125 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
126 			res.push_back(string(*bIter));
127 	}
128 
129 	return res;
130 }
131 
removeExtensions(const vector<string> & a,const vector<const char * > & b)132 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
133 {
134 	vector<string>	res;
135 	set<string>		removeExts	(b.begin(), b.end());
136 
137 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
138 	{
139 		if (!de::contains(removeExts, *aIter))
140 			res.push_back(*aIter);
141 	}
142 
143 	return res;
144 }
145 
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)146 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
147 {
148 	vector<const char*> coreExtensions;
149 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
150 	return addExtensions(extensions, coreExtensions);
151 }
152 
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)153 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
154 {
155 	vector<const char*> coreExtensions;
156 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
157 	return addExtensions(extensions, coreExtensions);
158 }
159 
getTargetInstanceVersion(const PlatformInterface & vkp)160 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
161 {
162 	deUint32 version = pack(ApiVersion(1, 0, 0));
163 
164 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
165 		TCU_THROW(InternalError, "Enumerate instance version error");
166 	return version;
167 }
168 
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)169 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
170 {
171 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion);
172 	InstanceDriver							preinterface			(vkp, preinstance.get());
173 
174 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
175 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
176 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
177 	{
178 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
179 		if (props.apiVersion < lowestDeviceVersion)
180 			lowestDeviceVersion = props.apiVersion;
181 	}
182 
183 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
184 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
185 	const deUint32							choosenDeviceVersion	= props.apiVersion;
186 
187 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
188 }
189 
190 
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,DebugReportRecorder * recorder)191 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, DebugReportRecorder* recorder)
192 {
193 	const bool			isValidationEnabled	= (recorder != nullptr);
194 	vector<const char*>	enabledLayers;
195 
196 	// \note Extensions in core are not explicitly enabled even though
197 	//		 they are in the extension list advertised to tests.
198 	vector<const char*> coreExtensions;
199 	getCoreInstanceExtensions(apiVersion, coreExtensions);
200 	const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
201 
202 	if (isValidationEnabled)
203 	{
204 		if (!isDebugReportSupported(vkp))
205 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
206 
207 		enabledLayers = vkt::getValidationLayers(vkp);
208 		if (enabledLayers.empty())
209 			TCU_THROW(NotSupportedError, "No validation layers found");
210 	}
211 
212 	return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, recorder);
213 }
214 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)215 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
216 {
217 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
218 
219 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
220 	{
221 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
222 			return (deUint32)queueNdx;
223 	}
224 
225 	TCU_THROW(NotSupportedError, "No matching queue found");
226 }
227 
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)228 Move<VkDevice> createDefaultDevice (const PlatformInterface&			vkp,
229 									VkInstance							instance,
230 									const InstanceInterface&			vki,
231 									VkPhysicalDevice					physicalDevice,
232 									const deUint32						apiVersion,
233 									deUint32							queueIndex,
234 									deUint32							sparseQueueIndex,
235 									const VkPhysicalDeviceFeatures2&	enabledFeatures,
236 									const vector<string>&				enabledExtensions,
237 									const tcu::CommandLine&				cmdLine)
238 {
239 	VkDeviceQueueCreateInfo		queueInfo[2];
240 	VkDeviceCreateInfo			deviceInfo;
241 	vector<const char*>			enabledLayers;
242 	vector<const char*>			extensionPtrs;
243 	const float					queuePriority	= 1.0f;
244 	const deUint32				numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
245 
246 	deMemset(&queueInfo,	0, sizeof(queueInfo));
247 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
248 
249 	if (cmdLine.isValidationEnabled())
250 	{
251 		enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
252 		if (enabledLayers.empty())
253 			TCU_THROW(NotSupportedError, "No validation layers found");
254 	}
255 
256 	// \note Extensions in core are not explicitly enabled even though
257 	//		 they are in the extension list advertised to tests.
258 	vector<const char*> coreExtensions;
259 	getCoreDeviceExtensions(apiVersion, coreExtensions);
260 	vector<string>	nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
261 
262 	extensionPtrs.resize(nonCoreExtensions.size());
263 
264 	for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
265 		extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
266 
267 	queueInfo[0].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
268 	queueInfo[0].pNext						= DE_NULL;
269 	queueInfo[0].flags						= (VkDeviceQueueCreateFlags)0u;
270 	queueInfo[0].queueFamilyIndex			= queueIndex;
271 	queueInfo[0].queueCount					= 1u;
272 	queueInfo[0].pQueuePriorities			= &queuePriority;
273 
274 	if (numQueues > 1)
275 	{
276 		queueInfo[1].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
277 		queueInfo[1].pNext						= DE_NULL;
278 		queueInfo[1].flags						= (VkDeviceQueueCreateFlags)0u;
279 		queueInfo[1].queueFamilyIndex			= sparseQueueIndex;
280 		queueInfo[1].queueCount					= 1u;
281 		queueInfo[1].pQueuePriorities			= &queuePriority;
282 	}
283 
284 	// VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
285 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
286 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
287 	deviceInfo.queueCreateInfoCount			= numQueues;
288 	deviceInfo.pQueueCreateInfos			= queueInfo;
289 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
290 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
291 	deviceInfo.enabledLayerCount			= (deUint32)enabledLayers.size();
292 	deviceInfo.ppEnabledLayerNames			= (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
293 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
294 
295 	return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
296 }
297 
298 } // anonymous
299 
300 class DefaultDevice
301 {
302 public:
303 																	DefaultDevice							(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
304 																	~DefaultDevice							(void);
305 
getInstance(void) const306 	VkInstance														getInstance								(void) const { return *m_instance;											}
getInstanceInterface(void) const307 	const InstanceInterface&										getInstanceInterface					(void) const { return m_instanceInterface;									}
getMaximumFrameworkVulkanVersion(void) const308 	deUint32														getMaximumFrameworkVulkanVersion		(void) const { return m_maximumFrameworkVulkanVersion;						}
getAvailableInstanceVersion(void) const309 	deUint32														getAvailableInstanceVersion				(void) const { return m_availableInstanceVersion;							}
getUsedInstanceVersion(void) const310 	deUint32														getUsedInstanceVersion					(void) const { return m_usedInstanceVersion;								}
getInstanceExtensions(void) const311 	const vector<string>&											getInstanceExtensions					(void) const { return m_instanceExtensions;									}
312 
getPhysicalDevice(void) const313 	VkPhysicalDevice												getPhysicalDevice						(void) const { return m_physicalDevice;										}
getDeviceVersion(void) const314 	deUint32														getDeviceVersion						(void) const { return m_deviceVersion;										}
315 
isDeviceFeatureInitialized(VkStructureType sType) const316 	bool															isDeviceFeatureInitialized				(VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);		}
getDeviceFeatures(void) const317 	const VkPhysicalDeviceFeatures&									getDeviceFeatures						(void) const { return m_deviceFeatures.getCoreFeatures2().features;			}
getDeviceFeatures2(void) const318 	const VkPhysicalDeviceFeatures2&								getDeviceFeatures2						(void) const { return m_deviceFeatures.getCoreFeatures2();					}
getVulkan11Features(void) const319 	const VkPhysicalDeviceVulkan11Features&							getVulkan11Features						(void) const { return m_deviceFeatures.getVulkan11Features();				}
getVulkan12Features(void) const320 	const VkPhysicalDeviceVulkan12Features&							getVulkan12Features						(void) const { return m_deviceFeatures.getVulkan12Features();				}
getVulkan13Features(void) const321 	const VkPhysicalDeviceVulkan13Features&							getVulkan13Features						(void) const { return m_deviceFeatures.getVulkan13Features();				}
322 
323 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
324 
isDevicePropertyInitialized(VkStructureType sType) const325 	bool															isDevicePropertyInitialized				(VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType);	}
getDeviceProperties(void) const326 	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties.getCoreProperties2().properties;	}
getDeviceProperties2(void) const327 	const VkPhysicalDeviceProperties2&								getDeviceProperties2					(void) const { return m_deviceProperties.getCoreProperties2();				}
getDeviceVulkan11Properties(void) const328 	const VkPhysicalDeviceVulkan11Properties&						getDeviceVulkan11Properties				(void) const { return m_deviceProperties.getVulkan11Properties();			}
getDeviceVulkan12Properties(void) const329 	const VkPhysicalDeviceVulkan12Properties&						getDeviceVulkan12Properties				(void) const { return m_deviceProperties.getVulkan12Properties();			}
getDeviceVulkan13Properties(void) const330 	const VkPhysicalDeviceVulkan13Properties&						getDeviceVulkan13Properties				(void) const { return m_deviceProperties.getVulkan13Properties();			}
331 
332 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
333 
getDevice(void) const334 	VkDevice														getDevice								(void) const { return *m_device;											}
getDeviceInterface(void) const335 	const DeviceInterface&											getDeviceInterface						(void) const { return m_deviceInterface;									}
getDeviceExtensions(void) const336 	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;									}
getUsedApiVersion(void) const337 	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;										}
getUniversalQueueFamilyIndex(void) const338 	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;							}
339 	VkQueue															getUniversalQueue						(void) const;
getSparseQueueFamilyIndex(void) const340 	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;								}
341 	VkQueue															getSparseQueue							(void) const;
342 
hasDebugReportRecorder(void) const343 	bool															hasDebugReportRecorder					(void) const { return m_debugReportRecorder.get() != nullptr;				}
getDebugReportRecorder(void) const344 	vk::DebugReportRecorder&										getDebugReportRecorder					(void) const { return *m_debugReportRecorder.get();							}
345 
346 private:
347 	using DebugReportRecorderPtr		= de::UniquePtr<vk::DebugReportRecorder>;
348 	using DebugReportCallbackPtr		= vk::Move<VkDebugReportCallbackEXT>;
349 
350 	const deUint32						m_maximumFrameworkVulkanVersion;
351 	const deUint32						m_availableInstanceVersion;
352 	const deUint32						m_usedInstanceVersion;
353 
354 	const std::pair<deUint32, deUint32> m_deviceVersions;
355 	const deUint32						m_usedApiVersion;
356 
357 	const DebugReportRecorderPtr		m_debugReportRecorder;
358 	const vector<string>				m_instanceExtensions;
359 	const Unique<VkInstance>			m_instance;
360 	const InstanceDriver				m_instanceInterface;
361 	const DebugReportCallbackPtr		m_debugReportCallback;
362 
363 	const VkPhysicalDevice				m_physicalDevice;
364 	const deUint32						m_deviceVersion;
365 
366 	const vector<string>				m_deviceExtensions;
367 	const DeviceFeatures				m_deviceFeatures;
368 
369 	const deUint32						m_universalQueueFamilyIndex;
370 	const deUint32						m_sparseQueueFamilyIndex;
371 	const DeviceProperties				m_deviceProperties;
372 
373 	const Unique<VkDevice>				m_device;
374 	const DeviceDriver					m_deviceInterface;
375 };
376 
377 namespace
378 {
379 
sanitizeApiVersion(deUint32 v)380 deUint32 sanitizeApiVersion(deUint32 v)
381 {
382 	return VK_MAKE_VERSION(VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
383 }
384 
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)385 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, bool printValidationErrors)
386 {
387 	if (isDebugReportSupported(vkp))
388 		return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
389 	else
390 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
391 }
392 
393 } // anonymous
394 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)395 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
396 	: m_maximumFrameworkVulkanVersion	(VK_API_MAX_FRAMEWORK_VERSION)
397 	, m_availableInstanceVersion		(getTargetInstanceVersion(vkPlatform))
398 	, m_usedInstanceVersion				(sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
399 	, m_deviceVersions					(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
400 	, m_usedApiVersion					(sanitizeApiVersion(deMinu32(m_usedInstanceVersion, m_deviceVersions.first)))
401 
402 	, m_debugReportRecorder				(cmdLine.isValidationEnabled()
403 										 ? createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors())
404 										 : de::MovePtr<vk::DebugReportRecorder>())
405 	, m_instanceExtensions				(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
406 	, m_instance						(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, m_debugReportRecorder.get()))
407 
408 	, m_instanceInterface				(vkPlatform, *m_instance)
409 	, m_debugReportCallback				(cmdLine.isValidationEnabled()
410 										 ? m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get())
411 										 : DebugReportCallbackPtr())
412 	, m_physicalDevice					(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
413 	, m_deviceVersion					(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
414 
415 	, m_deviceExtensions				(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
416 	, m_deviceFeatures					(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
417 	, m_universalQueueFamilyIndex		(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
418 	, m_sparseQueueFamilyIndex			(m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
419 	, m_deviceProperties				(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
420 	, m_device							(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
421 	, m_deviceInterface					(vkPlatform, *m_instance, *m_device)
422 {
423 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
424 }
425 
~DefaultDevice(void)426 DefaultDevice::~DefaultDevice (void)
427 {
428 }
429 
getUniversalQueue(void) const430 VkQueue DefaultDevice::getUniversalQueue (void) const
431 {
432 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
433 }
434 
getSparseQueue(void) const435 VkQueue DefaultDevice::getSparseQueue (void) const
436 {
437 	if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
438 		TCU_THROW(NotSupportedError, "Sparse binding not supported.");
439 
440 	return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
441 }
442 
443 namespace
444 {
445 // Allocator utilities
446 
createAllocator(DefaultDevice * device)447 vk::Allocator* createAllocator (DefaultDevice* device)
448 {
449 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
450 
451 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
452 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
453 }
454 
455 } // anonymous
456 
457 // Context
458 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection)459 Context::Context (tcu::TestContext&				testCtx,
460 				  const vk::PlatformInterface&	platformInterface,
461 				  vk::BinaryCollection&			progCollection)
462 	: m_testCtx					(testCtx)
463 	, m_platformInterface		(platformInterface)
464 	, m_progCollection			(progCollection)
465 	, m_device					(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
466 	, m_allocator				(createAllocator(m_device.get()))
467 	, m_resultSetOnValidation	(false)
468 {
469 }
470 
~Context(void)471 Context::~Context (void)
472 {
473 }
474 
getMaximumFrameworkVulkanVersion(void) const475 deUint32										Context::getMaximumFrameworkVulkanVersion		(void) const { return m_device->getMaximumFrameworkVulkanVersion();			}
getAvailableInstanceVersion(void) const476 deUint32										Context::getAvailableInstanceVersion			(void) const { return m_device->getAvailableInstanceVersion();				}
getInstanceExtensions(void) const477 const vector<string>&							Context::getInstanceExtensions					(void) const { return m_device->getInstanceExtensions();					}
getInstance(void) const478 vk::VkInstance									Context::getInstance							(void) const { return m_device->getInstance();								}
getInstanceInterface(void) const479 const vk::InstanceInterface&					Context::getInstanceInterface					(void) const { return m_device->getInstanceInterface();						}
getPhysicalDevice(void) const480 vk::VkPhysicalDevice							Context::getPhysicalDevice						(void) const { return m_device->getPhysicalDevice();						}
getDeviceVersion(void) const481 deUint32										Context::getDeviceVersion						(void) const { return m_device->getDeviceVersion();							}
getDeviceFeatures(void) const482 const vk::VkPhysicalDeviceFeatures&				Context::getDeviceFeatures						(void) const { return m_device->getDeviceFeatures();						}
getDeviceFeatures2(void) const483 const vk::VkPhysicalDeviceFeatures2&			Context::getDeviceFeatures2						(void) const { return m_device->getDeviceFeatures2();						}
getDeviceVulkan11Features(void) const484 const vk::VkPhysicalDeviceVulkan11Features&		Context::getDeviceVulkan11Features				(void) const { return m_device->getVulkan11Features();						}
getDeviceVulkan12Features(void) const485 const vk::VkPhysicalDeviceVulkan12Features&		Context::getDeviceVulkan12Features				(void) const { return m_device->getVulkan12Features();						}
getDeviceVulkan13Features(void) const486 const vk::VkPhysicalDeviceVulkan13Features&		Context::getDeviceVulkan13Features				(void) const { return m_device->getVulkan13Features();						}
487 
isDeviceFunctionalitySupported(const std::string & extension) const488 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
489 {
490 	// check if extension was promoted to core
491 	deUint32 apiVersion = getUsedApiVersion();
492 	if (isCoreDeviceExtension(apiVersion, extension))
493 	{
494 		if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
495 		{
496 			// Check feature bits in extension-specific structures.
497 			if (extension == "VK_KHR_multiview")
498 				return !!m_device->getMultiviewFeatures().multiview;
499 			if (extension == "VK_KHR_variable_pointers")
500 				return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
501 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
502 				return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
503 			if (extension == "VK_KHR_shader_draw_parameters")
504 				return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
505 		}
506 		else
507 		{
508 			// Check feature bits using the new Vulkan 1.2 structures.
509 			const auto& vk11Features = m_device->getVulkan11Features();
510 			if (extension == "VK_KHR_multiview")
511 				return !!vk11Features.multiview;
512 			if (extension == "VK_KHR_variable_pointers")
513 				return !!vk11Features.variablePointersStorageBuffer;
514 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
515 				return !!vk11Features.samplerYcbcrConversion;
516 			if (extension == "VK_KHR_shader_draw_parameters")
517 				return !!vk11Features.shaderDrawParameters;
518 
519 			const auto& vk12Features = m_device->getVulkan12Features();
520 			if (extension == "VK_KHR_timeline_semaphore")
521 				return !!vk12Features.timelineSemaphore;
522 			if (extension == "VK_KHR_buffer_device_address")
523 				return !!vk12Features.bufferDeviceAddress;
524 			if (extension == "VK_EXT_descriptor_indexing")
525 				return !!vk12Features.descriptorIndexing;
526 			if (extension == "VK_KHR_draw_indirect_count")
527 				return !!vk12Features.drawIndirectCount;
528 			if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
529 				return !!vk12Features.samplerMirrorClampToEdge;
530 			if (extension == "VK_EXT_sampler_filter_minmax")
531 				return !!vk12Features.samplerFilterMinmax;
532 			if (extension == "VK_EXT_shader_viewport_index_layer")
533 				return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
534 
535 			const auto& vk13Features = m_device->getVulkan13Features();
536 			if (extension == "VK_EXT_inline_uniform_block")
537 				return !!vk13Features.inlineUniformBlock;
538 			if (extension == "VK_EXT_pipeline_creation_cache_control")
539 				return !!vk13Features.pipelineCreationCacheControl;
540 			if (extension == "VK_EXT_private_data")
541 				return !!vk13Features.privateData;
542 			if (extension == "VK_EXT_shader_demote_to_helper_invocation")
543 				return !!vk13Features.shaderDemoteToHelperInvocation;
544 			if (extension == "VK_KHR_shader_terminate_invocation")
545 				return !!vk13Features.shaderTerminateInvocation;
546 			if (extension == "VK_EXT_subgroup_size_control")
547 				return !!vk13Features.subgroupSizeControl;
548 			if (extension == "VK_KHR_synchronization2")
549 				return !!vk13Features.synchronization2;
550 			if (extension == "VK_EXT_texture_compression_astc_hdr")
551 				return !!vk13Features.textureCompressionASTC_HDR;
552 			if (extension == "VK_KHR_zero_initialize_workgroup_memory")
553 				return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
554 			if (extension == "VK_KHR_dynamic_rendering")
555 				return !!vk13Features.dynamicRendering;
556 			if (extension == "VK_KHR_shader_integer_dot_product")
557 				return !!vk13Features.shaderIntegerDotProduct;
558 			if (extension == "VK_KHR_maintenance4")
559 				return !!vk13Features.maintenance4;
560 		}
561 
562 		// No feature flags to check.
563 		return true;
564 	}
565 
566 	// check if extension is on the list of extensions for current device
567 	const auto& extensions = getDeviceExtensions();
568 	if (de::contains(extensions.begin(), extensions.end(), extension))
569 	{
570 		if (extension == "VK_KHR_timeline_semaphore")
571 			return !!getTimelineSemaphoreFeatures().timelineSemaphore;
572 		if (extension == "VK_KHR_synchronization2")
573 			return !!getSynchronization2Features().synchronization2;
574 		if (extension == "VK_EXT_extended_dynamic_state")
575 			return !!getExtendedDynamicStateFeaturesEXT().extendedDynamicState;
576 		if (extension == "VK_EXT_shader_demote_to_helper_invocation")
577 			return !!getShaderDemoteToHelperInvocationFeatures().shaderDemoteToHelperInvocation;
578 		if (extension == "VK_KHR_workgroup_memory_explicit_layout")
579 			return !!getWorkgroupMemoryExplicitLayoutFeatures().workgroupMemoryExplicitLayout;
580 
581 		return true;
582 	}
583 
584 	return false;
585 }
586 
isInstanceFunctionalitySupported(const std::string & extension) const587 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
588 {
589 	// NOTE: current implementation uses isInstanceExtensionSupported but
590 	// this will change when some instance extensions will be promoted to the
591 	// core; don't use isInstanceExtensionSupported directly, use this method instead
592 	return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
593 }
594 
595 #include "vkDeviceFeaturesForContextDefs.inl"
596 
getDeviceProperties(void) const597 const vk::VkPhysicalDeviceProperties&			Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();			}
getDeviceProperties2(void) const598 const vk::VkPhysicalDeviceProperties2&			Context::getDeviceProperties2				(void) const { return m_device->getDeviceProperties2();			}
getDeviceVulkan11Properties(void) const599 const vk::VkPhysicalDeviceVulkan11Properties&	Context::getDeviceVulkan11Properties		(void) const { return m_device->getDeviceVulkan11Properties();	}
getDeviceVulkan12Properties(void) const600 const vk::VkPhysicalDeviceVulkan12Properties&	Context::getDeviceVulkan12Properties		(void) const { return m_device->getDeviceVulkan12Properties();	}
getDeviceVulkan13Properties(void) const601 const vk::VkPhysicalDeviceVulkan13Properties&	Context::getDeviceVulkan13Properties		(void) const { return m_device->getDeviceVulkan13Properties();	}
602 
603 #include "vkDevicePropertiesForContextDefs.inl"
604 
getDeviceExtensions(void) const605 const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();			}
getDevice(void) const606 vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const607 const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const608 deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const609 vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();			}
getSparseQueueFamilyIndex(void) const610 deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();	}
getSparseQueue(void) const611 vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();				}
getDefaultAllocator(void) const612 vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;								}
getUsedApiVersion(void) const613 deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();			}
contextSupports(const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const614 bool									Context::contextSupports					(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
615 																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
contextSupports(const ApiVersion version) const616 bool									Context::contextSupports					(const ApiVersion version) const
617 																							{ return m_device->getUsedApiVersion() >= pack(version); }
contextSupports(const deUint32 requiredApiVersionBits) const618 bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
619 																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
isDeviceFeatureInitialized(vk::VkStructureType sType) const620 bool									Context::isDeviceFeatureInitialized			(vk::VkStructureType sType) const
621 																							{ return m_device->isDeviceFeatureInitialized(sType);	}
isDevicePropertyInitialized(vk::VkStructureType sType) const622 bool									Context::isDevicePropertyInitialized		(vk::VkStructureType sType) const
623 																							{ return m_device->isDevicePropertyInitialized(sType);	}
624 
requireDeviceFunctionality(const std::string & required) const625 bool Context::requireDeviceFunctionality (const std::string& required) const
626 {
627 	if (!isDeviceFunctionalitySupported(required))
628 		TCU_THROW(NotSupportedError, required + " is not supported");
629 
630 	return true;
631 }
632 
requireInstanceFunctionality(const std::string & required) const633 bool Context::requireInstanceFunctionality (const std::string& required) const
634 {
635 	if (!isInstanceFunctionalitySupported(required))
636 		TCU_THROW(NotSupportedError, required + " is not supported");
637 
638 	return true;
639 }
640 
641 struct DeviceCoreFeaturesTable
642 {
643 	const char*		featureName;
644 	const deUint32	featureArrayIndex;
645 	const deUint32	featureArrayOffset;
646 };
647 
648 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
649 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)	{ #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
650 
651 const DeviceCoreFeaturesTable	deviceCoreFeaturesTable[] =
652 {
653 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS							,	robustBufferAccess						),
654 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32						,	fullDrawIndexUint32						),
655 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY								,	imageCubeArray							),
656 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND								,	independentBlend						),
657 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER								,	geometryShader							),
658 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER							,	tessellationShader						),
659 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING							,	sampleRateShading						),
660 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND								,	dualSrcBlend							),
661 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP										,	logicOp									),
662 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT							,	multiDrawIndirect						),
663 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE					,	drawIndirectFirstInstance				),
664 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP									,	depthClamp								),
665 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP								,	depthBiasClamp							),
666 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID							,	fillModeNonSolid						),
667 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS									,	depthBounds								),
668 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES									,	wideLines								),
669 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS									,	largePoints								),
670 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE									,	alphaToOne								),
671 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT								,	multiViewport							),
672 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY							,	samplerAnisotropy						),
673 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2						,	textureCompressionETC2					),
674 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR					,	textureCompressionASTC_LDR				),
675 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC						,	textureCompressionBC					),
676 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE						,	occlusionQueryPrecise					),
677 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY						,	pipelineStatisticsQuery					),
678 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			,	vertexPipelineStoresAndAtomics			),
679 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS					,	fragmentStoresAndAtomics				),
680 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	,	shaderTessellationAndGeometryPointSize	),
681 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED					,	shaderImageGatherExtended				),
682 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS			,	shaderStorageImageExtendedFormats		),
683 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE				,	shaderStorageImageMultisample			),
684 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT		,	shaderStorageImageReadWithoutFormat		),
685 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT		,	shaderStorageImageWriteWithoutFormat	),
686 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderUniformBufferArrayDynamicIndexing	),
687 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderSampledImageArrayDynamicIndexing	),
688 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderStorageBufferArrayDynamicIndexing	),
689 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderStorageImageArrayDynamicIndexing	),
690 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE							,	shaderClipDistance						),
691 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE							,	shaderCullDistance						),
692 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64								,	shaderFloat64							),
693 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64									,	shaderInt64								),
694 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16									,	shaderInt16								),
695 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY						,	shaderResourceResidency					),
696 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD						,	shaderResourceMinLod					),
697 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING								,	sparseBinding							),
698 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER						,	sparseResidencyBuffer					),
699 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D						,	sparseResidencyImage2D					),
700 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D						,	sparseResidencyImage3D					),
701 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES						,	sparseResidency2Samples					),
702 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES						,	sparseResidency4Samples					),
703 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES						,	sparseResidency8Samples					),
704 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES					,	sparseResidency16Samples				),
705 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED						,	sparseResidencyAliased					),
706 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE						,	variableMultisampleRate					),
707 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES								,	inheritedQueries						),
708 };
709 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)710 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
711 {
712 	const vk::VkPhysicalDeviceFeatures& featuresAvailable		= getDeviceFeatures();
713 	const vk::VkBool32*					featuresAvailableArray	= (vk::VkBool32*)(&featuresAvailable);
714 	const deUint32						requiredFeatureIndex	= static_cast<deUint32>(requiredFeature);
715 
716 	DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
717 	DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
718 
719 	if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
720 		TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
721 
722 	return true;
723 }
724 
isExtendedStorageFormat(VkFormat format)725 static bool isExtendedStorageFormat (VkFormat format)
726 {
727 	switch(format)
728 	{
729 		case VK_FORMAT_R8G8B8A8_UNORM:
730 		case VK_FORMAT_R8G8B8A8_SNORM:
731 		case VK_FORMAT_R8G8B8A8_UINT:
732 		case VK_FORMAT_R8G8B8A8_SINT:
733 		case VK_FORMAT_R32_UINT:
734 		case VK_FORMAT_R32_SINT:
735 		case VK_FORMAT_R32_SFLOAT:
736 		case VK_FORMAT_R32G32_UINT:
737 		case VK_FORMAT_R32G32_SINT:
738 		case VK_FORMAT_R32G32_SFLOAT:
739 		case VK_FORMAT_R32G32B32A32_UINT:
740 		case VK_FORMAT_R32G32B32A32_SINT:
741 		case VK_FORMAT_R32G32B32A32_SFLOAT:
742 		case VK_FORMAT_R16G16B16A16_UINT:
743 		case VK_FORMAT_R16G16B16A16_SINT:
744 		case VK_FORMAT_R16G16B16A16_SFLOAT:
745 		case VK_FORMAT_R16G16_SFLOAT:
746 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
747 		case VK_FORMAT_R16_SFLOAT:
748 		case VK_FORMAT_R16G16B16A16_UNORM:
749 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
750 		case VK_FORMAT_R16G16_UNORM:
751 		case VK_FORMAT_R8G8_UNORM:
752 		case VK_FORMAT_R16_UNORM:
753 		case VK_FORMAT_R8_UNORM:
754 		case VK_FORMAT_R16G16B16A16_SNORM:
755 		case VK_FORMAT_R16G16_SNORM:
756 		case VK_FORMAT_R8G8_SNORM:
757 		case VK_FORMAT_R16_SNORM:
758 		case VK_FORMAT_R8_SNORM:
759 		case VK_FORMAT_R16G16_SINT:
760 		case VK_FORMAT_R8G8_SINT:
761 		case VK_FORMAT_R16_SINT:
762 		case VK_FORMAT_R8_SINT:
763 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
764 		case VK_FORMAT_R16G16_UINT:
765 		case VK_FORMAT_R8G8_UINT:
766 		case VK_FORMAT_R16_UINT:
767 		case VK_FORMAT_R8_UINT:
768 			return true;
769 		default:
770 			return false;
771 	}
772 }
773 
isDepthFormat(VkFormat format)774 static bool isDepthFormat (VkFormat format)
775 {
776 	switch(format)
777 	{
778 		case VK_FORMAT_D16_UNORM:
779 		case VK_FORMAT_X8_D24_UNORM_PACK32:
780 		case VK_FORMAT_D32_SFLOAT:
781 		case VK_FORMAT_D16_UNORM_S8_UINT:
782 		case VK_FORMAT_D24_UNORM_S8_UINT:
783 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
784 			return true;
785 		default:
786 			return false;
787 	}
788 }
789 
getRequiredFormatProperties(const vk::VkFormat & format) const790 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat& format) const
791 {
792 	vk::VkFormatProperties3 p;
793 	p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
794 	p.pNext = DE_NULL;
795 
796 	vk::VkFormatProperties properties;
797 	getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
798 	p.linearTilingFeatures	= properties.linearTilingFeatures;
799 	p.optimalTilingFeatures	= properties.optimalTilingFeatures;
800 	p.bufferFeatures		= properties.bufferFeatures;
801 
802 	const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
803 	if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
804 	{
805 		if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
806 			p.linearTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
807 		if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
808 			p.optimalTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
809 	}
810 	if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
811 	{
812 		if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
813 			p.linearTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
814 		if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
815 			p.optimalTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
816 	}
817 	if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
818 		p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
819 	if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
820 		p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
821 
822 	return p;
823 }
824 
getFormatProperties(const vk::VkFormat & format) const825 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat& format) const
826 {
827 	if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
828 	{
829 		vk::VkFormatProperties3 p;
830 		p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
831 		p.pNext = DE_NULL;
832 
833 		vk::VkFormatProperties2 properties;
834 		properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
835 		properties.pNext = &p;
836 
837 		getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
838 		return p;
839 	}
840 	else
841 		return Context::getRequiredFormatProperties(format);
842 }
843 
getInstanceProcAddr()844 void* Context::getInstanceProcAddr	()
845 {
846 	return (void*)m_platformInterface.getGetInstanceProcAddr();
847 }
848 
isBufferDeviceAddressSupported(void) const849 bool Context::isBufferDeviceAddressSupported(void) const
850 {
851 	return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
852 		   isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
853 }
854 
hasDebugReportRecorder() const855 bool Context::hasDebugReportRecorder () const
856 {
857 	return m_device->hasDebugReportRecorder();
858 }
859 
getDebugReportRecorder() const860 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
861 {
862 	return m_device->getDebugReportRecorder();
863 }
864 
865 // TestCase
866 
initPrograms(SourceCollections &) const867 void TestCase::initPrograms (SourceCollections&) const
868 {
869 }
870 
checkSupport(Context &) const871 void TestCase::checkSupport (Context&) const
872 {
873 }
874 
delayedInit(void)875 void TestCase::delayedInit (void)
876 {
877 }
878 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)879 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
880 {
881 	using DebugMessages = vk::DebugReportRecorder::MessageList;
882 
883 	const DebugMessages&	messages	= debugReportRecorder.getMessages();
884 	tcu::TestLog&			log			= context.getTestContext().getLog();
885 
886 	if (messages.size() > 0)
887 	{
888 		const tcu::ScopedLogSection	section		(log, "DebugMessages", "Debug Messages");
889 		int							numErrors	= 0;
890 
891 		for (const auto& msg : messages)
892 		{
893 			if (msg.shouldBeLogged())
894 				log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
895 
896 			if (msg.isError())
897 				numErrors += 1;
898 		}
899 
900 		debugReportRecorder.clearMessages();
901 
902 		if (numErrors > 0)
903 		{
904 			string errorMsg = de::toString(numErrors) + " API usage errors found";
905 			context.resultSetOnValidation(true);
906 			context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
907 		}
908 	}
909 }
910 
911 } // vkt
912