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