1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan test case base classes
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktTestCase.hpp"
25 #include "vktCustomInstancesDevices.hpp"
26 
27 #include "vkRef.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkDebugReportUtil.hpp"
34 #include "vkDeviceFeatures.hpp"
35 #include "vkDeviceProperties.hpp"
36 
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include "deSTLUtil.hpp"
41 #include "deMemory.h"
42 
43 #include <set>
44 
45 struct vk_executor;
46 
47 namespace vkt
48 {
49 
50 // Default device utilities
51 
52 using std::vector;
53 using std::string;
54 using std::set;
55 using namespace vk;
56 
57 namespace
58 {
59 
filterExtensions(const vector<VkExtensionProperties> & extensions)60 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
61 {
62 	vector<string>	enabledExtensions;
63 	bool			khrBufferDeviceAddress	= false;
64 
65 	const char*		extensionGroups[]		=
66 	{
67 		"VK_KHR_",
68 		"VK_EXT_",
69 		"VK_KHX_",
70 		"VK_NV_cooperative_matrix",
71 		"VK_EXT_extended_dynamic_state2",
72 		"VK_NV_ray_tracing",
73         "VK_NV_inherited_viewport_scissor",
74 		"VK_AMD_mixed_attachment_samples",
75 		"VK_AMD_shader_fragment_mask",
76 		"VK_AMD_buffer_marker",
77 		"VK_AMD_shader_explicit_vertex_parameter",
78 		"VK_AMD_shader_image_load_store_lod",
79 		"VK_AMD_shader_trinary_minmax",
80 		"VK_AMD_texture_gather_bias_lod",
81 		"VK_ANDROID_external_memory_android_hardware_buffer",
82 	};
83 
84 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
85 	{
86 		if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
87 		{
88 			khrBufferDeviceAddress = true;
89 			break;
90 		}
91 	}
92 
93 	for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
94 	{
95 		const auto& extName = extensions[extNdx].extensionName;
96 
97 		// Skip enabling VK_KHR_pipeline_library unless needed.
98 		if (deStringEqual(extName, "VK_KHR_pipeline_library"))
99 			continue;
100 
101 		// VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
102 		if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
103 			continue;
104 
105 		for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
106 		{
107 			if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
108 				enabledExtensions.push_back(extName);
109 		}
110 	}
111 
112 	return enabledExtensions;
113 }
114 
addExtensions(const vector<string> & a,const vector<const char * > & b)115 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
116 {
117 	vector<string>	res		(a);
118 
119 	for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
120 	{
121 		if (!de::contains(res.begin(), res.end(), string(*bIter)))
122 			res.push_back(string(*bIter));
123 	}
124 
125 	return res;
126 }
127 
removeExtensions(const vector<string> & a,const vector<const char * > & b)128 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
129 {
130 	vector<string>	res;
131 	set<string>		removeExts	(b.begin(), b.end());
132 
133 	for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
134 	{
135 		if (!de::contains(removeExts, *aIter))
136 			res.push_back(*aIter);
137 	}
138 
139 	return res;
140 }
141 
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)142 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
143 {
144 	vector<const char*> coreExtensions;
145 	getCoreInstanceExtensions(instanceVersion, coreExtensions);
146 	return addExtensions(extensions, coreExtensions);
147 }
148 
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)149 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
150 {
151 	vector<const char*> coreExtensions;
152 	getCoreDeviceExtensions(instanceVersion, coreExtensions);
153 	return addExtensions(extensions, coreExtensions);
154 }
155 
getTargetInstanceVersion(const PlatformInterface & vkp)156 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
157 {
158 	deUint32 version = pack(ApiVersion(1, 0, 0));
159 
160 	if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
161 		TCU_THROW(InternalError, "Enumerate instance version error");
162 	return version;
163 }
164 
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)165 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
166 {
167 	Move<VkInstance>						preinstance				= createDefaultInstance(vkp, apiVersion);
168 	InstanceDriver							preinterface			(vkp, preinstance.get());
169 
170 	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(preinterface, preinstance.get());
171 	deUint32								lowestDeviceVersion		= 0xFFFFFFFFu;
172 	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
173 	{
174 		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
175 		if (props.apiVersion < lowestDeviceVersion)
176 			lowestDeviceVersion = props.apiVersion;
177 	}
178 
179 	const vk::VkPhysicalDevice				choosenDevice			= chooseDevice(preinterface, *preinstance, cmdLine);
180 	const VkPhysicalDeviceProperties		props					= getPhysicalDeviceProperties(preinterface, choosenDevice);
181 	const deUint32							choosenDeviceVersion	= props.apiVersion;
182 
183 	return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
184 }
185 
186 
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)187 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
188 {
189 	const bool								isValidationEnabled	= cmdLine.isValidationEnabled();
190 	vector<const char*>						enabledLayers;
191 
192 	// \note Extensions in core are not explicitly enabled even though
193 	//		 they are in the extension list advertised to tests.
194 	vector<const char*>						coreExtensions;
195 	getCoreInstanceExtensions(apiVersion, coreExtensions);
196 	vector<string>							nonCoreExtensions	(removeExtensions(enabledExtensions, coreExtensions));
197 
198 	if (isValidationEnabled)
199 	{
200 		if (!isDebugReportSupported(vkp))
201 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
202 
203 		enabledLayers = vkt::getValidationLayers(vkp);
204 		if (enabledLayers.empty())
205 			TCU_THROW(NotSupportedError, "No validation layers found");
206 	}
207 
208 	return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions);
209 }
210 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)211 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
212 {
213 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
214 
215 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
216 	{
217 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
218 			return (deUint32)queueNdx;
219 	}
220 
221 	TCU_THROW(NotSupportedError, "No matching queue found");
222 }
223 
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const deUint32 apiVersion,deUint32 queueIndex,deUint32 sparseQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)224 Move<VkDevice> createDefaultDevice (const PlatformInterface&			vkp,
225 									VkInstance							instance,
226 									const InstanceInterface&			vki,
227 									VkPhysicalDevice					physicalDevice,
228 									const deUint32						apiVersion,
229 									deUint32							queueIndex,
230 									deUint32							sparseQueueIndex,
231 									const VkPhysicalDeviceFeatures2&	enabledFeatures,
232 									const vector<string>&				enabledExtensions,
233 									const tcu::CommandLine&				cmdLine)
234 {
235 	VkDeviceQueueCreateInfo		queueInfo[2];
236 	VkDeviceCreateInfo			deviceInfo;
237 	vector<const char*>			enabledLayers;
238 	vector<const char*>			extensionPtrs;
239 	const float					queuePriority	= 1.0f;
240 	const deUint32				numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
241 
242 	deMemset(&queueInfo,	0, sizeof(queueInfo));
243 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
244 
245 	if (cmdLine.isValidationEnabled())
246 	{
247 		enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
248 		if (enabledLayers.empty())
249 			TCU_THROW(NotSupportedError, "No validation layers found");
250 	}
251 
252 	// \note Extensions in core are not explicitly enabled even though
253 	//		 they are in the extension list advertised to tests.
254 	vector<const char*> coreExtensions;
255 	getCoreDeviceExtensions(apiVersion, coreExtensions);
256 	vector<string>	nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
257 
258 	extensionPtrs.resize(nonCoreExtensions.size());
259 
260 	for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
261 		extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
262 
263 	queueInfo[0].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
264 	queueInfo[0].pNext						= DE_NULL;
265 	queueInfo[0].flags						= (VkDeviceQueueCreateFlags)0u;
266 	queueInfo[0].queueFamilyIndex			= queueIndex;
267 	queueInfo[0].queueCount					= 1u;
268 	queueInfo[0].pQueuePriorities			= &queuePriority;
269 
270 	if (numQueues > 1)
271 	{
272 		queueInfo[1].sType						= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
273 		queueInfo[1].pNext						= DE_NULL;
274 		queueInfo[1].flags						= (VkDeviceQueueCreateFlags)0u;
275 		queueInfo[1].queueFamilyIndex			= sparseQueueIndex;
276 		queueInfo[1].queueCount					= 1u;
277 		queueInfo[1].pQueuePriorities			= &queuePriority;
278 	}
279 
280 	// VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
281 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
282 	deviceInfo.pNext						= enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
283 	deviceInfo.queueCreateInfoCount			= numQueues;
284 	deviceInfo.pQueueCreateInfos			= queueInfo;
285 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
286 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
287 	deviceInfo.enabledLayerCount			= (deUint32)enabledLayers.size();
288 	deviceInfo.ppEnabledLayerNames			= (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
289 	deviceInfo.pEnabledFeatures				= enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
290 
291 	return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
292 };
293 
294 } // anonymous
295 
296 class DefaultDevice
297 {
298 public:
299 																	DefaultDevice							(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
300 																	~DefaultDevice							(void);
301 
getInstance(void) const302 	VkInstance														getInstance								(void) const { return *m_instance;											}
getInstanceInterface(void) const303 	const InstanceInterface&										getInstanceInterface					(void) const { return m_instanceInterface;									}
getMaximumFrameworkVulkanVersion(void) const304 	deUint32														getMaximumFrameworkVulkanVersion		(void) const { return m_maximumFrameworkVulkanVersion;						}
getAvailableInstanceVersion(void) const305 	deUint32														getAvailableInstanceVersion				(void) const { return m_availableInstanceVersion;							}
getUsedInstanceVersion(void) const306 	deUint32														getUsedInstanceVersion					(void) const { return m_usedInstanceVersion;								}
getInstanceExtensions(void) const307 	const vector<string>&											getInstanceExtensions					(void) const { return m_instanceExtensions;									}
308 
getPhysicalDevice(void) const309 	VkPhysicalDevice												getPhysicalDevice						(void) const { return m_physicalDevice;										}
getDeviceVersion(void) const310 	deUint32														getDeviceVersion						(void) const { return m_deviceVersion;										}
311 
isDeviceFeatureInitialized(VkStructureType sType) const312 	bool															isDeviceFeatureInitialized				(VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);		}
getDeviceFeatures(void) const313 	const VkPhysicalDeviceFeatures&									getDeviceFeatures						(void) const { return m_deviceFeatures.getCoreFeatures2().features;			}
getDeviceFeatures2(void) const314 	const VkPhysicalDeviceFeatures2&								getDeviceFeatures2						(void) const { return m_deviceFeatures.getCoreFeatures2();					}
getVulkan11Features(void) const315 	const VkPhysicalDeviceVulkan11Features&							getVulkan11Features						(void) const { return m_deviceFeatures.getVulkan11Features();				}
getVulkan12Features(void) const316 	const VkPhysicalDeviceVulkan12Features&							getVulkan12Features						(void) const { return m_deviceFeatures.getVulkan12Features();				}
317 
318 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
319 
isDevicePropertyInitialized(VkStructureType sType) const320 	bool															isDevicePropertyInitialized				(VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType);	}
getDeviceProperties(void) const321 	const VkPhysicalDeviceProperties&								getDeviceProperties						(void) const { return m_deviceProperties.getCoreProperties2().properties;	}
getDeviceProperties2(void) const322 	const VkPhysicalDeviceProperties2&								getDeviceProperties2					(void) const { return m_deviceProperties.getCoreProperties2();				}
getVulkan11Properties(void) const323 	const VkPhysicalDeviceVulkan11Properties&						getVulkan11Properties					(void) const { return m_deviceProperties.getVulkan11Properties();			}
getVulkan12Properties(void) const324 	const VkPhysicalDeviceVulkan12Properties&						getVulkan12Properties					(void) const { return m_deviceProperties.getVulkan12Properties();			}
325 
326 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
327 
getDevice(void) const328 	VkDevice														getDevice								(void) const { return *m_device;											}
getDeviceInterface(void) const329 	const DeviceInterface&											getDeviceInterface						(void) const { return m_deviceInterface;									}
getDeviceExtensions(void) const330 	const vector<string>&											getDeviceExtensions						(void) const { return m_deviceExtensions;									}
getUsedApiVersion(void) const331 	deUint32														getUsedApiVersion						(void) const { return m_usedApiVersion;										}
getUniversalQueueFamilyIndex(void) const332 	deUint32														getUniversalQueueFamilyIndex			(void) const { return m_universalQueueFamilyIndex;							}
333 	VkQueue															getUniversalQueue						(void) const;
getSparseQueueFamilyIndex(void) const334 	deUint32														getSparseQueueFamilyIndex				(void) const { return m_sparseQueueFamilyIndex;								}
335 	VkQueue															getSparseQueue							(void) const;
336 
hasDebugReportRecorder(void) const337 	bool															hasDebugReportRecorder					(void) const { return m_debugReportRecorder.get() != nullptr;				}
getDebugReportRecorder(void) const338 	vk::DebugReportRecorder&										getDebugReportRecorder					(void) const { return *m_debugReportRecorder.get();							}
339 
340 private:
341 	using DebugReportRecorderPtr		= de::UniquePtr<vk::DebugReportRecorder>;
342 
343 	const deUint32						m_maximumFrameworkVulkanVersion;
344 	const deUint32						m_availableInstanceVersion;
345 	const deUint32						m_usedInstanceVersion;
346 
347 	const std::pair<deUint32, deUint32> m_deviceVersions;
348 	const deUint32						m_usedApiVersion;
349 
350 	const vector<string>				m_instanceExtensions;
351 	const Unique<VkInstance>			m_instance;
352 	const InstanceDriver				m_instanceInterface;
353 	const DebugReportRecorderPtr		m_debugReportRecorder;
354 
355 	const VkPhysicalDevice				m_physicalDevice;
356 	const deUint32						m_deviceVersion;
357 
358 	const vector<string>				m_deviceExtensions;
359 	const DeviceFeatures				m_deviceFeatures;
360 
361 	const deUint32						m_universalQueueFamilyIndex;
362 	const deUint32						m_sparseQueueFamilyIndex;
363 	const DeviceProperties				m_deviceProperties;
364 
365 	const Unique<VkDevice>				m_device;
366 	const DeviceDriver					m_deviceInterface;
367 };
368 
369 namespace
370 {
371 
sanitizeApiVersion(deUint32 v)372 deUint32 sanitizeApiVersion(deUint32 v)
373 {
374 	return VK_MAKE_VERSION(VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
375 }
376 
createDebugReportRecorder(const vk::PlatformInterface & vkp,const vk::InstanceInterface & vki,vk::VkInstance instance,bool printValidationErrors)377 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, const vk::InstanceInterface& vki, vk::VkInstance instance, bool printValidationErrors)
378 {
379 	if (isDebugReportSupported(vkp))
380 		return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(vki, instance, printValidationErrors));
381 	else
382 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
383 }
384 
385 } // anonymous
386 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)387 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
388 	: m_maximumFrameworkVulkanVersion	(VK_API_MAX_FRAMEWORK_VERSION)
389 	, m_availableInstanceVersion		(getTargetInstanceVersion(vkPlatform))
390 	, m_usedInstanceVersion				(sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
391 	, m_deviceVersions					(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
392 	, m_usedApiVersion					(sanitizeApiVersion(deMinu32(m_usedInstanceVersion, m_deviceVersions.first)))
393 
394 	, m_instanceExtensions				(addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
395 	, m_instance						(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
396 
397 	, m_instanceInterface				(vkPlatform, *m_instance)
398 	, m_debugReportRecorder				(cmdLine.isValidationEnabled()
399 										 ? createDebugReportRecorder(vkPlatform,
400 																	 m_instanceInterface,
401 																	 *m_instance,
402 																	 cmdLine.printValidationErrors())
403 										 : de::MovePtr<vk::DebugReportRecorder>(DE_NULL))
404 	, m_physicalDevice					(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
405 	, m_deviceVersion					(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
406 
407 	, m_deviceExtensions				(addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
408 	, m_deviceFeatures					(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
409 	, m_universalQueueFamilyIndex		(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
410 	, m_sparseQueueFamilyIndex			(m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
411 	, m_deviceProperties				(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
412 	, m_device							(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
413 	, m_deviceInterface					(vkPlatform, *m_instance, *m_device)
414 {
415 	DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
416 }
417 
~DefaultDevice(void)418 DefaultDevice::~DefaultDevice (void)
419 {
420 }
421 
getUniversalQueue(void) const422 VkQueue DefaultDevice::getUniversalQueue (void) const
423 {
424 	return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
425 }
426 
getSparseQueue(void) const427 VkQueue DefaultDevice::getSparseQueue (void) const
428 {
429 	if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
430 		TCU_THROW(NotSupportedError, "Sparse binding not supported.");
431 
432 	return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
433 }
434 
435 namespace
436 {
437 // Allocator utilities
438 
createAllocator(DefaultDevice * device)439 vk::Allocator* createAllocator (DefaultDevice* device)
440 {
441 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
442 
443 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
444 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
445 }
446 
447 } // anonymous
448 
449 // Context
450 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection)451 Context::Context (tcu::TestContext&				testCtx,
452 				  const vk::PlatformInterface&	platformInterface,
453 				  vk::BinaryCollection&			progCollection)
454 	: m_testCtx					(testCtx)
455 	, m_platformInterface		(platformInterface)
456 	, m_progCollection			(progCollection)
457 	, m_device					(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
458 	, m_allocator				(createAllocator(m_device.get()))
459 	, m_resultSetOnValidation	(false)
460 {
461 }
462 
~Context(void)463 Context::~Context (void)
464 {
465 }
466 
getMaximumFrameworkVulkanVersion(void) const467 deUint32								Context::getMaximumFrameworkVulkanVersion	(void) const { return m_device->getMaximumFrameworkVulkanVersion();		}
getAvailableInstanceVersion(void) const468 deUint32								Context::getAvailableInstanceVersion		(void) const { return m_device->getAvailableInstanceVersion();	}
getInstanceExtensions(void) const469 const vector<string>&					Context::getInstanceExtensions				(void) const { return m_device->getInstanceExtensions();		}
getInstance(void) const470 vk::VkInstance							Context::getInstance						(void) const { return m_device->getInstance();					}
getInstanceInterface(void) const471 const vk::InstanceInterface&			Context::getInstanceInterface				(void) const { return m_device->getInstanceInterface();			}
getPhysicalDevice(void) const472 vk::VkPhysicalDevice					Context::getPhysicalDevice					(void) const { return m_device->getPhysicalDevice();			}
getDeviceVersion(void) const473 deUint32								Context::getDeviceVersion					(void) const { return m_device->getDeviceVersion();				}
getDeviceFeatures(void) const474 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures					(void) const { return m_device->getDeviceFeatures();			}
getDeviceFeatures2(void) const475 const vk::VkPhysicalDeviceFeatures2&	Context::getDeviceFeatures2					(void) const { return m_device->getDeviceFeatures2();			}
476 
isDeviceFunctionalitySupported(const std::string & extension) const477 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
478 {
479 	// check if extension was promoted to core
480 	deUint32 apiVersion = getUsedApiVersion();
481 	if (isCoreDeviceExtension(apiVersion, extension))
482 	{
483 		if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
484 		{
485 			// Check feature bits in extension-specific structures.
486 			if (extension == "VK_KHR_multiview")
487 				return !!m_device->getMultiviewFeatures().multiview;
488 			if (extension == "VK_KHR_variable_pointers")
489 				return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
490 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
491 				return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
492 			if (extension == "VK_KHR_shader_draw_parameters")
493 				return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
494 		}
495 		else
496 		{
497 			// Check feature bits using the new Vulkan 1.2 structures.
498 			const auto& vk11Features = m_device->getVulkan11Features();
499 			if (extension == "VK_KHR_multiview")
500 				return !!vk11Features.multiview;
501 			if (extension == "VK_KHR_variable_pointers")
502 				return !!vk11Features.variablePointersStorageBuffer;
503 			if (extension == "VK_KHR_sampler_ycbcr_conversion")
504 				return !!vk11Features.samplerYcbcrConversion;
505 			if (extension == "VK_KHR_shader_draw_parameters")
506 				return !!vk11Features.shaderDrawParameters;
507 
508 			const auto& vk12Features = m_device->getVulkan12Features();
509 			if (extension == "VK_KHR_timeline_semaphore")
510 				return !!vk12Features.timelineSemaphore;
511 			if (extension == "VK_KHR_buffer_device_address")
512 				return !!vk12Features.bufferDeviceAddress;
513 			if (extension == "VK_EXT_descriptor_indexing")
514 				return !!vk12Features.descriptorIndexing;
515 			if (extension == "VK_KHR_draw_indirect_count")
516 				return !!vk12Features.drawIndirectCount;
517 			if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
518 				return !!vk12Features.samplerMirrorClampToEdge;
519 			if (extension == "VK_EXT_sampler_filter_minmax")
520 				return !!vk12Features.samplerFilterMinmax;
521 			if (extension == "VK_EXT_shader_viewport_index_layer")
522 				return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
523 		}
524 
525 		// No feature flags to check.
526 		return true;
527 	}
528 
529 	// check if extension is on the lits of extensions for current device
530 	const auto& extensions = getDeviceExtensions();
531 	if (de::contains(extensions.begin(), extensions.end(), extension))
532 	{
533 		if (extension == "VK_KHR_timeline_semaphore")
534 			return !!getTimelineSemaphoreFeatures().timelineSemaphore;
535 		if (extension == "VK_KHR_synchronization2")
536 			return !!getSynchronization2Features().synchronization2;
537 		if (extension == "VK_EXT_extended_dynamic_state")
538 			return !!getExtendedDynamicStateFeaturesEXT().extendedDynamicState;
539 		if (extension == "VK_EXT_shader_demote_to_helper_invocation")
540 			return !!getShaderDemoteToHelperInvocationFeaturesEXT().shaderDemoteToHelperInvocation;
541 		if (extension == "VK_KHR_workgroup_memory_explicit_layout")
542 			return !!getWorkgroupMemoryExplicitLayoutFeatures().workgroupMemoryExplicitLayout;
543 
544 		return true;
545 	}
546 
547 	return false;
548 }
549 
isInstanceFunctionalitySupported(const std::string & extension) const550 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
551 {
552 	// NOTE: current implementation uses isInstanceExtensionSupported but
553 	// this will change when some instance extensions will be promoted to the
554 	// core; don't use isInstanceExtensionSupported directly, use this method instead
555 	return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
556 }
557 
558 #include "vkDeviceFeaturesForContextDefs.inl"
559 
getDeviceProperties(void) const560 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties				(void) const { return m_device->getDeviceProperties();			}
getDeviceProperties2(void) const561 const vk::VkPhysicalDeviceProperties2&	Context::getDeviceProperties2				(void) const { return m_device->getDeviceProperties2();			}
562 
563 #include "vkDevicePropertiesForContextDefs.inl"
564 
getDeviceExtensions(void) const565 const vector<string>&					Context::getDeviceExtensions				(void) const { return m_device->getDeviceExtensions();			}
getDevice(void) const566 vk::VkDevice							Context::getDevice							(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const567 const vk::DeviceInterface&				Context::getDeviceInterface					(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const568 deUint32								Context::getUniversalQueueFamilyIndex		(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const569 vk::VkQueue								Context::getUniversalQueue					(void) const { return m_device->getUniversalQueue();			}
getSparseQueueFamilyIndex(void) const570 deUint32								Context::getSparseQueueFamilyIndex			(void) const { return m_device->getSparseQueueFamilyIndex();	}
getSparseQueue(void) const571 vk::VkQueue								Context::getSparseQueue						(void) const { return m_device->getSparseQueue();				}
getDefaultAllocator(void) const572 vk::Allocator&							Context::getDefaultAllocator				(void) const { return *m_allocator;								}
getUsedApiVersion(void) const573 deUint32								Context::getUsedApiVersion					(void) const { return m_device->getUsedApiVersion();			}
contextSupports(const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const574 bool									Context::contextSupports					(const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
575 																							{ return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
contextSupports(const ApiVersion version) const576 bool									Context::contextSupports					(const ApiVersion version) const
577 																							{ return m_device->getUsedApiVersion() >= pack(version); }
contextSupports(const deUint32 requiredApiVersionBits) const578 bool									Context::contextSupports					(const deUint32 requiredApiVersionBits) const
579 																							{ return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
isDeviceFeatureInitialized(vk::VkStructureType sType) const580 bool									Context::isDeviceFeatureInitialized			(vk::VkStructureType sType) const
581 																							{ return m_device->isDeviceFeatureInitialized(sType);	}
isDevicePropertyInitialized(vk::VkStructureType sType) const582 bool									Context::isDevicePropertyInitialized		(vk::VkStructureType sType) const
583 																							{ return m_device->isDevicePropertyInitialized(sType);	}
584 
requireDeviceFunctionality(const std::string & required) const585 bool Context::requireDeviceFunctionality (const std::string& required) const
586 {
587 	if (!isDeviceFunctionalitySupported(required))
588 		TCU_THROW(NotSupportedError, required + " is not supported");
589 
590 	return true;
591 }
592 
requireInstanceFunctionality(const std::string & required) const593 bool Context::requireInstanceFunctionality (const std::string& required) const
594 {
595 	if (!isInstanceFunctionalitySupported(required))
596 		TCU_THROW(NotSupportedError, required + " is not supported");
597 
598 	return true;
599 }
600 
601 struct DeviceCoreFeaturesTable
602 {
603 	const char*		featureName;
604 	const deUint32	featureArrayIndex;
605 	const deUint32	featureArrayOffset;
606 };
607 
608 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
609 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)	{ #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
610 
611 const DeviceCoreFeaturesTable	deviceCoreFeaturesTable[] =
612 {
613 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS							,	robustBufferAccess						),
614 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32						,	fullDrawIndexUint32						),
615 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY								,	imageCubeArray							),
616 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND								,	independentBlend						),
617 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER								,	geometryShader							),
618 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER							,	tessellationShader						),
619 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING							,	sampleRateShading						),
620 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND								,	dualSrcBlend							),
621 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP										,	logicOp									),
622 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT							,	multiDrawIndirect						),
623 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE					,	drawIndirectFirstInstance				),
624 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP									,	depthClamp								),
625 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP								,	depthBiasClamp							),
626 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID							,	fillModeNonSolid						),
627 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS									,	depthBounds								),
628 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES									,	wideLines								),
629 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS									,	largePoints								),
630 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE									,	alphaToOne								),
631 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT								,	multiViewport							),
632 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY							,	samplerAnisotropy						),
633 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2						,	textureCompressionETC2					),
634 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR					,	textureCompressionASTC_LDR				),
635 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC						,	textureCompressionBC					),
636 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE						,	occlusionQueryPrecise					),
637 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY						,	pipelineStatisticsQuery					),
638 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			,	vertexPipelineStoresAndAtomics			),
639 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS					,	fragmentStoresAndAtomics				),
640 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	,	shaderTessellationAndGeometryPointSize	),
641 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED					,	shaderImageGatherExtended				),
642 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS			,	shaderStorageImageExtendedFormats		),
643 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE				,	shaderStorageImageMultisample			),
644 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT		,	shaderStorageImageReadWithoutFormat		),
645 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT		,	shaderStorageImageWriteWithoutFormat	),
646 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderUniformBufferArrayDynamicIndexing	),
647 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderSampledImageArrayDynamicIndexing	),
648 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING	,	shaderStorageBufferArrayDynamicIndexing	),
649 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING	,	shaderStorageImageArrayDynamicIndexing	),
650 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE							,	shaderClipDistance						),
651 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE							,	shaderCullDistance						),
652 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64								,	shaderFloat64							),
653 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64									,	shaderInt64								),
654 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16									,	shaderInt16								),
655 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY						,	shaderResourceResidency					),
656 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD						,	shaderResourceMinLod					),
657 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING								,	sparseBinding							),
658 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER						,	sparseResidencyBuffer					),
659 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D						,	sparseResidencyImage2D					),
660 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D						,	sparseResidencyImage3D					),
661 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES						,	sparseResidency2Samples					),
662 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES						,	sparseResidency4Samples					),
663 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES						,	sparseResidency8Samples					),
664 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES					,	sparseResidency16Samples				),
665 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED						,	sparseResidencyAliased					),
666 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE						,	variableMultisampleRate					),
667 	DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES								,	inheritedQueries						),
668 };
669 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)670 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
671 {
672 	const vk::VkPhysicalDeviceFeatures& featuresAvailable		= getDeviceFeatures();
673 	const vk::VkBool32*					featuresAvailableArray	= (vk::VkBool32*)(&featuresAvailable);
674 	const deUint32						requiredFeatureIndex	= static_cast<deUint32>(requiredFeature);
675 
676 	DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
677 	DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
678 
679 	if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
680 		TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
681 
682 	return true;
683 }
684 
getInstanceProcAddr()685 void* Context::getInstanceProcAddr	()
686 {
687 	return (void*)m_platformInterface.getGetInstanceProcAddr();
688 }
689 
isBufferDeviceAddressSupported(void) const690 bool Context::isBufferDeviceAddressSupported(void) const
691 {
692 	return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
693 		   isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
694 }
695 
hasDebugReportRecorder() const696 bool Context::hasDebugReportRecorder () const
697 {
698 	return m_device->hasDebugReportRecorder();
699 }
700 
getDebugReportRecorder() const701 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
702 {
703 	return m_device->getDebugReportRecorder();
704 }
705 
706 // TestCase
707 
initPrograms(SourceCollections &) const708 void TestCase::initPrograms (SourceCollections&) const
709 {
710 }
711 
checkSupport(Context &) const712 void TestCase::checkSupport (Context&) const
713 {
714 }
715 
delayedInit(void)716 void TestCase::delayedInit (void)
717 {
718 }
719 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)720 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
721 {
722 	using DebugMessages = vk::DebugReportRecorder::MessageList;
723 
724 	const DebugMessages&	messages	= debugReportRecorder.getMessages();
725 	tcu::TestLog&			log			= context.getTestContext().getLog();
726 
727 	if (messages.size() > 0)
728 	{
729 		const tcu::ScopedLogSection	section		(log, "DebugMessages", "Debug Messages");
730 		int							numErrors	= 0;
731 
732 		for (const auto& msg : messages)
733 		{
734 			if (msg.shouldBeLogged())
735 				log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
736 
737 			if (msg.isError())
738 				numErrors += 1;
739 		}
740 
741 		debugReportRecorder.clearMessages();
742 
743 		if (numErrors > 0)
744 		{
745 			string errorMsg = de::toString(numErrors) + " API usage errors found";
746 			context.resultSetOnValidation(true);
747 			context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
748 		}
749 	}
750 }
751 
752 } // vkt
753