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