• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  * Copyright (c) 2023 LunarG, Inc.
7  * Copyright (c) 2023 Nintendo
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan test case base classes
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktTestCase.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkDeviceUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkDebugReportUtil.hpp"
36 #include "vkDeviceFeatures.hpp"
37 #include "vkDeviceProperties.hpp"
38 #ifdef CTS_USES_VULKANSC
39 #include "vkSafetyCriticalUtil.hpp"
40 #include "vkAppParamsUtil.hpp"
41 #endif // CTS_USES_VULKANSC
42 
43 #include "tcuCommandLine.hpp"
44 #include "tcuTestLog.hpp"
45 
46 #include "deSTLUtil.hpp"
47 #include "deMemory.h"
48 
49 #include <set>
50 #include <cstring>
51 #include <iterator>
52 #include <algorithm>
53 
54 namespace vkt
55 {
56 
57 // Default device utilities
58 
59 using std::vector;
60 using std::string;
61 using std::set;
62 using namespace vk;
63 
64 namespace
65 {
66 
filterExtensions(const vector<VkExtensionProperties> & extensions)67 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
68 {
69 	vector<string>	enabledExtensions;
70 	bool			khrBufferDeviceAddress	= false;
71 	bool			excludeExtension		= false;
72 
73 	const char*		extensionGroups[]		=
74 	{
75 		"VK_KHR_",
76 		"VK_EXT_",
77 		"VK_KHX_",
78 		"VK_OHOS_",
79 		"VK_NV_cooperative_matrix",
80 		"VK_NV_ray_tracing",
81 		"VK_NV_inherited_viewport_scissor",
82 		"VK_NV_mesh_shader",
83 		"VK_AMD_mixed_attachment_samples",
84 		"VK_AMD_buffer_marker",
85 		"VK_AMD_shader_explicit_vertex_parameter",
86 		"VK_AMD_shader_image_load_store_lod",
87 		"VK_AMD_shader_trinary_minmax",
88 		"VK_AMD_texture_gather_bias_lod",
89 		"VK_AMD_shader_early_and_late_fragment_tests",
90 		"VK_ANDROID_external_memory_android_hardware_buffer",
91 		"VK_VALVE_mutable_descriptor_type",
92 		"VK_NV_shader_subgroup_partitioned",
93 		"VK_NV_clip_space_w_scaling",
94 		"VK_NV_scissor_exclusive",
95 		"VK_NV_shading_rate_image",
96 		"VK_ARM_rasterization_order_attachment_access",
97 		"VK_GOOGLE_surfaceless_query",
98 		"VK_FUCHSIA_",
99 		"VK_NV_fragment_coverage_to_color",
100 		"VK_NV_framebuffer_mixed_samples",
101 		"VK_NV_coverage_reduction_mode",
102 		"VK_NV_viewport_swizzle",
103 		"VK_NV_representative_fragment_test",
104 	};
105 
106 	const char* exclusions[] =
107 	{
108 		"VK_EXT_device_address_binding_report",
109 		"VK_EXT_device_memory_report"
110 	};
111 
112 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
113 	{
114 		if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
115 		{
116 			khrBufferDeviceAddress = true;
117 			break;
118 		}
119 	}
120 
121 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
122 	{
123 		const auto& extName = extensions[extNdx].extensionName;
124 
125 		excludeExtension = false;
126 
127 		// VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
128 		if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
129 			continue;
130 
131 		for (int exclusionsNdx = 0; exclusionsNdx < DE_LENGTH_OF_ARRAY(exclusions); exclusionsNdx++)
132 		{
133 			if (deStringEqual(extName, exclusions[exclusionsNdx]))
134 			{
135 				excludeExtension = true;
136 				break;
137 			}
138 		}
139 
140 		if (excludeExtension)
141 			continue;
142 
143 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
144 		{
145 			if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
146 				enabledExtensions.push_back(extName);
147 		}
148 	}
149 
150 	return enabledExtensions;
151 }
152 
addExtensions(const vector<string> & a,const vector<const char * > & b)153 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
154 {
155 	vector<string>	res		(a);
156 
157 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
158 	{
159 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
160 			res.push_back(string(*bIter));
161 	}
162 
163 	return res;
164 }
165 
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)166 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
167 {
168 	vector<const char*> coreExtensions;
169 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
170 	return addExtensions(extensions, coreExtensions);
171 }
172 
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)173 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
174 {
175 	vector<const char*> coreExtensions;
176 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
177 	return addExtensions(extensions, coreExtensions);
178 }
179 
getTargetInstanceVersion(const PlatformInterface & vkp)180 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
181 {
182 	deUint32 version = pack(ApiVersion(0, 1, 0, 0));
183 
184 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
185 		TCU_THROW(InternalError, "Enumerate instance version error");
186 #ifdef CTS_USES_VULKANSC
187 	// Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
188 	version = pack(ApiVersion(1, 1, 0, 0));
189 #endif
190 	return version;
191 }
192 
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)193 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
194 {
195 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion, cmdLine);
196 	InstanceDriver							preinterface			(vkp, preinstance.get());
197 
198 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
199 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
200 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
201 	{
202 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
203 		if (props.apiVersion < lowestDeviceVersion)
204 			lowestDeviceVersion = props.apiVersion;
205 	}
206 
207 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
208 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
209 	const deUint32							choosenDeviceVersion	= props.apiVersion;
210 
211 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
212 }
213 
214 // Remove extensions from a which are found in b.
removeExtensions(const vector<string> & a,const vector<const char * > & b)215 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
216 {
217 	vector<string>	res;
218 	set<string>		removeExts	(b.begin(), b.end());
219 
220 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
221 	{
222 		if (!de::contains(removeExts, *aIter))
223 			res.push_back(*aIter);
224 	}
225 
226 	return res;
227 }
228 
229 #ifndef CTS_USES_VULKANSC
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder)230 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine, DebugReportRecorder* recorder)
231 #else
232 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
233 #endif // CTS_USES_VULKANSC
234 {
235 #ifndef CTS_USES_VULKANSC
236 	const bool			isValidationEnabled	= (recorder != nullptr);
237 #else
238 	const bool			isValidationEnabled = false;
239 #endif // CTS_USES_VULKANSC
240 	vector<const char*>	enabledLayers;
241 
242 	// \note Extensions in core are not explicitly enabled even though
243 	//		 they are in the extension list advertised to tests.
244 	vector<const char*> coreExtensions;
245 	getCoreInstanceExtensions(apiVersion, coreExtensions);
246 	const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
247 
248 	if (isValidationEnabled)
249 	{
250 		if (!isDebugReportSupported(vkp))
251 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
252 
253 		enabledLayers = vkt::getValidationLayers(vkp);
254 		if (enabledLayers.empty())
255 			TCU_THROW(NotSupportedError, "No validation layers found");
256 	}
257 
258 #ifndef CTS_USES_VULKANSC
259 	return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine, recorder);
260 #else
261 	return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine);
262 #endif // CTS_USES_VULKANSC
263 }
264 
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueIndex,deUint32 sparseQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<const char * > & usedExtensions,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)265 Move<VkDevice> createDefaultDevice (const PlatformInterface&				vkp,
266 									VkInstance								instance,
267 									const InstanceInterface&				vki,
268 									VkPhysicalDevice						physicalDevice,
269 									deUint32								queueIndex,
270 									deUint32								sparseQueueIndex,
271 									const VkPhysicalDeviceFeatures2&		enabledFeatures,
272 									const vector<const char*>&				usedExtensions,
273 									const tcu::CommandLine&					cmdLine,
274 									de::SharedPtr<vk::ResourceInterface>	resourceInterface)
275 {
276 	VkDeviceQueueCreateInfo		queueInfo[2];
277 	VkDeviceCreateInfo			deviceInfo;
278 	vector<const char*>			enabledLayers;
279 	const float					queuePriority	= 1.0f;
280 	const deUint32				numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
281 
282 	deMemset(&queueInfo,	0, sizeof(queueInfo));
283 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
284 
285 	if (cmdLine.isValidationEnabled())
286 	{
287 		enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
288 		if (enabledLayers.empty())
289 			TCU_THROW(NotSupportedError, "No validation layers found");
290 	}
291 
292 	queueInfo[0].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
293 	queueInfo[0].pNext						= DE_NULL;
294 	queueInfo[0].flags						= (VkDeviceQueueCreateFlags)0u;
295 	queueInfo[0].queueFamilyIndex			= queueIndex;
296 	queueInfo[0].queueCount					= 1u;
297 	queueInfo[0].pQueuePriorities			= &queuePriority;
298 
299 	if (numQueues > 1)
300 	{
301 		queueInfo[1].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
302 		queueInfo[1].pNext						= DE_NULL;
303 		queueInfo[1].flags						= (VkDeviceQueueCreateFlags)0u;
304 		queueInfo[1].queueFamilyIndex			= sparseQueueIndex;
305 		queueInfo[1].queueCount					= 1u;
306 		queueInfo[1].pQueuePriorities			= &queuePriority;
307 	}
308 
309 	// VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
310 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
311 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : nullptr;
312 	deviceInfo.queueCreateInfoCount			= numQueues;
313 	deviceInfo.pQueueCreateInfos			= queueInfo;
314 	deviceInfo.enabledExtensionCount		= de::sizeU32(usedExtensions);
315 	deviceInfo.ppEnabledExtensionNames		= de::dataOrNull(usedExtensions);
316 	deviceInfo.enabledLayerCount			= de::sizeU32(enabledLayers);
317 	deviceInfo.ppEnabledLayerNames			= de::dataOrNull(enabledLayers);
318 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? nullptr : &enabledFeatures.features;
319 
320 #ifdef CTS_USES_VULKANSC
321 	// devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
322 	VkDeviceObjectReservationCreateInfo	dmrCI	= resetDeviceObjectReservationCreateInfo();
323 	VkPipelineCacheCreateInfo			pcCI	=
324 	{
325 		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,				// VkStructureType				sType;
326 		DE_NULL,													// const void*					pNext;
327 		VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
328 			VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
329 		0U,															// deUintptr					initialDataSize;
330 		DE_NULL														// const void*					pInitialData;
331 	};
332 
333 	std::vector<VkPipelinePoolSize> poolSizes;
334 	if (cmdLine.isSubProcess())
335 	{
336 		resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, queueIndex);
337 
338 		dmrCI									= resourceInterface->getStatMax();
339 
340 		if(resourceInterface->getCacheDataSize() > 0)
341 		{
342 			pcCI.initialDataSize				= resourceInterface->getCacheDataSize();
343 			pcCI.pInitialData					= resourceInterface->getCacheData();
344 			dmrCI.pipelineCacheCreateInfoCount	= 1;
345 			dmrCI.pPipelineCacheCreateInfos		= &pcCI;
346 		}
347 
348 		poolSizes								= resourceInterface->getPipelinePoolSizes();
349 		if (!poolSizes.empty())
350 		{
351 			dmrCI.pipelinePoolSizeCount			= deUint32(poolSizes.size());
352 			dmrCI.pPipelinePoolSizes			= poolSizes.data();
353 		}
354 	}
355 
356 	dmrCI.pNext										= deviceInfo.pNext;
357 	VkPhysicalDeviceVulkanSC10Features sc10Features	= createDefaultSC10Features();
358 	if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
359 	{
360 		sc10Features.pNext = &dmrCI;
361 		deviceInfo.pNext = &sc10Features;
362 	}
363 	else
364 		deviceInfo.pNext = &dmrCI;
365 
366 	vector<VkApplicationParametersEXT> appParams;
367 	if (readApplicationParameters(appParams, cmdLine, false))
368 	{
369 		appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
370 		deviceInfo.pNext = &appParams[0];
371 	}
372 
373 	VkFaultCallbackInfo					faultCallbackInfo		=
374 	{
375 		VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO,					//	VkStructureType				sType;
376 		DE_NULL,												//	void*						pNext;
377 		0U,														//	uint32_t					faultCount;
378 		nullptr,												//	VkFaultData*				pFaults;
379 		Context::faultCallbackFunction							//	PFN_vkFaultCallbackFunction	pfnFaultCallback;
380 	};
381 
382 	if (cmdLine.isSubProcess())
383 	{
384 		// XXX workaround incorrect constness on faultCallbackInfo.pNext.
385 		faultCallbackInfo.pNext = const_cast<void *>(deviceInfo.pNext);
386 		deviceInfo.pNext = &faultCallbackInfo;
387 	}
388 
389 #else
390 	DE_UNREF(resourceInterface);
391 #endif // CTS_USES_VULKANSC
392 
393 	return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
394 }
395 
396 } // anonymous
397 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)398 deUint32 findQueueFamilyIndexWithCaps(const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
399 {
400 	const vector<VkQueueFamilyProperties>	queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
401 
402 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
403 	{
404 		deUint32 queueFlags = queueProps[queueNdx].queueFlags;
405 		if ((queueFlags & requiredCaps) == requiredCaps && !(queueFlags & excludedCaps))
406 			return (deUint32)queueNdx;
407 	}
408 
409 	TCU_THROW(NotSupportedError, "No matching queue found");
410 }
411 
412 class DefaultDevice
413 {
414 public:
415 																	DefaultDevice							(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface);
416 																	~DefaultDevice							(void);
417 
getInstance(void) const418 	VkInstance														getInstance								(void) const { return *m_instance;											}
getInstanceInterface(void) const419 	const InstanceInterface&										getInstanceInterface					(void) const { return m_instanceInterface;									}
getMaximumFrameworkVulkanVersion(void) const420 	deUint32														getMaximumFrameworkVulkanVersion		(void) const { return m_maximumFrameworkVulkanVersion;						}
getAvailableInstanceVersion(void) const421 	deUint32														getAvailableInstanceVersion				(void) const { return m_availableInstanceVersion;							}
getUsedInstanceVersion(void) const422 	deUint32														getUsedInstanceVersion					(void) const { return m_usedInstanceVersion;								}
getInstanceExtensions(void) const423 	const vector<string>&											getInstanceExtensions					(void) const { return m_instanceExtensions;									}
424 
getPhysicalDevice(void) const425 	VkPhysicalDevice												getPhysicalDevice						(void) const { return m_physicalDevice;										}
getDeviceVersion(void) const426 	deUint32														getDeviceVersion						(void) const { return m_deviceVersion;										}
427 
isDeviceFeatureInitialized(VkStructureType sType) const428 	bool															isDeviceFeatureInitialized				(VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);		}
getDeviceFeatures(void) const429 	const VkPhysicalDeviceFeatures&									getDeviceFeatures						(void) const { return m_deviceFeatures.getCoreFeatures2().features;			}
getDeviceFeatures2(void) const430 	const VkPhysicalDeviceFeatures2&								getDeviceFeatures2						(void) const { return m_deviceFeatures.getCoreFeatures2();					}
getVulkan11Features(void) const431 	const VkPhysicalDeviceVulkan11Features&							getVulkan11Features						(void) const { return m_deviceFeatures.getVulkan11Features();				}
getVulkan12Features(void) const432 	const VkPhysicalDeviceVulkan12Features&							getVulkan12Features						(void) const { return m_deviceFeatures.getVulkan12Features();				}
433 #ifndef CTS_USES_VULKANSC
getVulkan13Features(void) const434 	const VkPhysicalDeviceVulkan13Features&							getVulkan13Features						(void) const { return m_deviceFeatures.getVulkan13Features();				}
435 #endif // CTS_USES_VULKANSC
436 
437 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
438 
isDevicePropertyInitialized(VkStructureType sType) const439 	bool															isDevicePropertyInitialized				(VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType);	}
getDeviceProperties(void) const440 	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties.getCoreProperties2().properties;	}
getDeviceProperties2(void) const441 	const VkPhysicalDeviceProperties2&								getDeviceProperties2					(void) const { return m_deviceProperties.getCoreProperties2();				}
getDeviceVulkan11Properties(void) const442 	const VkPhysicalDeviceVulkan11Properties&						getDeviceVulkan11Properties				(void) const { return m_deviceProperties.getVulkan11Properties();			}
getDeviceVulkan12Properties(void) const443 	const VkPhysicalDeviceVulkan12Properties&						getDeviceVulkan12Properties				(void) const { return m_deviceProperties.getVulkan12Properties();			}
444 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const445 	const VkPhysicalDeviceVulkan13Properties&						getDeviceVulkan13Properties				(void) const { return m_deviceProperties.getVulkan13Properties();			}
446 #endif // CTS_USES_VULKANSC
447 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const448 	const VkPhysicalDeviceVulkanSC10Properties&						getDeviceVulkanSC10Properties			(void) const { return m_deviceProperties.getVulkanSC10Properties(); }
449 #endif // CTS_USES_VULKANSC
450 
451 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
452 
getDevice(void) const453 	VkDevice														getDevice								(void) const { return *m_device;											}
getDeviceInterface(void) const454 	const DeviceInterface&											getDeviceInterface						(void) const { return *m_deviceInterface;									}
getDeviceExtensions(void) const455 	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;									}
getDeviceCreationExtensions(void) const456 	const vector<const char*>&										getDeviceCreationExtensions				(void) const { return m_creationExtensions;									}
getUsedApiVersion(void) const457 	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;										}
getUniversalQueueFamilyIndex(void) const458 	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;							}
459 	VkQueue															getUniversalQueue						(void) const;
getSparseQueueFamilyIndex(void) const460 	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;								}
461 	VkQueue															getSparseQueue							(void) const;
462 
463 #ifndef CTS_USES_VULKANSC
hasDebugReportRecorder(void) const464 	bool															hasDebugReportRecorder					(void) const { return m_debugReportRecorder.get() != nullptr;				}
getDebugReportRecorder(void) const465 	vk::DebugReportRecorder&										getDebugReportRecorder					(void) const { return *m_debugReportRecorder.get();							}
466 #endif // CTS_USES_VULKANSC
467 
468 private:
469 #ifndef CTS_USES_VULKANSC
470 	using DebugReportRecorderPtr		= de::UniquePtr<vk::DebugReportRecorder>;
471 	using DebugReportCallbackPtr		= vk::Move<VkDebugReportCallbackEXT>;
472 #endif // CTS_USES_VULKANSC
473 
474 	const deUint32						m_maximumFrameworkVulkanVersion;
475 	const deUint32						m_availableInstanceVersion;
476 	const deUint32						m_usedInstanceVersion;
477 
478 	const std::pair<deUint32, deUint32> m_deviceVersions;
479 	const deUint32						m_usedApiVersion;
480 
481 #ifndef CTS_USES_VULKANSC
482 	const DebugReportRecorderPtr		m_debugReportRecorder;
483 #endif // CTS_USES_VULKANSC
484 	const vector<string>				m_instanceExtensions;
485 	const Unique<VkInstance>			m_instance;
486 #ifndef CTS_USES_VULKANSC
487 	const InstanceDriver				m_instanceInterface;
488 	const DebugReportCallbackPtr		m_debugReportCallback;
489 #else
490 	const InstanceDriverSC				m_instanceInterface;
491 #endif // CTS_USES_VULKANSC
492 	const VkPhysicalDevice				m_physicalDevice;
493 	const deUint32						m_deviceVersion;
494 
495 	const vector<string>				m_deviceExtensions;
496 	const DeviceFeatures				m_deviceFeatures;
497 
498 	const deUint32						m_universalQueueFamilyIndex;
499 	const deUint32						m_sparseQueueFamilyIndex;
500 	const DeviceProperties				m_deviceProperties;
501 	const vector<const char*>			m_creationExtensions;
502 
503 	const Unique<VkDevice>				m_device;
504 	const de::MovePtr<DeviceDriver>		m_deviceInterface;
505 };
506 
507 namespace
508 {
509 
sanitizeApiVersion(deUint32 v)510 deUint32 sanitizeApiVersion(deUint32 v)
511 {
512 	return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
513 }
514 
515 #ifndef CTS_USES_VULKANSC
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)516 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, bool printValidationErrors)
517 {
518 	if (isDebugReportSupported(vkp))
519 		return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
520 	else
521 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
522 }
523 #endif // CTS_USES_VULKANSC
524 
525 // Returns list of non-core extensions. Note the pointers in the result vector come from the extensions vector passed as an argument.
removeCoreExtensions(const deUint32 apiVersion,const vector<string> & extensions)526 vector<const char*> removeCoreExtensions (const deUint32 apiVersion, const vector<string>& extensions)
527 {
528 	// Make vector of char ptrs.
529 	vector<const char*> extensionPtrs;
530 	extensionPtrs.reserve(extensions.size());
531 	std::transform(begin(extensions), end(extensions), std::back_inserter(extensionPtrs), [](const string& s) { return s.c_str(); });
532 
533 	// Obtain the core extension list.
534 	vector<const char*> coreExtensions;
535 	getCoreDeviceExtensions(apiVersion, coreExtensions);
536 
537 	// Remove any extension found in the core extension list.
538 	const auto isNonCoreExtension = [&coreExtensions](const char* extName) {
539 		const auto isSameString = [&extName](const char* otherExtName) { return (std::strcmp(otherExtName, extName) == 0); };
540 		return std::find_if(begin(coreExtensions), end(coreExtensions), isSameString) == end(coreExtensions);
541 	};
542 
543 	vector<const char*> filteredExtensions;
544 	std::copy_if(begin(extensionPtrs), end(extensionPtrs), std::back_inserter(filteredExtensions), isNonCoreExtension);
545 	return filteredExtensions;
546 }
547 
548 } // anonymous
549 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)550 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface)
551 #ifndef CTS_USES_VULKANSC
552 	: m_maximumFrameworkVulkanVersion	(VK_API_MAX_FRAMEWORK_VERSION)
553 #else
554 	: m_maximumFrameworkVulkanVersion	(VKSC_API_MAX_FRAMEWORK_VERSION)
555 #endif // CTS_USES_VULKANSC
556 	, m_availableInstanceVersion		(getTargetInstanceVersion(vkPlatform))
557 	, m_usedInstanceVersion				(sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
558 	, m_deviceVersions					(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
559 	, m_usedApiVersion					(sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
560 
561 #ifndef CTS_USES_VULKANSC
562 	, m_debugReportRecorder				(cmdLine.isValidationEnabled()
563 										 ? createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors())
564 										 : de::MovePtr<vk::DebugReportRecorder>())
565 #endif // CTS_USES_VULKANSC
566 	, m_instanceExtensions				(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
567 #ifndef CTS_USES_VULKANSC
568 	, m_instance						(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
569 #else
570 	, m_instance						(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
571 #endif // CTS_USES_VULKANSC
572 
573 #ifndef CTS_USES_VULKANSC
574 	, m_instanceInterface				(vkPlatform, *m_instance)
575 
576 	, m_debugReportCallback				(cmdLine.isValidationEnabled()
577 										 ? m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get())
578 										 : DebugReportCallbackPtr())
579 #else
580 	, m_instanceInterface				(vkPlatform, *m_instance, cmdLine, resourceInterface)
581 #endif // CTS_USES_VULKANSC
582 	, m_physicalDevice					(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
583 	, m_deviceVersion					(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
584 
585 	, m_deviceExtensions				(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
586 	, m_deviceFeatures					(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
587 	, m_universalQueueFamilyIndex		(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
588 #ifndef CTS_USES_VULKANSC
589 	, m_sparseQueueFamilyIndex			(m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
590 #else
591 	, m_sparseQueueFamilyIndex			(0)
592 #endif // CTS_USES_VULKANSC
593 	, m_deviceProperties				(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
594 	// When the default device is created, we remove the core extensions from the extension list, but those core extensions are
595 	// still reported as part of Context::getDeviceExtensions(). If we need the list of extensions actually used when creating the
596 	// default device, we can use Context::getDeviceCreationExtensions().
597 	, m_creationExtensions				(removeCoreExtensions(m_usedApiVersion, m_deviceExtensions))
598 	, m_device							(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_creationExtensions, cmdLine, resourceInterface))
599 #ifndef CTS_USES_VULKANSC
600 	, m_deviceInterface					(de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device, m_usedApiVersion)))
601 #else
602 	, m_deviceInterface					(de::MovePtr<DeviceDriverSC>(new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface, getDeviceVulkanSC10Properties(), getDeviceProperties(), m_usedApiVersion)))
603 #endif // CTS_USES_VULKANSC
604 {
605 #ifndef CTS_USES_VULKANSC
606 	DE_UNREF(resourceInterface);
607 #endif
608 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
609 }
610 
~DefaultDevice(void)611 DefaultDevice::~DefaultDevice (void)
612 {
613 }
614 
getUniversalQueue(void) const615 VkQueue DefaultDevice::getUniversalQueue (void) const
616 {
617 	return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
618 }
619 
getSparseQueue(void) const620 VkQueue DefaultDevice::getSparseQueue (void) const
621 {
622 	if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
623 		TCU_THROW(NotSupportedError, "Sparse binding not supported.");
624 
625 	return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
626 }
627 
628 namespace
629 {
630 // Allocator utilities
631 
createAllocator(DefaultDevice * device)632 vk::Allocator* createAllocator (DefaultDevice* device)
633 {
634 	const auto&	vki					= device->getInstanceInterface();
635 	const auto	physicalDevice		= device->getPhysicalDevice();
636 	const auto	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
637 
638 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
639 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
640 }
641 
642 } // anonymous
643 
644 // Context
645 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection,de::SharedPtr<vk::ResourceInterface> resourceInterface)646 Context::Context (tcu::TestContext&						testCtx,
647 				  const vk::PlatformInterface&			platformInterface,
648 				  vk::BinaryCollection&					progCollection,
649 				  de::SharedPtr<vk::ResourceInterface>	resourceInterface )
650 	: m_testCtx					(testCtx)
651 	, m_platformInterface		(platformInterface)
652 	, m_progCollection			(progCollection)
653 	, m_resourceInterface		(resourceInterface)
654 	, m_device					(new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
655 	, m_allocator				(createAllocator(m_device.get()))
656 	, m_resultSetOnValidation	(false)
657 {
658 }
659 
~Context(void)660 Context::~Context (void)
661 {
662 }
663 
getMaximumFrameworkVulkanVersion(void) const664 deUint32										Context::getMaximumFrameworkVulkanVersion		(void) const { return m_device->getMaximumFrameworkVulkanVersion();			}
getAvailableInstanceVersion(void) const665 deUint32										Context::getAvailableInstanceVersion			(void) const { return m_device->getAvailableInstanceVersion();				}
getInstanceExtensions(void) const666 const vector<string>&							Context::getInstanceExtensions					(void) const { return m_device->getInstanceExtensions();					}
getInstance(void) const667 vk::VkInstance									Context::getInstance							(void) const { return m_device->getInstance();								}
getInstanceInterface(void) const668 const vk::InstanceInterface&					Context::getInstanceInterface					(void) const { return m_device->getInstanceInterface();						}
getPhysicalDevice(void) const669 vk::VkPhysicalDevice							Context::getPhysicalDevice						(void) const { return m_device->getPhysicalDevice();						}
getDeviceVersion(void) const670 deUint32										Context::getDeviceVersion						(void) const { return m_device->getDeviceVersion();							}
getDeviceFeatures(void) const671 const vk::VkPhysicalDeviceFeatures&				Context::getDeviceFeatures						(void) const { return m_device->getDeviceFeatures();						}
getDeviceFeatures2(void) const672 const vk::VkPhysicalDeviceFeatures2&			Context::getDeviceFeatures2						(void) const { return m_device->getDeviceFeatures2();						}
getDeviceVulkan11Features(void) const673 const vk::VkPhysicalDeviceVulkan11Features&		Context::getDeviceVulkan11Features				(void) const { return m_device->getVulkan11Features();						}
getDeviceVulkan12Features(void) const674 const vk::VkPhysicalDeviceVulkan12Features&		Context::getDeviceVulkan12Features				(void) const { return m_device->getVulkan12Features();						}
675 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Features(void) const676 const vk::VkPhysicalDeviceVulkan13Features&		Context::getDeviceVulkan13Features				(void) const { return m_device->getVulkan13Features();						}
677 #endif // CTS_USES_VULKANSC
678 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Features(void) const679 const vk::VkPhysicalDeviceVulkanSC10Features&	Context::getDeviceVulkanSC10Features			(void) const { return m_device->getVulkanSC10Features();					}
680 #endif // CTS_USES_VULKANSC
681 
isDeviceFunctionalitySupported(const std::string & extension) const682 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
683 {
684 	// If extension was promoted to core then check using the core mechanism. This is required so that
685 	// all core implementations have the functionality tested, even if they don't support the extension.
686 	// (It also means that core-optional extensions will not be reported as supported unless the
687 	// features are really supported if the CTS code adds all core extensions to the extension list).
688 	deUint32 apiVersion = getUsedApiVersion();
689 	if (isCoreDeviceExtension(apiVersion, extension))
690 	{
691 		if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
692 		{
693 			// Check feature bits in extension-specific structures.
694 			if (extension == "VK_KHR_multiview")
695 				return !!m_device->getMultiviewFeatures().multiview;
696 			if (extension == "VK_KHR_variable_pointers")
697 				return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
698 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
699 				return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
700 			if (extension == "VK_KHR_shader_draw_parameters")
701 				return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
702 		}
703 		else
704 		{
705 			// Check feature bits using the new Vulkan 1.2 structures.
706 			const auto& vk11Features = m_device->getVulkan11Features();
707 			if (extension == "VK_KHR_multiview")
708 				return !!vk11Features.multiview;
709 			if (extension == "VK_KHR_variable_pointers")
710 				return !!vk11Features.variablePointersStorageBuffer;
711 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
712 				return !!vk11Features.samplerYcbcrConversion;
713 			if (extension == "VK_KHR_shader_draw_parameters")
714 				return !!vk11Features.shaderDrawParameters;
715 
716 			const auto& vk12Features = m_device->getVulkan12Features();
717 			if (extension == "VK_KHR_timeline_semaphore")
718 				return !!vk12Features.timelineSemaphore;
719 			if (extension == "VK_KHR_buffer_device_address")
720 				return !!vk12Features.bufferDeviceAddress;
721 			if (extension == "VK_EXT_descriptor_indexing")
722 				return !!vk12Features.descriptorIndexing;
723 			if (extension == "VK_KHR_draw_indirect_count")
724 				return !!vk12Features.drawIndirectCount;
725 			if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
726 				return !!vk12Features.samplerMirrorClampToEdge;
727 			if (extension == "VK_EXT_sampler_filter_minmax")
728 				return !!vk12Features.samplerFilterMinmax;
729 			if (extension == "VK_EXT_shader_viewport_index_layer")
730 				return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
731 
732 #ifndef CTS_USES_VULKANSC
733 			const auto& vk13Features = m_device->getVulkan13Features();
734 			if (extension == "VK_EXT_inline_uniform_block")
735 				return !!vk13Features.inlineUniformBlock;
736 			if (extension == "VK_EXT_pipeline_creation_cache_control")
737 				return !!vk13Features.pipelineCreationCacheControl;
738 			if (extension == "VK_EXT_private_data")
739 				return !!vk13Features.privateData;
740 			if (extension == "VK_EXT_shader_demote_to_helper_invocation")
741 				return !!vk13Features.shaderDemoteToHelperInvocation;
742 			if (extension == "VK_KHR_shader_terminate_invocation")
743 				return !!vk13Features.shaderTerminateInvocation;
744 			if (extension == "VK_EXT_subgroup_size_control")
745 				return !!vk13Features.subgroupSizeControl;
746 			if (extension == "VK_KHR_synchronization2")
747 				return !!vk13Features.synchronization2;
748 			if (extension == "VK_EXT_texture_compression_astc_hdr")
749 				return !!vk13Features.textureCompressionASTC_HDR;
750 			if (extension == "VK_KHR_zero_initialize_workgroup_memory")
751 				return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
752 			if (extension == "VK_KHR_dynamic_rendering")
753 				return !!vk13Features.dynamicRendering;
754 			if (extension == "VK_KHR_shader_integer_dot_product")
755 				return !!vk13Features.shaderIntegerDotProduct;
756 			if (extension == "VK_KHR_maintenance4")
757 				return !!vk13Features.maintenance4;
758 #endif // CTS_USES_VULKANSC
759 
760 #ifdef CTS_USES_VULKANSC
761 			const auto& vk12Properties = m_device->getDeviceVulkan12Properties();
762 			if (extension == "VK_KHR_depth_stencil_resolve")
763 				return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) && (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
764 #endif // CTS_USES_VULKANSC
765 		}
766 
767 		// No feature flags to check.
768 		return true;
769 	}
770 
771 	// If this is not a core extension then just return whether the implementation says it's supported.
772 	const auto& extensions = getDeviceExtensions();
773 	return de::contains(extensions.begin(), extensions.end(), extension);
774 }
775 
isInstanceFunctionalitySupported(const std::string & extension) const776 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
777 {
778 	// NOTE: current implementation uses isInstanceExtensionSupported but
779 	// this will change when some instance extensions will be promoted to the
780 	// core; don't use isInstanceExtensionSupported directly, use this method instead
781 	return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
782 }
783 
784 #include "vkDeviceFeaturesForContextDefs.inl"
785 
getDeviceProperties(void) const786 const vk::VkPhysicalDeviceProperties&			Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();			}
getDeviceProperties2(void) const787 const vk::VkPhysicalDeviceProperties2&			Context::getDeviceProperties2				(void) const { return m_device->getDeviceProperties2();			}
getDeviceVulkan11Properties(void) const788 const vk::VkPhysicalDeviceVulkan11Properties&	Context::getDeviceVulkan11Properties		(void) const { return m_device->getDeviceVulkan11Properties();	}
getDeviceVulkan12Properties(void) const789 const vk::VkPhysicalDeviceVulkan12Properties&	Context::getDeviceVulkan12Properties		(void) const { return m_device->getDeviceVulkan12Properties();	}
790 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const791 const vk::VkPhysicalDeviceVulkan13Properties&	Context::getDeviceVulkan13Properties		(void) const { return m_device->getDeviceVulkan13Properties();	}
792 #endif // CTS_USES_VULKANSC
793 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const794 const vk::VkPhysicalDeviceVulkanSC10Properties&	Context::getDeviceVulkanSC10Properties		(void) const { return m_device->getDeviceVulkanSC10Properties(); }
795 #endif // CTS_USES_VULKANSC
796 
797 #include "vkDevicePropertiesForContextDefs.inl"
798 
getDeviceExtensions(void) const799 const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();			}
getDeviceCreationExtensions(void) const800 const vector<const char*>&				Context::getDeviceCreationExtensions		(void) const { return m_device->getDeviceCreationExtensions();	}
getDevice(void) const801 vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const802 const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const803 deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const804 vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();			}
getSparseQueueFamilyIndex(void) const805 deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();	}
getSparseQueue(void) const806 vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();				}
getResourceInterface(void) const807 de::SharedPtr<vk::ResourceInterface>	Context::getResourceInterface				(void) const { return m_resourceInterface;						}
getDefaultAllocator(void) const808 vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;								}
getUsedApiVersion(void) const809 deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();			}
contextSupports(const deUint32 variantNum,const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const810 bool									Context::contextSupports					(const deUint32 variantNum, const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
811 																							{ return isApiVersionSupported(m_device->getUsedApiVersion(), VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum)); }
contextSupports(const ApiVersion version) const812 bool									Context::contextSupports					(const ApiVersion version) const
813 																							{ return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version)); }
contextSupports(const deUint32 requiredApiVersionBits) const814 bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
815 																							{ return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits); }
isDeviceFeatureInitialized(vk::VkStructureType sType) const816 bool									Context::isDeviceFeatureInitialized			(vk::VkStructureType sType) const
817 																							{ return m_device->isDeviceFeatureInitialized(sType);	}
isDevicePropertyInitialized(vk::VkStructureType sType) const818 bool									Context::isDevicePropertyInitialized		(vk::VkStructureType sType) const
819 																							{ return m_device->isDevicePropertyInitialized(sType);	}
820 
requireDeviceFunctionality(const std::string & required) const821 bool Context::requireDeviceFunctionality (const std::string& required) const
822 {
823 	if (!isDeviceFunctionalitySupported(required))
824 		TCU_THROW(NotSupportedError, required + " is not supported");
825 
826 	return true;
827 }
828 
requireInstanceFunctionality(const std::string & required) const829 bool Context::requireInstanceFunctionality (const std::string& required) const
830 {
831 	if (!isInstanceFunctionalitySupported(required))
832 		TCU_THROW(NotSupportedError, required + " is not supported");
833 
834 	return true;
835 }
836 
837 struct DeviceCoreFeaturesTable
838 {
839 	const char*		featureName;
840 	const deUint32	featureArrayIndex;
841 	const deUint32	featureArrayOffset;
842 };
843 
844 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
845 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)	{ #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
846 
847 const DeviceCoreFeaturesTable	deviceCoreFeaturesTable[] =
848 {
849 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS							,	robustBufferAccess						),
850 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32						,	fullDrawIndexUint32						),
851 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY								,	imageCubeArray							),
852 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND								,	independentBlend						),
853 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER								,	geometryShader							),
854 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER							,	tessellationShader						),
855 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING							,	sampleRateShading						),
856 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND								,	dualSrcBlend							),
857 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP										,	logicOp									),
858 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT							,	multiDrawIndirect						),
859 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE					,	drawIndirectFirstInstance				),
860 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP									,	depthClamp								),
861 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP								,	depthBiasClamp							),
862 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID							,	fillModeNonSolid						),
863 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS									,	depthBounds								),
864 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES									,	wideLines								),
865 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS									,	largePoints								),
866 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE									,	alphaToOne								),
867 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT								,	multiViewport							),
868 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY							,	samplerAnisotropy						),
869 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2						,	textureCompressionETC2					),
870 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR					,	textureCompressionASTC_LDR				),
871 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC						,	textureCompressionBC					),
872 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE						,	occlusionQueryPrecise					),
873 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY						,	pipelineStatisticsQuery					),
874 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			,	vertexPipelineStoresAndAtomics			),
875 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS					,	fragmentStoresAndAtomics				),
876 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	,	shaderTessellationAndGeometryPointSize	),
877 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED					,	shaderImageGatherExtended				),
878 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS			,	shaderStorageImageExtendedFormats		),
879 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE				,	shaderStorageImageMultisample			),
880 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT		,	shaderStorageImageReadWithoutFormat		),
881 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT		,	shaderStorageImageWriteWithoutFormat	),
882 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderUniformBufferArrayDynamicIndexing	),
883 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderSampledImageArrayDynamicIndexing	),
884 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderStorageBufferArrayDynamicIndexing	),
885 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderStorageImageArrayDynamicIndexing	),
886 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE							,	shaderClipDistance						),
887 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE							,	shaderCullDistance						),
888 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64								,	shaderFloat64							),
889 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64									,	shaderInt64								),
890 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16									,	shaderInt16								),
891 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY						,	shaderResourceResidency					),
892 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD						,	shaderResourceMinLod					),
893 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING								,	sparseBinding							),
894 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER						,	sparseResidencyBuffer					),
895 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D						,	sparseResidencyImage2D					),
896 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D						,	sparseResidencyImage3D					),
897 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES						,	sparseResidency2Samples					),
898 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES						,	sparseResidency4Samples					),
899 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES						,	sparseResidency8Samples					),
900 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES					,	sparseResidency16Samples				),
901 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED						,	sparseResidencyAliased					),
902 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE						,	variableMultisampleRate					),
903 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES								,	inheritedQueries						),
904 };
905 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)906 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
907 {
908 	const vk::VkPhysicalDeviceFeatures& featuresAvailable		= getDeviceFeatures();
909 	const vk::VkBool32*					featuresAvailableArray	= (vk::VkBool32*)(&featuresAvailable);
910 	const deUint32						requiredFeatureIndex	= static_cast<deUint32>(requiredFeature);
911 
912 	DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
913 	DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
914 
915 	if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
916 		TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
917 
918 	return true;
919 }
920 
921 #ifndef CTS_USES_VULKANSC
922 
isExtendedStorageFormat(VkFormat format)923 static bool isExtendedStorageFormat (VkFormat format)
924 {
925 	switch(format)
926 	{
927 		case VK_FORMAT_R8G8B8A8_UNORM:
928 		case VK_FORMAT_R8G8B8A8_SNORM:
929 		case VK_FORMAT_R8G8B8A8_UINT:
930 		case VK_FORMAT_R8G8B8A8_SINT:
931 		case VK_FORMAT_R32_UINT:
932 		case VK_FORMAT_R32_SINT:
933 		case VK_FORMAT_R32_SFLOAT:
934 		case VK_FORMAT_R32G32_UINT:
935 		case VK_FORMAT_R32G32_SINT:
936 		case VK_FORMAT_R32G32_SFLOAT:
937 		case VK_FORMAT_R32G32B32A32_UINT:
938 		case VK_FORMAT_R32G32B32A32_SINT:
939 		case VK_FORMAT_R32G32B32A32_SFLOAT:
940 		case VK_FORMAT_R16G16B16A16_UINT:
941 		case VK_FORMAT_R16G16B16A16_SINT:
942 		case VK_FORMAT_R16G16B16A16_SFLOAT:
943 		case VK_FORMAT_R16G16_SFLOAT:
944 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
945 		case VK_FORMAT_R16_SFLOAT:
946 		case VK_FORMAT_R16G16B16A16_UNORM:
947 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
948 		case VK_FORMAT_R16G16_UNORM:
949 		case VK_FORMAT_R8G8_UNORM:
950 		case VK_FORMAT_R16_UNORM:
951 		case VK_FORMAT_R8_UNORM:
952 		case VK_FORMAT_R16G16B16A16_SNORM:
953 		case VK_FORMAT_R16G16_SNORM:
954 		case VK_FORMAT_R8G8_SNORM:
955 		case VK_FORMAT_R16_SNORM:
956 		case VK_FORMAT_R8_SNORM:
957 		case VK_FORMAT_R16G16_SINT:
958 		case VK_FORMAT_R8G8_SINT:
959 		case VK_FORMAT_R16_SINT:
960 		case VK_FORMAT_R8_SINT:
961 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
962 		case VK_FORMAT_R16G16_UINT:
963 		case VK_FORMAT_R8G8_UINT:
964 		case VK_FORMAT_R16_UINT:
965 		case VK_FORMAT_R8_UINT:
966 			return true;
967 		default:
968 			return false;
969 	}
970 }
971 
isDepthFormat(VkFormat format)972 static bool isDepthFormat (VkFormat format)
973 {
974 	switch(format)
975 	{
976 		case VK_FORMAT_D16_UNORM:
977 		case VK_FORMAT_X8_D24_UNORM_PACK32:
978 		case VK_FORMAT_D32_SFLOAT:
979 		case VK_FORMAT_D16_UNORM_S8_UINT:
980 		case VK_FORMAT_D24_UNORM_S8_UINT:
981 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
982 			return true;
983 		default:
984 			return false;
985 	}
986 }
987 
getRequiredFormatProperties(const vk::VkFormat & format) const988 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat& format) const
989 {
990 	vk::VkFormatProperties3 p;
991 	p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
992 	p.pNext = DE_NULL;
993 
994 	vk::VkFormatProperties properties;
995 	getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
996 	p.linearTilingFeatures	= properties.linearTilingFeatures;
997 	p.optimalTilingFeatures	= properties.optimalTilingFeatures;
998 	p.bufferFeatures		= properties.bufferFeatures;
999 
1000 	const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
1001 	if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
1002 	{
1003 		if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1004 			p.linearTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1005 		if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1006 			p.optimalTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1007 	}
1008 	if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
1009 	{
1010 		if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1011 			p.linearTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1012 		if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1013 			p.optimalTilingFeatures	|= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1014 	}
1015 	if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1016 		p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1017 	if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1018 		p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1019 
1020 	return p;
1021 }
1022 
getFormatProperties(const vk::VkFormat & format) const1023 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat& format) const
1024 {
1025 	if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
1026 	{
1027 		vk::VkFormatProperties3 p;
1028 		p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1029 		p.pNext = DE_NULL;
1030 
1031 		vk::VkFormatProperties2 properties;
1032 		properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1033 		properties.pNext = &p;
1034 
1035 		getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
1036 		return p;
1037 	}
1038 	else
1039 		return Context::getRequiredFormatProperties(format);
1040 }
1041 
1042 #endif // CTS_USES_VULKANSC
1043 
getInstanceProcAddr()1044 void* Context::getInstanceProcAddr	()
1045 {
1046 	return (void*)m_platformInterface.getGetInstanceProcAddr();
1047 }
1048 
isBufferDeviceAddressSupported(void) const1049 bool Context::isBufferDeviceAddressSupported(void) const
1050 {
1051 	return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
1052 		   isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
1053 }
1054 
1055 #ifndef CTS_USES_VULKANSC
1056 
hasDebugReportRecorder() const1057 bool Context::hasDebugReportRecorder () const
1058 {
1059 	return m_device->hasDebugReportRecorder();
1060 }
1061 
getDebugReportRecorder() const1062 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
1063 {
1064 	return m_device->getDebugReportRecorder();
1065 }
1066 
1067 #endif // CTS_USES_VULKANSC
1068 
resetCommandPoolForVKSC(const VkDevice device,const VkCommandPool commandPool)1069 void Context::resetCommandPoolForVKSC	(const VkDevice					device,
1070 										 const VkCommandPool			commandPool)
1071 {
1072 #ifdef CTS_USES_VULKANSC
1073 	if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE) {
1074 		const DeviceInterface &vk = getDeviceInterface();
1075 		VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1076 	}
1077 #else
1078 	DE_UNREF(device);
1079 	DE_UNREF(commandPool);
1080 #endif
1081 }
1082 
getContextCommonData()1083 ContextCommonData Context::getContextCommonData() {
1084 	return ContextCommonData {
1085 		getInstanceInterface(),
1086 		getDevice(),
1087 		getDeviceInterface(),
1088 		getPhysicalDevice(),
1089 		getDefaultAllocator(),
1090 		getUniversalQueueFamilyIndex(),
1091 		getUniversalQueue()
1092 	};
1093 }
1094 
1095 #ifdef CTS_USES_VULKANSC
1096 std::vector<VkFaultData>						Context::m_faultData;
1097 std::mutex										Context::m_faultDataMutex;
1098 
faultCallbackFunction(VkBool32 unrecordedFaults,uint32_t faultCount,const VkFaultData * pFaults)1099 void Context::faultCallbackFunction(VkBool32 unrecordedFaults,
1100 									uint32_t faultCount,
1101 									const VkFaultData* pFaults)
1102 {
1103 	DE_UNREF(unrecordedFaults);
1104 	std::lock_guard<std::mutex> lock(m_faultDataMutex);
1105 
1106 	// Append new faults to the vector
1107 	for (deUint32 i = 0; i < faultCount; ++i) {
1108 		VkFaultData faultData = pFaults[i];
1109 		faultData.pNext = DE_NULL;
1110 
1111 		m_faultData.push_back(faultData);
1112 	}
1113 }
1114 #endif // CTS_USES_VULKANSC
1115 
1116 // TestCase
1117 
initPrograms(SourceCollections &) const1118 void TestCase::initPrograms (SourceCollections&) const
1119 {
1120 }
1121 
checkSupport(Context &) const1122 void TestCase::checkSupport (Context&) const
1123 {
1124 }
1125 
delayedInit(void)1126 void TestCase::delayedInit (void)
1127 {
1128 }
1129 
1130 #ifndef CTS_USES_VULKANSC
1131 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)1132 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
1133 {
1134 	using DebugMessages = vk::DebugReportRecorder::MessageList;
1135 
1136 	const DebugMessages&	messages	= debugReportRecorder.getMessages();
1137 	tcu::TestLog&			log			= context.getTestContext().getLog();
1138 
1139 	if (messages.size() > 0)
1140 	{
1141 		const tcu::ScopedLogSection	section		(log, "DebugMessages", "Debug Messages");
1142 		int							numErrors	= 0;
1143 
1144 		for (const auto& msg : messages)
1145 		{
1146 			if (msg.shouldBeLogged())
1147 				log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1148 
1149 			if (msg.isError())
1150 				numErrors += 1;
1151 		}
1152 
1153 		debugReportRecorder.clearMessages();
1154 
1155 		if (numErrors > 0)
1156 		{
1157 			string errorMsg = de::toString(numErrors) + " API usage errors found";
1158 			context.resultSetOnValidation(true);
1159 			context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1160 		}
1161 	}
1162 }
1163 
1164 #endif // CTS_USES_VULKANSC
1165 
1166 } // vkt
1167