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