• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 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 VkSurface Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktWsiSurfaceTests.hpp"
25 
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktCustomInstancesDevices.hpp"
29 #include "vktNativeObjectsUtil.hpp"
30 
31 #include "vkDefs.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkStrUtil.hpp"
34 #include "vkRef.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkMemUtil.hpp"
38 #include "vkDeviceUtil.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkWsiPlatform.hpp"
42 #include "vkWsiUtil.hpp"
43 #include "vkAllocationCallbackUtil.hpp"
44 #include "vkQueryUtil.hpp"
45 
46 #include "tcuTestLog.hpp"
47 #include "tcuFormatUtil.hpp"
48 #include "tcuPlatform.hpp"
49 #include "tcuResultCollector.hpp"
50 #include "tcuCommandLine.hpp"
51 
52 #include "deUniquePtr.hpp"
53 #include "deStringUtil.hpp"
54 #include "deMemory.h"
55 
56 namespace vk
57 {
58 
operator !=(const VkSurfaceFormatKHR & a,const VkSurfaceFormatKHR & b)59 inline bool operator!= (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
60 {
61 	return (a.format != b.format) || (a.colorSpace != b.colorSpace);
62 }
63 
operator ==(const VkSurfaceFormatKHR & a,const VkSurfaceFormatKHR & b)64 inline bool operator== (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
65 {
66 	return !(a != b);
67 }
68 
operator !=(const VkExtent2D & a,const VkExtent2D & b)69 inline bool operator!= (const VkExtent2D& a, const VkExtent2D& b)
70 {
71 	return (a.width != b.width) || (a.height != b.height);
72 }
73 
operator !=(const VkSurfaceCapabilitiesKHR & a,const VkSurfaceCapabilitiesKHR & b)74 inline bool operator!= (const VkSurfaceCapabilitiesKHR& a, const VkSurfaceCapabilitiesKHR& b)
75 {
76 	return (a.minImageCount				!= b.minImageCount)				||
77 		   (a.maxImageCount				!= b.maxImageCount)				||
78 		   (a.currentExtent				!= b.currentExtent)				||
79 		   (a.minImageExtent			!= b.minImageExtent)			||
80 		   (a.maxImageExtent			!= b.maxImageExtent)			||
81 		   (a.maxImageArrayLayers		!= b.maxImageArrayLayers)		||
82 		   (a.supportedTransforms		!= b.supportedTransforms)		||
83 		   (a.currentTransform			!= b.currentTransform)			||
84 		   (a.supportedCompositeAlpha	!= b.supportedCompositeAlpha)	||
85 		   (a.supportedUsageFlags		!= b.supportedUsageFlags);
86 }
87 
88 } // vk
89 
90 namespace vkt
91 {
92 namespace wsi
93 {
94 
95 namespace
96 {
97 
98 using namespace vk;
99 using namespace vk::wsi;
100 
101 using tcu::TestLog;
102 using tcu::Maybe;
103 using tcu::UVec2;
104 
105 using de::MovePtr;
106 using de::UniquePtr;
107 
108 using std::string;
109 using std::vector;
110 
111 enum
112 {
113 	SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC	= 0xffffffff
114 };
115 
116 enum
117 {
118 	GUARD_SIZE										= 0x20,			//!< Number of bytes to check
119 	GUARD_VALUE										= 0xcd,			//!< Data pattern
120 };
121 
122 template<typename T>
123 class CheckIncompleteResult
124 {
125 public:
~CheckIncompleteResult(void)126 	virtual			~CheckIncompleteResult	(void) {}
127 	virtual void	getResult				(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, T* data) = 0;
128 
operator ()(tcu::ResultCollector & results,const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkSurfaceKHR surface,const std::size_t expectedCompleteSize)129 	void operator() (tcu::ResultCollector&		results,
130 					 const InstanceInterface&	vki,
131 					 const VkPhysicalDevice		physDevice,
132 					 const VkSurfaceKHR			surface,
133 					 const std::size_t			expectedCompleteSize)
134 	{
135 		if (expectedCompleteSize == 0)
136 			return;
137 
138 		vector<T>		outputData	(expectedCompleteSize);
139 		const deUint32	usedSize	= static_cast<deUint32>(expectedCompleteSize / 3);
140 
141 		ValidateQueryBits::fillBits(outputData.begin(), outputData.end());	// unused entries should have this pattern intact
142 		m_count		= usedSize;
143 		m_result	= VK_SUCCESS;
144 
145 		getResult(vki, physDevice, surface, &outputData[0]);				// update m_count and m_result
146 
147 		if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end()))
148 			results.fail("Query didn't return VK_INCOMPLETE");
149 	}
150 
151 protected:
152 	deUint32	m_count;
153 	VkResult	m_result;
154 };
155 
156 struct CheckPhysicalDeviceSurfaceFormatsIncompleteResult : public CheckIncompleteResult<VkSurfaceFormatKHR>
157 {
getResultvkt::wsi::__anon60bb292a0111::CheckPhysicalDeviceSurfaceFormatsIncompleteResult158 	void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkSurfaceFormatKHR* data)
159 	{
160 		m_result = vki.getPhysicalDeviceSurfaceFormatsKHR(physDevice, surface, &m_count, data);
161 	}
162 };
163 
164 struct CheckPhysicalDeviceSurfacePresentModesIncompleteResult : public CheckIncompleteResult<VkPresentModeKHR>
165 {
getResultvkt::wsi::__anon60bb292a0111::CheckPhysicalDeviceSurfacePresentModesIncompleteResult166 	void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkPresentModeKHR* data)
167 	{
168 		m_result = vki.getPhysicalDeviceSurfacePresentModesKHR(physDevice, surface, &m_count, data);
169 	}
170 };
171 
172 typedef vector<VkExtensionProperties> Extensions;
173 
createInstanceWithWsi(Context & context,Type wsiType,const vector<string> extraExtensions,const VkAllocationCallbacks * pAllocator=DE_NULL)174 CustomInstance createInstanceWithWsi (Context&						context,
175 									  Type							wsiType,
176 									  const vector<string>			extraExtensions,
177 									  const VkAllocationCallbacks*	pAllocator	= DE_NULL)
178 {
179 	const deUint32	version		= context.getUsedApiVersion();
180 	vector<string>	extensions	= extraExtensions;
181 
182 	extensions.push_back("VK_KHR_surface");
183 	extensions.push_back(getExtensionName(wsiType));
184 	if (isDisplaySurface(wsiType))
185 		extensions.push_back("VK_KHR_display");
186 
187 	vector<string>	instanceExtensions;
188 	for (const auto& ext : extensions)
189 	{
190 		if (!context.isInstanceFunctionalitySupported(ext))
191 			TCU_THROW(NotSupportedError, (ext + " is not supported").c_str());
192 
193 		if (!isCoreInstanceExtension(version, ext))
194 			instanceExtensions.push_back(ext);
195 	}
196 
197 	return vkt::createCustomInstanceWithExtensions(context, instanceExtensions, pAllocator);
198 }
199 
200 struct InstanceHelper
201 {
202 	const vector<VkExtensionProperties>	supportedExtensions;
203 	CustomInstance						instance;
204 	const InstanceDriver&				vki;
205 
InstanceHelpervkt::wsi::__anon60bb292a0111::InstanceHelper206 	InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
207 		: supportedExtensions	(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
208 																	  DE_NULL))
209 		, instance				(createInstanceWithWsi(context,
210 													   wsiType,
211 													   vector<string>(),
212 													   pAllocator))
213 		, vki					(instance.getDriver())
214 	{}
215 
InstanceHelpervkt::wsi::__anon60bb292a0111::InstanceHelper216 	InstanceHelper (Context& context, Type wsiType, const vector<string>& extensions, const VkAllocationCallbacks* pAllocator = DE_NULL)
217 		: supportedExtensions	(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
218 																	  DE_NULL))
219 		, instance				(createInstanceWithWsi(context,
220 													   wsiType,
221 													   extensions,
222 													   pAllocator))
223 		, vki					(instance.getDriver())
224 	{}
225 };
226 
createSurfaceTest(Context & context,Type wsiType)227 tcu::TestStatus createSurfaceTest (Context& context, Type wsiType)
228 {
229 	const InstanceHelper		instHelper	(context, wsiType);
230 	const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
231 	const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
232 
233 	return tcu::TestStatus::pass("Creating surface succeeded");
234 }
235 
querySurfaceCounterTest(Context & context,Type wsiType)236 tcu::TestStatus querySurfaceCounterTest (Context& context, Type wsiType)
237 {
238 	const InstanceHelper			instHelper		(context, wsiType);
239 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
240 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
241 	const vk::InstanceInterface&	vki				= context.getInstanceInterface();
242 	const vk::VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
243 	const bool						isDisplay		= isDisplaySurface(wsiType);
244 
245 	if (!isInstanceExtensionSupported(context.getUsedApiVersion(), context.getInstanceExtensions(), "VK_EXT_display_surface_counter"))
246 		TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
247 
248 	const vk::VkSurfaceCapabilities2EXT	capsExt = getPhysicalDeviceSurfaceCapabilities2EXT	(vki, physicalDevice, surface.get());
249 	const vk::VkSurfaceCapabilitiesKHR	capsKhr = getPhysicalDeviceSurfaceCapabilities		(vki, physicalDevice, surface.get());
250 
251 	if (!sameSurfaceCapabilities(capsKhr, capsExt))
252 	{
253 		return tcu::TestStatus::fail("KHR and EXT surface capabilities do not match");
254 	}
255 
256 	if (!isDisplay && capsExt.supportedSurfaceCounters != 0)
257 	{
258 		return tcu::TestStatus::fail("supportedSurfaceCounters nonzero (" + de::toString(capsExt.supportedSurfaceCounters) + ") for non-display surface");
259 	}
260 
261 	return tcu::TestStatus::pass("Pass");
262 }
263 
createSurfaceCustomAllocatorTest(Context & context,Type wsiType)264 tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
265 {
266 	AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
267 	tcu::TestLog&				log					= context.getTestContext().getLog();
268 
269 	{
270 		const InstanceHelper		instHelper	(context, wsiType, allocationRecorder.getCallbacks());
271 		const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
272 		const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki,
273 															   instHelper.instance,
274 															   wsiType,
275 															   native.getDisplay(),
276 															   native.getWindow(),
277 															   context.getTestContext().getCommandLine(),
278 															   allocationRecorder.getCallbacks()));
279 
280 		if (!validateAndLog(log,
281 							allocationRecorder,
282 							(1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)		|
283 							(1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
284 			return tcu::TestStatus::fail("Detected invalid system allocation callback");
285 	}
286 
287 	if (!validateAndLog(log, allocationRecorder, 0u))
288 		return tcu::TestStatus::fail("Detected invalid system allocation callback");
289 
290 	if (allocationRecorder.getRecordsBegin() == allocationRecorder.getRecordsEnd())
291 		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
292 	else
293 		return tcu::TestStatus::pass("Creating surface succeeded using custom allocator");
294 }
295 
createSurfaceSimulateOOMTest(Context & context,Type wsiType)296 tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
297 {
298 	tcu::TestLog&	log	= context.getTestContext().getLog();
299 
300 	for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
301 	{
302 		AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
303 		DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(),
304 														 DeterministicFailAllocator::MODE_DO_NOT_COUNT,
305 														 0);
306 		bool						gotOOM				= false;
307 
308 		log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
309 
310 		try
311 		{
312 			const InstanceHelper		instHelper	(context, wsiType, failingAllocator.getCallbacks());
313 
314 			// OOM is not simulated for VkInstance as we don't want to spend time
315 			// testing OOM paths inside instance creation.
316 			failingAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
317 
318 			const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
319 			const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki,
320 																   instHelper.instance,
321 																   wsiType,
322 																   native.getDisplay(),
323 																   native.getWindow(),
324 																   context.getTestContext().getCommandLine(),
325 																   failingAllocator.getCallbacks()));
326 
327 			if (!validateAndLog(log,
328 								allocationRecorder,
329 								(1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)		|
330 								(1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
331 				return tcu::TestStatus::fail("Detected invalid system allocation callback");
332 		}
333 		catch (const OutOfMemoryError& e)
334 		{
335 			log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
336 			gotOOM = true;
337 		}
338 
339 		if (!validateAndLog(log, allocationRecorder, 0u))
340 			return tcu::TestStatus::fail("Detected invalid system allocation callback");
341 
342 		if (!gotOOM)
343 		{
344 			log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
345 
346 			if (numPassingAllocs == 0)
347 				return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
348 			else
349 				return tcu::TestStatus::pass("OOM simulation completed");
350 		}
351 	}
352 
353 	return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating surface did not succeed, callback limit exceeded");
354 }
355 
getNumQueueFamilies(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)356 deUint32 getNumQueueFamilies (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
357 {
358 	deUint32	numFamilies		= 0;
359 
360 	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
361 
362 	return numFamilies;
363 }
364 
querySurfaceSupportTest(Context & context,Type wsiType)365 tcu::TestStatus querySurfaceSupportTest (Context& context, Type wsiType)
366 {
367 	tcu::TestLog&					log						= context.getTestContext().getLog();
368 	tcu::ResultCollector			results					(log);
369 
370 	const InstanceHelper			instHelper				(context, wsiType);
371 	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
372 	const Unique<VkSurfaceKHR>		surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
373 	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
374 
375 	// On Android surface must be supported by all devices and queue families
376 	const bool						expectSupportedOnAll	= wsiType == TYPE_ANDROID;
377 
378 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
379 	{
380 		const VkPhysicalDevice		physicalDevice		= physicalDevices[deviceNdx];
381 		const deUint32				numQueueFamilies	= getNumQueueFamilies(instHelper.vki, physicalDevice);
382 
383 		for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
384 		{
385 			const VkBool32	isSupported		= getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
386 
387 			log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": "
388 									<< (isSupported == VK_FALSE ? "NOT " : "") << "supported"
389 				<< TestLog::EndMessage;
390 
391 			if (expectSupportedOnAll && !isSupported)
392 				results.fail("Surface must be supported by all devices and queue families");
393 		}
394 	}
395 
396 	return tcu::TestStatus(results.getResult(), results.getMessage());
397 }
398 
queryPresentationSupportTest(Context & context,Type wsiType)399 tcu::TestStatus queryPresentationSupportTest(Context& context, Type wsiType)
400 {
401 	// There is no implementation of getPhysicalDevicePresentationSupport for DRM.
402 	if (wsiType == TYPE_DIRECT_DRM) {
403 		TCU_THROW(NotSupportedError, "No presentation support query for Drm.");
404 	}
405 
406 	tcu::TestLog&					log						= context.getTestContext().getLog();
407 	tcu::ResultCollector			results					(log);
408 
409 	const InstanceHelper			instHelper				(context, wsiType);
410 	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
411 	const Unique<VkSurfaceKHR>		surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
412 	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
413 
414 	native.getDisplay();
415 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
416 	{
417 		const VkPhysicalDevice		physicalDevice		= physicalDevices[deviceNdx];
418 		const deUint32				numQueueFamilies	= getNumQueueFamilies(instHelper.vki, physicalDevice);
419 
420 		for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
421 		{
422 			VkBool32	isPresentationSupported	= getPhysicalDevicePresentationSupport(instHelper.vki, physicalDevice, queueFamilyNdx, wsiType, native.getDisplay());
423 			VkBool32	isSurfaceSupported		= getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
424 
425 			log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": presentation "
426 									<< (isPresentationSupported == VK_FALSE ? "NOT " : "") << "supported. Surface "
427 									<< (isSurfaceSupported == VK_FALSE ? "NOT " : "") << "supported."
428 				<< TestLog::EndMessage;
429 
430 			if (isPresentationSupported != isSurfaceSupported)
431 				results.fail("Presentation support is different from surface support");
432 		}
433 	}
434 
435 	return tcu::TestStatus(results.getResult(), results.getMessage());
436 }
437 
isSupportedByAnyQueue(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)438 bool isSupportedByAnyQueue (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
439 {
440 	const deUint32	numQueueFamilies	= getNumQueueFamilies(vki, physicalDevice);
441 
442 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
443 	{
444 		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
445 			return true;
446 	}
447 
448 	return false;
449 }
450 
validateSurfaceCapabilities(tcu::ResultCollector & results,const VkSurfaceCapabilitiesKHR & capabilities)451 void validateSurfaceCapabilities (tcu::ResultCollector& results, const VkSurfaceCapabilitiesKHR& capabilities)
452 {
453 	results.check(capabilities.minImageCount > 0,
454 				  "minImageCount must be larger than 0");
455 
456 	results.check(capabilities.minImageExtent.width > 0 &&
457 				  capabilities.minImageExtent.height > 0,
458 				  "minImageExtent dimensions must be larger than 0");
459 
460 	results.check(capabilities.maxImageExtent.width > 0 &&
461 				  capabilities.maxImageExtent.height > 0,
462 				  "maxImageExtent dimensions must be larger than 0");
463 
464 	results.check(capabilities.minImageExtent.width <= capabilities.maxImageExtent.width &&
465 				  capabilities.minImageExtent.height <= capabilities.maxImageExtent.height,
466 				  "maxImageExtent must be larger or equal to minImageExtent");
467 
468 	if (capabilities.currentExtent.width != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC ||
469 		capabilities.currentExtent.height != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC)
470 	{
471 		results.check(capabilities.currentExtent.width > 0 &&
472 					  capabilities.currentExtent.height > 0,
473 					  "currentExtent dimensions must be larger than 0");
474 
475 		results.check(de::inRange(capabilities.currentExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) &&
476 					  de::inRange(capabilities.currentExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height),
477 					  "currentExtent is not in supported extent limits");
478 	}
479 
480 	results.check(capabilities.maxImageArrayLayers > 0,
481 				  "maxImageArrayLayers must be larger than 0");
482 
483 	results.check((capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0,
484 				  "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT must be set in supportedUsageFlags");
485 
486 	results.check(capabilities.supportedTransforms != 0,
487 				  "At least one transform must be supported");
488 
489 	results.check(dePop32(capabilities.currentTransform) != 0,
490 				  "Invalid currentTransform");
491 
492 	results.check((capabilities.supportedTransforms & capabilities.currentTransform) != 0,
493 				  "currentTransform is not supported by surface");
494 
495 	results.check(capabilities.supportedCompositeAlpha != 0,
496 				  "At least one alpha mode must be supported");
497 }
498 
querySurfaceCapabilitiesTest(Context & context,Type wsiType)499 tcu::TestStatus querySurfaceCapabilitiesTest (Context& context, Type wsiType)
500 {
501 	tcu::TestLog&					log						= context.getTestContext().getLog();
502 	tcu::ResultCollector			results					(log);
503 
504 	const InstanceHelper			instHelper				(context, wsiType);
505 	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
506 	const Unique<VkSurfaceKHR>		surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
507 	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
508 
509 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
510 	{
511 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
512 		{
513 			const VkSurfaceCapabilitiesKHR	capabilities	= getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
514 																								   physicalDevices[deviceNdx],
515 																								   *surface);
516 
517 			log << TestLog::Message << "Device " << deviceNdx << ": " << capabilities << TestLog::EndMessage;
518 
519 			validateSurfaceCapabilities(results, capabilities);
520 		}
521 		// else skip query as surface is not supported by the device
522 	}
523 
524 	return tcu::TestStatus(results.getResult(), results.getMessage());
525 }
526 
querySurfaceCapabilities2Test(Context & context,Type wsiType)527 tcu::TestStatus querySurfaceCapabilities2Test (Context& context, Type wsiType)
528 {
529 	tcu::TestLog&					log						= context.getTestContext().getLog();
530 	tcu::ResultCollector			results					(log);
531 
532 	const InstanceHelper			instHelper				(context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
533 	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
534 	const Unique<VkSurfaceKHR>		surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
535 	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
536 
537 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
538 	{
539 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
540 		{
541 			const VkSurfaceCapabilitiesKHR	refCapabilities	= getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
542 																								   physicalDevices[deviceNdx],
543 																								   *surface);
544 			VkSurfaceCapabilities2KHR		extCapabilities;
545 
546 			deMemset(&extCapabilities, 0xcd, sizeof(VkSurfaceCapabilities2KHR));
547 			extCapabilities.sType	= VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
548 			extCapabilities.pNext	= DE_NULL;
549 
550 			{
551 				const VkPhysicalDeviceSurfaceInfo2KHR	surfaceInfo	=
552 				{
553 					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
554 					DE_NULL,
555 					*surface
556 				};
557 				VkPhysicalDeviceSurfaceInfo2KHR			infoCopy;
558 
559 				deMemcpy(&infoCopy, &surfaceInfo, sizeof(VkPhysicalDeviceSurfaceInfo2KHR));
560 
561 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(physicalDevices[deviceNdx], &surfaceInfo, &extCapabilities));
562 
563 				results.check(deMemoryEqual(&surfaceInfo, &infoCopy, sizeof(VkPhysicalDeviceSurfaceInfo2KHR)) == DE_TRUE, "Driver wrote into input struct");
564 			}
565 
566 			results.check(extCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR &&
567 						  extCapabilities.pNext == DE_NULL,
568 						  "sType/pNext modified");
569 
570 			if (refCapabilities != extCapabilities.surfaceCapabilities)
571 			{
572 				log << TestLog::Message
573 					<< "Device " << deviceNdx
574 					<< ": expected " << refCapabilities
575 					<< ", got " << extCapabilities.surfaceCapabilities
576 					<< TestLog::EndMessage;
577 				results.fail("Mismatch between VK_KHR_surface and VK_KHR_surface2 query results");
578 			}
579 		}
580 	}
581 
582 	return tcu::TestStatus(results.getResult(), results.getMessage());
583 }
584 
querySurfaceProtectedCapabilitiesTest(Context & context,Type wsiType)585 tcu::TestStatus querySurfaceProtectedCapabilitiesTest (Context& context, Type wsiType)
586 {
587 	tcu::TestLog&			log			= context.getTestContext().getLog();
588 	tcu::ResultCollector		results			(log);
589 
590 	vector<string>			requiredExtensions;
591 	requiredExtensions.push_back("VK_KHR_get_surface_capabilities2");
592 	requiredExtensions.push_back("VK_KHR_surface_protected_capabilities");
593 	const InstanceHelper		instHelper		(context, wsiType, requiredExtensions);
594 	const NativeObjects		native			(context, instHelper.supportedExtensions, wsiType);
595 	const Unique<VkSurfaceKHR>	surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
596 	const vector<VkPhysicalDevice>	physicalDevices		= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
597 
598 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
599 	{
600 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
601 		{
602 			VkSurfaceCapabilities2KHR		extCapabilities;
603 			VkSurfaceProtectedCapabilitiesKHR	extProtectedCapabilities;
604 
605 			deMemset(&extProtectedCapabilities, 0xcd, sizeof(VkSurfaceProtectedCapabilitiesKHR));
606 			extProtectedCapabilities.sType		= VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
607 			extProtectedCapabilities.pNext		= DE_NULL;
608 
609 			deMemset(&extCapabilities, 0xcd, sizeof(VkSurfaceCapabilities2KHR));
610 			extCapabilities.sType	= VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
611 			extCapabilities.pNext	= &extProtectedCapabilities;
612 
613 			{
614 				VkPhysicalDeviceSurfaceInfo2KHR		infoCopy;
615 				const VkPhysicalDeviceSurfaceInfo2KHR	surfaceInfo =
616 				{
617 					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
618 					DE_NULL,
619 					*surface
620 				};
621 
622 
623 				deMemcpy(&infoCopy, &surfaceInfo, sizeof(VkPhysicalDeviceSurfaceInfo2KHR));
624 
625 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(physicalDevices[deviceNdx], &surfaceInfo, &extCapabilities));
626 
627 				results.check(deMemoryEqual(&surfaceInfo, &infoCopy, sizeof(VkPhysicalDeviceSurfaceInfo2KHR)) == DE_TRUE, "Driver wrote into input struct");
628 			}
629 
630 			results.check(extCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR &&
631 					extCapabilities.pNext == &extProtectedCapabilities,
632 					"sType/pNext modified");
633 
634 			results.check(extProtectedCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR &&
635 					extProtectedCapabilities.pNext == DE_NULL,
636 					"sType/pNext modified");
637 
638 			results.check(extProtectedCapabilities.supportsProtected == 0 ||
639 					extProtectedCapabilities.supportsProtected == 1,
640 					"supportsProtected ");
641 		}
642 	}
643 
644 	return tcu::TestStatus(results.getResult(), results.getMessage());
645 }
646 
validateSurfaceFormats(tcu::ResultCollector & results,Type wsiType,const vector<VkSurfaceFormatKHR> & formats)647 void validateSurfaceFormats (tcu::ResultCollector& results, Type wsiType, const vector<VkSurfaceFormatKHR>& formats)
648 {
649 	const VkSurfaceFormatKHR*	requiredFormats		= DE_NULL;
650 	size_t						numRequiredFormats	= 0;
651 
652 	if (wsiType == TYPE_ANDROID)
653 	{
654 		static const VkSurfaceFormatKHR s_androidFormats[] =
655 		{
656 			{ VK_FORMAT_R8G8B8A8_UNORM,			VK_COLOR_SPACE_SRGB_NONLINEAR_KHR	},
657 			{ VK_FORMAT_R8G8B8A8_SRGB,			VK_COLOR_SPACE_SRGB_NONLINEAR_KHR	},
658 			{ VK_FORMAT_R5G6B5_UNORM_PACK16,	VK_COLOR_SPACE_SRGB_NONLINEAR_KHR	}
659 		};
660 
661 		requiredFormats		= &s_androidFormats[0];
662 		numRequiredFormats	= DE_LENGTH_OF_ARRAY(s_androidFormats);
663 	}
664 
665 	for (size_t ndx = 0; ndx < numRequiredFormats; ++ndx)
666 	{
667 		const VkSurfaceFormatKHR&	requiredFormat	= requiredFormats[ndx];
668 
669 		if (!de::contains(formats.begin(), formats.end(), requiredFormat))
670 			results.fail(de::toString(requiredFormat) + " not supported");
671 	}
672 
673 	// Check that there are no duplicates
674 	for (size_t ndx = 1; ndx < formats.size(); ++ndx)
675 	{
676 		if (de::contains(formats.begin(), formats.begin() + ndx, formats[ndx]))
677 			results.fail("Found duplicate entry " + de::toString(formats[ndx]));
678 	}
679 }
680 
querySurfaceFormatsTest(Context & context,Type wsiType)681 tcu::TestStatus querySurfaceFormatsTest (Context& context, Type wsiType)
682 {
683 	tcu::TestLog&					log				= context.getTestContext().getLog();
684 	tcu::ResultCollector			results			(log);
685 
686 	const InstanceHelper			instHelper		(context, wsiType);
687 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
688 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
689 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
690 
691 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
692 	{
693 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
694 		{
695 			deUint32	numFormats = 0;
696 
697 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, DE_NULL));
698 
699 			std::vector<VkSurfaceFormatKHR>	formats	(numFormats + 1);
700 
701 			if (numFormats > 0)
702 			{
703 				const deUint32 numFormatsOrig = numFormats;
704 
705 				// check if below call properly overwrites formats count
706 				numFormats++;
707 
708 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, &formats[0]));
709 
710 				if (numFormats != numFormatsOrig)
711 					results.fail("Format count changed between calls");
712 			}
713 
714 			formats.pop_back();
715 
716 			log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(formats.begin(), formats.end()) << TestLog::EndMessage;
717 
718 			validateSurfaceFormats(results, wsiType, formats);
719 			CheckPhysicalDeviceSurfaceFormatsIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, formats.size());
720 		}
721 		// else skip query as surface is not supported by the device
722 	}
723 
724 	return tcu::TestStatus(results.getResult(), results.getMessage());
725 }
726 
querySurfaceFormatsTestSurfaceless(Context & context,Type wsiType)727 tcu::TestStatus querySurfaceFormatsTestSurfaceless (Context& context, Type wsiType)
728 {
729 	tcu::TestLog&					log				= context.getTestContext().getLog();
730 	tcu::ResultCollector			results			(log);
731 
732 	const InstanceHelper			instHelper		(context, wsiType, vector<string>(1, string("VK_GOOGLE_surfaceless_query")));
733 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
734 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
735 	const VkSurfaceKHR				nullSurface		= 0;
736 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
737 
738 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
739 	{
740 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
741 		{
742 			deUint32	numFormatsSurface = 0;
743 			deUint32	numFormatsNull = 0;
744 
745 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormatsSurface, DE_NULL));
746 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], nullSurface, &numFormatsNull, DE_NULL));
747 
748 			if (numFormatsSurface != numFormatsNull)
749 			{
750 				results.fail("Number of formats do not match");
751 				continue;
752 			}
753 
754 			std::vector<VkSurfaceFormatKHR>	formatsSurface(numFormatsSurface + 1);
755 			std::vector<VkSurfaceFormatKHR>	formatsNull(numFormatsSurface + 1);
756 
757 			if (numFormatsSurface > 0)
758 			{
759 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormatsSurface, &formatsSurface[0]));
760 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], nullSurface, &numFormatsSurface, &formatsNull[0]));
761 			}
762 
763 			formatsSurface.pop_back();
764 			formatsNull.pop_back();
765 
766 			for (deUint32 i = 0; i < numFormatsSurface; i++)
767 			{
768 				if (formatsSurface[i].colorSpace != formatsNull[i].colorSpace ||
769 					formatsSurface[i].format     != formatsNull[i].format)
770 				{
771 					results.fail("Surface formats do not match");
772 				}
773 			}
774 		}
775 	}
776 
777 	return tcu::TestStatus(results.getResult(), results.getMessage());
778 }
779 
querySurfaceFormats2Test(Context & context,Type wsiType)780 tcu::TestStatus querySurfaceFormats2Test (Context& context, Type wsiType)
781 {
782 	tcu::TestLog&					log				= context.getTestContext().getLog();
783 	tcu::ResultCollector			results			(log);
784 
785 	const InstanceHelper			instHelper		(context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
786 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
787 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
788 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
789 
790 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
791 	{
792 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
793 		{
794 			const vector<VkSurfaceFormatKHR>		refFormats	= getPhysicalDeviceSurfaceFormats(instHelper.vki,
795 																								  physicalDevices[deviceNdx],
796 																								  *surface);
797 			const VkPhysicalDeviceSurfaceInfo2KHR	surfaceInfo	=
798 			{
799 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
800 				DE_NULL,
801 				*surface
802 			};
803 			deUint32								numFormats	= 0;
804 
805 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, DE_NULL));
806 
807 			if ((size_t)numFormats != refFormats.size())
808 				results.fail("vkGetPhysicalDeviceSurfaceFormats2KHR() returned different number of formats");
809 
810 			if (numFormats > 0)
811 			{
812 				vector<VkSurfaceFormat2KHR>	formats	(numFormats + 1);
813 
814 				for (size_t ndx = 0; ndx < formats.size(); ++ndx)
815 				{
816 					formats[ndx].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
817 					formats[ndx].pNext = DE_NULL;
818 				}
819 
820 				const deUint32 numFormatsOrig = numFormats;
821 
822 				// check if below call properly overwrites formats count
823 				numFormats++;
824 
825 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, &formats[0]));
826 
827 				if ((size_t)numFormats != numFormatsOrig)
828 					results.fail("Format count changed between calls");
829 
830 				formats.pop_back();
831 
832 				{
833 					vector<VkSurfaceFormatKHR>	extFormats	(formats.size());
834 
835 					for (size_t ndx = 0; ndx < formats.size(); ++ndx)
836 					{
837 						results.check(formats[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
838 									  formats[ndx].pNext == DE_NULL,
839 									  "sType/pNext modified");
840 						extFormats[ndx] = formats[ndx].surfaceFormat;
841 					}
842 
843 					for (size_t ndx = 0; ndx < refFormats.size(); ++ndx)
844 					{
845 						if (!de::contains(extFormats.begin(), extFormats.end(), refFormats[ndx]))
846 							results.fail(de::toString(refFormats[ndx]) + " missing from extended query");
847 					}
848 				}
849 
850 				// Check VK_INCOMPLETE
851 				{
852 					vector<VkSurfaceFormat2KHR>	formatsClone	(formats);
853 					deUint32					numToSupply		= numFormats/2;
854 					VkResult					queryResult;
855 
856 					ValidateQueryBits::fillBits(formatsClone.begin() + numToSupply, formatsClone.end());
857 
858 					queryResult = instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numToSupply, &formatsClone[0]);
859 
860 					results.check(queryResult == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
861 					results.check(ValidateQueryBits::checkBits(formatsClone.begin() + numToSupply, formatsClone.end()),
862 								  "Driver wrote past last element");
863 
864 					for (size_t ndx = 0; ndx < (size_t)numToSupply; ++ndx)
865 					{
866 						results.check(formatsClone[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
867 									  formatsClone[ndx].pNext == DE_NULL &&
868 									  formatsClone[ndx].surfaceFormat == formats[ndx].surfaceFormat,
869 									  "Returned element " + de::toString(ndx) + " is different");
870 					}
871 				}
872 			}
873 		}
874 		// else skip query as surface is not supported by the device
875 	}
876 
877 	return tcu::TestStatus(results.getResult(), results.getMessage());
878 }
879 
validateSurfacePresentModes(tcu::ResultCollector & results,Type wsiType,const vector<VkPresentModeKHR> & modes)880 void validateSurfacePresentModes (tcu::ResultCollector& results, Type wsiType, const vector<VkPresentModeKHR>& modes)
881 {
882 	results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_FIFO_KHR),
883 				  "VK_PRESENT_MODE_FIFO_KHR is not supported");
884 
885 	if (wsiType == TYPE_ANDROID)
886 		results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR),
887 					  "VK_PRESENT_MODE_MAILBOX_KHR is not supported");
888 }
889 
querySurfacePresentModes2Test(Context & context,Type wsiType)890 tcu::TestStatus querySurfacePresentModes2Test (Context& context, Type wsiType)
891 {
892 	tcu::TestLog&					log				= context.getTestContext().getLog();
893 	tcu::ResultCollector			results			(log);
894 
895 	const InstanceHelper			instHelper		(context, wsiType);
896 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
897 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
898 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
899 	const std::vector<VkExtensionProperties>	deviceExtensions(enumerateDeviceExtensionProperties(instHelper.vki, context.getPhysicalDevice(), DE_NULL));
900 	if (!isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_full_screen_exclusive")))
901 		TCU_THROW(NotSupportedError, "Extension VK_EXT_full_screen_exclusive not supported");
902 
903 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
904 	{
905 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
906 		{
907 			const VkPhysicalDeviceSurfaceInfo2KHR	surfaceInfo =
908 			{
909 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
910 				DE_NULL,
911 				*surface
912 			};
913 
914 			deUint32	numModesRef = 0;
915 			deUint32	numModes    = 0;
916 
917 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModesRef, DE_NULL));
918 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModes2EXT(physicalDevices[deviceNdx], &surfaceInfo, &numModes, DE_NULL));
919 
920 			if (numModes != numModesRef)
921 			{
922 				results.fail("Number of modes do not match");
923 				continue;
924 			}
925 
926 			vector<VkPresentModeKHR>	modes	(numModes + 1);
927 
928 			if (numModes > 0)
929 			{
930 				const deUint32 numModesOrig = numModes;
931 
932 				// check if below call properly overwrites mode count
933 				numModes++;
934 
935 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModes2EXT(physicalDevices[deviceNdx], &surfaceInfo, &numModes, &modes[0]));
936 
937 				if ((size_t)numModes != numModesOrig)
938 					TCU_FAIL("Mode count changed between calls");
939 			}
940 
941 			modes.pop_back();
942 
943 			log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(modes.begin(), modes.end()) << TestLog::EndMessage;
944 
945 			validateSurfacePresentModes(results, wsiType, modes);
946 			if (numModes > 1)
947 			{
948 				numModes /= 2;
949 				vk::VkResult res = instHelper.vki.getPhysicalDeviceSurfacePresentModes2EXT(physicalDevices[deviceNdx], &surfaceInfo, &numModes, &modes[0]);
950 				if (res != VK_INCOMPLETE)
951 					TCU_FAIL("Failed to fetch incomplete results");
952 			}
953 		}
954 		// else skip query as surface is not supported by the device
955 	}
956 
957 	return tcu::TestStatus(results.getResult(), results.getMessage());
958 }
959 
querySurfacePresentModes2TestSurfaceless(Context & context,Type wsiType)960 tcu::TestStatus querySurfacePresentModes2TestSurfaceless (Context& context, Type wsiType)
961 {
962 	tcu::TestLog&									log					= context.getTestContext().getLog();
963 	tcu::ResultCollector							results				(log);
964 
965 	const std::string								extensionName		= "VK_GOOGLE_surfaceless_query";
966 	const InstanceHelper							instHelper			(context, wsiType, vector<string>(1, extensionName), DE_NULL);
967 	const NativeObjects								native				(context, instHelper.supportedExtensions, wsiType);
968 	const Unique<VkSurfaceKHR>						surface				(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
969 	const VkSurfaceKHR								nullSurface			= 0;
970 	const vector<VkPhysicalDevice>					physicalDevices		= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
971 	const std::vector<vk::VkExtensionProperties>	deviceExtensions	(enumerateDeviceExtensionProperties(instHelper.vki, context.getPhysicalDevice(), DE_NULL));
972 	const vector<VkPresentModeKHR>					validPresentModes	{ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR };
973 
974 	if (!isExtensionStructSupported(deviceExtensions, RequiredExtension("VK_EXT_full_screen_exclusive")))
975 		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Extension VK_EXT_full_screen_exclusive not supported");
976 
977 	// Ensure "VK_GOOGLE_surfaceless_query" extension's spec version is at least 2
978 	{
979 		deUint32									propertyCount = 0u;
980 		std::vector<vk::VkExtensionProperties>		extensionsProperties;
981 		vk::VkResult								extensionResult;
982 
983 		extensionResult = context.getPlatformInterface().enumerateInstanceExtensionProperties(DE_NULL, &propertyCount, DE_NULL);
984 		if (extensionResult != vk::VK_SUCCESS)
985 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Failed to retrieve spec version for extension " + extensionName);
986 
987 		extensionsProperties.resize(propertyCount);
988 
989 		extensionResult = context.getPlatformInterface().enumerateInstanceExtensionProperties(DE_NULL, &propertyCount, extensionsProperties.data());
990 		if (extensionResult != vk::VK_SUCCESS)
991 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Failed to retrieve spec version for extension " + extensionName);
992 
993 		for (const auto& property : extensionsProperties)
994 		{
995 			if (property.extensionName == extensionName)
996 			{
997 				if (property.specVersion < 2)
998 					return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "VK_GOOGLE_surfaceless_query is version 1. Need version 2 or higher");
999 				break;
1000 			}
1001 		}
1002 	}
1003 
1004 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1005 	{
1006 		const VkPhysicalDeviceSurfaceInfo2KHR	nullSurfaceInfo =
1007 		{
1008 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
1009 			DE_NULL,
1010 			nullSurface
1011 		};
1012 		deUint32	numModesNull	= 0u;
1013 
1014 		VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModes2EXT(physicalDevices[deviceNdx], &nullSurfaceInfo, &numModesNull, DE_NULL));
1015 
1016 		if (numModesNull == 0u)
1017 			continue;
1018 
1019 		vector<VkPresentModeKHR>	modesNull(numModesNull);
1020 
1021 		VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModes2EXT(physicalDevices[deviceNdx], &nullSurfaceInfo, &numModesNull, &modesNull[0]));
1022 
1023 		for (deUint32 i = 0; i < modesNull.size(); i++)
1024 		{
1025 			if (std::find(validPresentModes.begin(), validPresentModes.end(), modesNull[i]) == validPresentModes.end())
1026 			{
1027 				std::string error_string	= std::string("Present mode mismatch with mode: ") + getPresentModeKHRName(modesNull[i]);
1028 				results.fail(error_string);
1029 				break;
1030 			}
1031 		}
1032 	}
1033 
1034 	return tcu::TestStatus(results.getResult(), results.getMessage());
1035 }
1036 
querySurfaceFormats2TestSurfaceless(Context & context,Type wsiType)1037 tcu::TestStatus querySurfaceFormats2TestSurfaceless (Context& context, Type wsiType)
1038 {
1039 	tcu::TestLog&					log				= context.getTestContext().getLog();
1040 	tcu::ResultCollector			results			(log);
1041 
1042 	const vector<std::string>		extensions		({"VK_KHR_get_surface_capabilities2", "VK_GOOGLE_surfaceless_query"});
1043 	const InstanceHelper			instHelper		(context, wsiType, extensions );
1044 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
1045 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
1046 	const VkSurfaceKHR				nullSurface		= 0;
1047 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1048 
1049 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1050 	{
1051 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1052 		{
1053 			const VkPhysicalDeviceSurfaceInfo2KHR	surfaceInfo =
1054 			{
1055 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
1056 				DE_NULL,
1057 				*surface
1058 			};
1059 			const VkPhysicalDeviceSurfaceInfo2KHR	nullSurfaceInfo =
1060 			{
1061 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
1062 				DE_NULL,
1063 				nullSurface
1064 			};
1065 			deUint32								numFormatsSurface = 0;
1066 			deUint32								numFormatsNull    = 0;
1067 
1068 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormatsSurface, DE_NULL));
1069 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &nullSurfaceInfo, &numFormatsNull, DE_NULL));
1070 
1071 			if (numFormatsSurface != numFormatsNull)
1072 			{
1073 				results.fail("Number of formats do not match");
1074 				continue;
1075 			}
1076 
1077 			if (numFormatsSurface > 0)
1078 			{
1079 				vector<VkSurfaceFormat2KHR>	formatsSurface(numFormatsSurface + 1);
1080 				vector<VkSurfaceFormat2KHR>	formatsNull(numFormatsSurface + 1);
1081 
1082 				for (size_t ndx = 0; ndx < formatsSurface.size(); ++ndx)
1083 				{
1084 					formatsSurface[ndx].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
1085 					formatsSurface[ndx].pNext = DE_NULL;
1086 					formatsNull[ndx].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
1087 					formatsNull[ndx].pNext = DE_NULL;
1088 				}
1089 
1090 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormatsSurface, &formatsSurface[0]));
1091 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &nullSurfaceInfo, &numFormatsSurface, &formatsNull[0]));
1092 
1093 				formatsSurface.pop_back();
1094 				formatsNull.pop_back();
1095 
1096 				for (deUint32 i = 0; i < numFormatsSurface; i++)
1097 				{
1098 					if (formatsSurface[i].surfaceFormat != formatsNull[i].surfaceFormat)
1099 					{
1100 						results.fail("Surface formats do not match");
1101 					}
1102 				}
1103 			}
1104 		}
1105 	}
1106 
1107 	return tcu::TestStatus(results.getResult(), results.getMessage());
1108 }
1109 
querySurfacePresentModesTest(Context & context,Type wsiType)1110 tcu::TestStatus querySurfacePresentModesTest (Context& context, Type wsiType)
1111 {
1112 	tcu::TestLog&					log				= context.getTestContext().getLog();
1113 	tcu::ResultCollector			results			(log);
1114 
1115 	const InstanceHelper			instHelper		(context, wsiType);
1116 	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType);
1117 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
1118 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1119 
1120 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1121 	{
1122 		if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1123 		{
1124 			deUint32	numModes = 0;
1125 
1126 			VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, DE_NULL));
1127 
1128 			vector<VkPresentModeKHR>	modes	(numModes + 1);
1129 
1130 			if (numModes > 0)
1131 			{
1132 				const deUint32 numModesOrig = numModes;
1133 
1134 				// check if below call properly overwrites mode count
1135 				numModes++;
1136 
1137 				VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, &modes[0]));
1138 
1139 				if ((size_t)numModes != numModesOrig)
1140 					TCU_FAIL("Mode count changed between calls");
1141 			}
1142 
1143 			modes.pop_back();
1144 
1145 			log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(modes.begin(), modes.end()) << TestLog::EndMessage;
1146 
1147 			validateSurfacePresentModes(results, wsiType, modes);
1148 			CheckPhysicalDeviceSurfacePresentModesIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, modes.size());
1149 		}
1150 		// else skip query as surface is not supported by the device
1151 	}
1152 
1153 	return tcu::TestStatus(results.getResult(), results.getMessage());
1154 }
1155 
checkDeprecatedExtensionGoogleSurfacelessQuery(const vk::InstanceDriver & vk,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,tcu::ResultCollector & result)1156 void checkDeprecatedExtensionGoogleSurfacelessQuery(const vk::InstanceDriver& vk, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, tcu::ResultCollector& result)
1157 {
1158 	const VkSurfaceKHR				nullSurface		= DE_NULL;
1159 
1160 	if (isSupportedByAnyQueue(vk, physicalDevice, surface))
1161 	{
1162 		deUint32	numModesSurface = 0;
1163 		deUint32	numModesNull	= 0;
1164 
1165 		VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModesSurface, DE_NULL));
1166 		VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, nullSurface, &numModesNull, DE_NULL));
1167 
1168 		if (numModesNull == 0)
1169 			return;
1170 
1171 		// Actual surface needs to have at least the amount of modes that null surface has
1172 		if (numModesSurface < numModesNull)
1173 		{
1174 			result.fail("Number of modes does not match");
1175 			return;
1176 		}
1177 
1178 		vector<VkPresentModeKHR>	modesSurface(numModesSurface);
1179 		vector<VkPresentModeKHR>	modesNull(numModesNull);
1180 
1181 		VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModesSurface, &modesSurface[0]));
1182 		VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, nullSurface, &numModesNull, &modesNull[0]));
1183 
1184 		// All modes present in null surface should also be present in actual surface
1185 		for (deUint32 i = 0; i < modesNull.size(); i++)
1186 		{
1187 			if (std::find(modesSurface.begin(), modesSurface.end(), modesNull[i]) == modesSurface.end())
1188 			{
1189 				std::string error_string	= std::string("Present mode mismatch with mode: ") + getPresentModeKHRName(modesNull[i]);
1190 				result.fail(error_string);
1191 				break;
1192 			}
1193 		}
1194 	}
1195 }
1196 
checkExtensionGoogleSurfacelessQuery(const vk::InstanceDriver & vk,VkPhysicalDevice physicalDevice,tcu::ResultCollector & result)1197 void checkExtensionGoogleSurfacelessQuery(const vk::InstanceDriver& vk, VkPhysicalDevice physicalDevice, tcu::ResultCollector& result)
1198 {
1199 	const VkSurfaceKHR				nullSurface		= DE_NULL;
1200 	const vector<VkPresentModeKHR>	validPresentModes	{ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR };
1201 
1202 	deUint32	numModesNull	= 0;
1203 	VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, nullSurface, &numModesNull, DE_NULL));
1204 
1205 	if (numModesNull == 0u)
1206 		return;
1207 
1208 	vector<VkPresentModeKHR>	modesNull(numModesNull);
1209 
1210 	VK_CHECK(vk.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, nullSurface, &numModesNull, &modesNull[0]));
1211 
1212 	for (deUint32 i = 0; i < modesNull.size(); i++)
1213 	{
1214 		if (std::find(validPresentModes.begin(), validPresentModes.end(), modesNull[i]) == validPresentModes.end())
1215 		{
1216 			std::string error_string	= std::string("Present mode mismatch with mode: ") + getPresentModeKHRName(modesNull[i]);
1217 			result.fail(error_string);
1218 			break;
1219 		}
1220 	}
1221 }
1222 
querySurfacePresentModesTestSurfaceless(Context & context,Type wsiType)1223 tcu::TestStatus querySurfacePresentModesTestSurfaceless (Context& context, Type wsiType)
1224 {
1225 	tcu::TestLog&					log						= context.getTestContext().getLog();
1226 	tcu::ResultCollector			results					(log);
1227 
1228 	const std::string				extensionName			= "VK_GOOGLE_surfaceless_query";
1229 	const InstanceHelper			instHelper				(context, wsiType, vector<string>(1, extensionName), DE_NULL);
1230 	const NativeObjects				native					(context, instHelper.supportedExtensions, wsiType);
1231 	const Unique<vk::VkSurfaceKHR>	surface					(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
1232 
1233 	deUint32						extensionVersion		= 1u;
1234 
1235 	// Get "VK_GOOGLE_surfaceless_query" extension's spec version
1236 	{
1237 		deUint32									propertyCount = 0u;
1238 		std::vector<vk::VkExtensionProperties>		extensionsProperties;
1239 		vk::VkResult								extensionResult;
1240 
1241 		extensionResult = context.getPlatformInterface().enumerateInstanceExtensionProperties(DE_NULL, &propertyCount, DE_NULL);
1242 		if (extensionResult != vk::VK_SUCCESS)
1243 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Failed to retrieve spec version for extension " + extensionName);
1244 
1245 		extensionsProperties.resize(propertyCount);
1246 
1247 		extensionResult = context.getPlatformInterface().enumerateInstanceExtensionProperties(DE_NULL, &propertyCount, extensionsProperties.data());
1248 		if (extensionResult != vk::VK_SUCCESS)
1249 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Failed to retrieve spec version for extension " + extensionName);
1250 
1251 		for (const auto& property : extensionsProperties)
1252 		{
1253 			if (property.extensionName == extensionName)
1254 			{
1255 				extensionVersion = property.specVersion;
1256 				break;
1257 			}
1258 		}
1259 	}
1260 
1261 	log << TestLog::Message << "Checking spec version " << extensionVersion << " for VK_GOOGLE_surfaceless_query" << TestLog::EndMessage;
1262 
1263 	const bool						checkDeprecatedVersion	= extensionVersion < 2;
1264 	const vector<VkPhysicalDevice>	physicalDevices			= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1265 	for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1266 	{
1267 		if (checkDeprecatedVersion)
1268 			checkDeprecatedExtensionGoogleSurfacelessQuery(instHelper.vki, physicalDevices[deviceNdx], *surface, results);
1269 		else
1270 			checkExtensionGoogleSurfacelessQuery(instHelper.vki, physicalDevices[deviceNdx], results);
1271 	}
1272 
1273 	return tcu::TestStatus(results.getResult(), results.getMessage());
1274 }
1275 
queryDevGroupSurfacePresentCapabilitiesTest(Context & context,Type wsiType)1276 tcu::TestStatus queryDevGroupSurfacePresentCapabilitiesTest (Context& context, Type wsiType)
1277 {
1278 	tcu::TestLog&									log						= context.getTestContext().getLog();
1279 	const InstanceHelper							instHelper				(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
1280 	const float										queuePriority			= 1.0f;
1281 	const tcu::CommandLine&							cmdLine					= context.getTestContext().getCommandLine();
1282 	const deUint32									devGroupIdx				= cmdLine.getVKDeviceGroupId() - 1;
1283 	const deUint32									deviceIdx				= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
1284 	const VkDeviceGroupPresentModeFlagsKHR			requiredFlag			= VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1285 	const VkDeviceGroupPresentModeFlagsKHR			maxValidFlag			= VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
1286 																				VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
1287 	deUint8											buffer					[sizeof(VkDeviceGroupPresentCapabilitiesKHR) + GUARD_SIZE];
1288 	deUint32										queueFamilyIndex		= 0;
1289 	VkDeviceGroupPresentCapabilitiesKHR*			presentCapabilities;
1290 	std::vector<const char*>						deviceExtensions;
1291 
1292 	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
1293 		deviceExtensions.push_back("VK_KHR_device_group");
1294 	deviceExtensions.push_back("VK_KHR_swapchain");
1295 
1296 	for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
1297 	{
1298 		if (!context.isDeviceFunctionalitySupported(deviceExtensions[ndx]))
1299 			TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
1300 	}
1301 
1302 	const vector<VkPhysicalDeviceGroupProperties>	deviceGroupProps		= enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
1303 
1304 	const std::vector<VkQueueFamilyProperties>		queueProps				= getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
1305 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
1306 	{
1307 		if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1308 			queueFamilyIndex = (deUint32)queueNdx;
1309 	}
1310 	const VkDeviceQueueCreateInfo					deviceQueueCreateInfo	=
1311 	{
1312 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,				//type
1313 		DE_NULL,												//pNext
1314 		(VkDeviceQueueCreateFlags)0u,							//flags
1315 		queueFamilyIndex,										//queueFamilyIndex;
1316 		1u,														//queueCount;
1317 		&queuePriority,											//pQueuePriorities;
1318 	};
1319 	const VkDeviceGroupDeviceCreateInfo				deviceGroupInfo			=
1320 	{
1321 		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,	//stype
1322 		DE_NULL,												//pNext
1323 		deviceGroupProps[devGroupIdx].physicalDeviceCount,		//physicalDeviceCount
1324 		deviceGroupProps[devGroupIdx].physicalDevices			//physicalDevices
1325 	};
1326 
1327 	const VkDeviceCreateInfo						deviceCreateInfo		=
1328 	{
1329 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
1330 		&deviceGroupInfo,												//pNext;
1331 		(VkDeviceCreateFlags)0u,										//flags
1332 		1,																//queueRecordCount;
1333 		&deviceQueueCreateInfo,											//pRequestedQueues;
1334 		0,																//layerCount;
1335 		DE_NULL,														//ppEnabledLayerNames;
1336 		deUint32(deviceExtensions.size()),								//enabledExtensionCount;
1337 		(deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]),	//ppEnabledExtensionNames;
1338 		DE_NULL,														//pEnabledFeatures;
1339 	};
1340 
1341 	Move<VkDevice>		deviceGroup = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
1342 	const DeviceDriver	vk	(context.getPlatformInterface(), instHelper.instance, *deviceGroup);
1343 
1344 
1345 	presentCapabilities = reinterpret_cast<VkDeviceGroupPresentCapabilitiesKHR*>(buffer);
1346 	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1347 	presentCapabilities->sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR;
1348 	presentCapabilities->pNext = DE_NULL;
1349 	VK_CHECK(vk.getDeviceGroupPresentCapabilitiesKHR(deviceGroup.get(), presentCapabilities));
1350 
1351 	// Guard check
1352 	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1353 	{
1354 		if (buffer[ndx + sizeof(VkDeviceGroupPresentCapabilitiesKHR)] != GUARD_VALUE)
1355 		{
1356 			log << TestLog::Message << "deviceGroupPresentCapabilities - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1357 			return tcu::TestStatus::fail("deviceGroupPresentCapabilities buffer overflow");
1358 		}
1359 	}
1360 
1361 	// Check each physical device can present on itself
1362 	for (size_t physDevIdx = 0; physDevIdx < VK_MAX_DEVICE_GROUP_SIZE; physDevIdx++)
1363 	{
1364 		if (presentCapabilities->presentMask[physDevIdx])
1365 			if (!((1 << physDevIdx) & (presentCapabilities->presentMask[physDevIdx])))
1366 				return tcu::TestStatus::fail("deviceGroupPresentCapabilities, device can not present on itself, invalid present mask");
1367 	}
1368 
1369 	// Check if flags are valid
1370 	if ((!(presentCapabilities->modes & requiredFlag)) ||
1371 		presentCapabilities->modes > maxValidFlag)
1372 		return tcu::TestStatus::fail("deviceGroupPresentCapabilities flag not valid");
1373 
1374 	return tcu::TestStatus::pass("Querying deviceGroup present capabilities succeeded");
1375 }
1376 
queryDevGroupSurfacePresentModesTest(Context & context,Type wsiType)1377 tcu::TestStatus queryDevGroupSurfacePresentModesTest (Context& context, Type wsiType)
1378 {
1379 	tcu::TestLog&							log					= context.getTestContext().getLog();
1380 	tcu::ResultCollector					results				(log);
1381 	const InstanceHelper					instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
1382 	const NativeObjects						native				(context, instHelper.supportedExtensions, wsiType);
1383 	const Unique<VkSurfaceKHR>				surface				(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow(), context.getTestContext().getCommandLine()));
1384 	const float								queuePriority		= 1.0f;
1385 	const tcu::CommandLine&					cmdLine				= context.getTestContext().getCommandLine();
1386 	const deUint32							devGroupIdx			= cmdLine.getVKDeviceGroupId() - 1;
1387 	const deUint32							deviceIdx			= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
1388 	const VkDeviceGroupPresentModeFlagsKHR	requiredFlag		= VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1389 	const VkDeviceGroupPresentModeFlagsKHR	maxValidFlag		= VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
1390 																	VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
1391 	VkResult								result				= VK_SUCCESS;
1392 	deUint8									buffer				[sizeof(VkDeviceGroupPresentModeFlagsKHR) + GUARD_SIZE];
1393 	deUint32								rectCount			= 0;
1394 	deUint32								incompleteRectCount	= 0;
1395 	deUint32								queueFamilyIndex	= 0;
1396 	VkRect2D*								presentRectangles;
1397 	VkDeviceGroupPresentModeFlagsKHR*		presentModeFlags;
1398 	vector<deUint8>							rectanglesBuffer;
1399 	VkPhysicalDevice						physicalDevice		= chooseDevice(instHelper.vki, instHelper.instance, cmdLine);
1400 	const Extensions&						supportedExtensions	= enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);
1401 	std::vector<const char*>				deviceExtensions;
1402 
1403 	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
1404 		deviceExtensions.push_back("VK_KHR_device_group");
1405 	deviceExtensions.push_back("VK_KHR_swapchain");
1406 
1407 	for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
1408 	{
1409 		if (!isExtensionStructSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
1410 			TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
1411 	}
1412 
1413 	const vector<VkPhysicalDeviceGroupProperties>	deviceGroupProps = enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
1414 	const std::vector<VkQueueFamilyProperties>	queueProps		= getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
1415 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
1416 	{
1417 		if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1418 			queueFamilyIndex = (deUint32)queueNdx;
1419 	}
1420 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo =
1421 	{
1422 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,					//type
1423 		DE_NULL,													//pNext
1424 		(VkDeviceQueueCreateFlags)0u,								//flags
1425 		queueFamilyIndex,											//queueFamilyIndex;
1426 		1u,															//queueCount;
1427 		&queuePriority,												//pQueuePriorities;
1428 	};
1429 	const VkDeviceGroupDeviceCreateInfo			deviceGroupInfo =
1430 	{
1431 		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,	//stype
1432 		DE_NULL,												//pNext
1433 		deviceGroupProps[devGroupIdx].physicalDeviceCount,		//physicalDeviceCount
1434 		deviceGroupProps[devGroupIdx].physicalDevices			//physicalDevices
1435 	};
1436 
1437 	const VkDeviceCreateInfo					deviceCreateInfo =
1438 	{
1439 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
1440 		&deviceGroupInfo,												//pNext;
1441 		(VkDeviceCreateFlags)0u,										//flags
1442 		1,																//queueRecordCount;
1443 		&deviceQueueCreateInfo,											//pRequestedQueues;
1444 		0,																//layerCount;
1445 		DE_NULL,														//ppEnabledLayerNames;
1446 		deUint32(deviceExtensions.size()),								//enabledExtensionCount;
1447 		(deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]),	//ppEnabledExtensionNames;
1448 		DE_NULL,														//pEnabledFeatures;
1449 	};
1450 
1451 	Move<VkDevice>		deviceGroup = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
1452 	const DeviceDriver	vk	(context.getPlatformInterface(), instHelper.instance, *deviceGroup);
1453 	presentModeFlags = reinterpret_cast<VkDeviceGroupPresentModeFlagsKHR*>(buffer);
1454 	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1455 
1456 	VK_CHECK(vk.getDeviceGroupSurfacePresentModesKHR(deviceGroup.get(), *surface, presentModeFlags));
1457 
1458 	// Guard check
1459 	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1460 	{
1461 		if (buffer[ndx + sizeof(VkDeviceGroupPresentModeFlagsKHR)] != GUARD_VALUE)
1462 		{
1463 			log << TestLog::Message << "queryDevGroupSurfacePresentModesTest - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1464 			return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest buffer overflow");
1465 		}
1466 	}
1467 
1468 	// Check if flags are valid
1469 	if ((!(*presentModeFlags & requiredFlag)) ||
1470 		*presentModeFlags > maxValidFlag)
1471 		return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest flag not valid");
1472 
1473 	// getPhysicalDevicePresentRectanglesKHR is supported only when VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR is set
1474 	if ((*presentModeFlags & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR))
1475 	{
1476 		for (size_t physDevIdx = 0; physDevIdx < deviceGroupProps[devGroupIdx].physicalDeviceCount; physDevIdx++)
1477 		{
1478 			VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, DE_NULL));
1479 			rectanglesBuffer.resize(sizeof(VkRect2D) * rectCount + GUARD_SIZE);
1480 			presentRectangles = reinterpret_cast<VkRect2D*>(rectanglesBuffer.data());
1481 			deMemset(rectanglesBuffer.data(), GUARD_VALUE, rectanglesBuffer.size());
1482 
1483 			VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, presentRectangles));
1484 
1485 			// Guard check
1486 			for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1487 			{
1488 				if (rectanglesBuffer[ndx + sizeof(VkRect2D) * rectCount] != GUARD_VALUE)
1489 				{
1490 					log << TestLog::Message << "getPhysicalDevicePresentRectanglesKHR - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1491 					return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR buffer overflow");
1492 				}
1493 			}
1494 
1495 			// Check rectangles do not overlap
1496 			for (size_t rectIdx1 = 0; rectIdx1 < rectCount; rectIdx1++)
1497 			{
1498 				for (size_t rectIdx2 = 0; rectIdx2 < rectCount; rectIdx2++)
1499 				{
1500 					if (rectIdx1 != rectIdx2)
1501 					{
1502 						deUint32 rectATop		= presentRectangles[rectIdx1].offset.y;
1503 						deUint32 rectALeft		= presentRectangles[rectIdx1].offset.x;
1504 						deUint32 rectABottom	= presentRectangles[rectIdx1].offset.y + presentRectangles[rectIdx1].extent.height;
1505 						deUint32 rectARight		= presentRectangles[rectIdx1].offset.x + presentRectangles[rectIdx1].extent.width;
1506 
1507 						deUint32 rectBTop		= presentRectangles[rectIdx2].offset.y;
1508 						deUint32 rectBLeft		= presentRectangles[rectIdx2].offset.x;
1509 						deUint32 rectBBottom	= presentRectangles[rectIdx2].offset.y + presentRectangles[rectIdx2].extent.height;
1510 						deUint32 rectBRight		= presentRectangles[rectIdx2].offset.x + presentRectangles[rectIdx2].extent.width;
1511 
1512 						if (rectALeft < rectBRight && rectARight > rectBLeft &&
1513 							rectATop < rectBBottom && rectABottom > rectBTop)
1514 							return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR rectangles overlap");
1515 					}
1516 				}
1517 			}
1518 
1519 			// Check incomplete
1520 			incompleteRectCount = rectCount / 2;
1521 			result = instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &incompleteRectCount, presentRectangles);
1522 			results.check(result == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
1523 		}
1524 	}
1525 
1526 		return tcu::TestStatus(results.getResult(), results.getMessage());
1527 }
1528 
createSurfaceInitialSizeTest(Context & context,Type wsiType)1529 tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
1530 {
1531 	tcu::TestLog&					log				= context.getTestContext().getLog();
1532 	tcu::ResultCollector			results			(log);
1533 
1534 	const InstanceHelper			instHelper		(context, wsiType);
1535 
1536 	const UniquePtr<Display>		nativeDisplay	(NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1537 																				  instHelper.supportedExtensions,
1538 																				  wsiType));
1539 
1540 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1541 	const UVec2						sizes[]			=
1542 	{
1543 		UVec2(64, 64),
1544 		UVec2(124, 119),
1545 		UVec2(256, 512)
1546 	};
1547 
1548 	DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE);
1549 
1550 	for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1551 	{
1552 		const UVec2&				testSize		= sizes[sizeNdx];
1553 		const UniquePtr<Window>		nativeWindow	(NativeObjects::createWindow(*nativeDisplay, tcu::just(testSize)));
1554 		const Unique<VkSurfaceKHR>	surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow, context.getTestContext().getCommandLine()));
1555 
1556 		for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1557 		{
1558 			if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1559 			{
1560 				const VkSurfaceCapabilitiesKHR	capabilities	= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1561 
1562 				// \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1563 				results.check(capabilities.currentExtent.width == testSize.x() &&
1564 								capabilities.currentExtent.height == testSize.y(),
1565 								"currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1566 			}
1567 		}
1568 	}
1569 
1570 	return tcu::TestStatus(results.getResult(), results.getMessage());
1571 }
1572 
resizeSurfaceTest(Context & context,Type wsiType)1573 tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
1574 {
1575 	tcu::TestLog&					log				= context.getTestContext().getLog();
1576 	tcu::ResultCollector			results			(log);
1577 
1578 	const InstanceHelper			instHelper		(context, wsiType);
1579 
1580 	const UniquePtr<Display>		nativeDisplay	(NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1581 																				  instHelper.supportedExtensions,
1582 																				  wsiType));
1583 	UniquePtr<Window>				nativeWindow	(NativeObjects::createWindow(*nativeDisplay, tcu::Nothing));
1584 
1585 	const vector<VkPhysicalDevice>	physicalDevices	= enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1586 	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow, context.getTestContext().getCommandLine()));
1587 
1588 	const UVec2						sizes[]			=
1589 	{
1590 		UVec2(64, 64),
1591 		UVec2(124, 119),
1592 		UVec2(256, 512)
1593 	};
1594 
1595 	DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_RESIZE_WINDOW);
1596 
1597 	for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1598 	{
1599 		const UVec2		testSize	= sizes[sizeNdx];
1600 
1601 		try
1602 		{
1603 			nativeWindow->resize(testSize);
1604 		}
1605 		catch (const tcu::Exception& e)
1606 		{
1607 			// Make sure all exception types result in a test failure
1608 			results.fail(e.getMessage());
1609 		}
1610 
1611 		for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1612 		{
1613 			if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1614 			{
1615 				const VkSurfaceCapabilitiesKHR	capabilities	= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1616 
1617 				// \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1618 				results.check(capabilities.currentExtent.width == testSize.x() &&
1619 								capabilities.currentExtent.height == testSize.y(),
1620 								"currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1621 			}
1622 		}
1623 	}
1624 
1625 	return tcu::TestStatus(results.getResult(), results.getMessage());
1626 }
1627 
destroyNullHandleSurfaceTest(Context & context,Type wsiType)1628 tcu::TestStatus destroyNullHandleSurfaceTest (Context& context, Type wsiType)
1629 {
1630 	const InstanceHelper	instHelper	(context, wsiType);
1631 	const VkSurfaceKHR		nullHandle	= DE_NULL;
1632 
1633 	// Default allocator
1634 	instHelper.vki.destroySurfaceKHR(instHelper.instance, nullHandle, DE_NULL);
1635 
1636 	// Custom allocator
1637 	{
1638 		AllocationCallbackRecorder	recordingAllocator	(getSystemAllocator(), 1u);
1639 
1640 		instHelper.vki.destroySurfaceKHR(instHelper.instance, nullHandle, recordingAllocator.getCallbacks());
1641 
1642 		if (recordingAllocator.getNumRecords() != 0u)
1643 			return tcu::TestStatus::fail("Implementation allocated/freed the memory");
1644 	}
1645 
1646 	return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
1647 }
1648 
1649 } // anonymous
1650 
createSurfaceTests(tcu::TestCaseGroup * testGroup,vk::wsi::Type wsiType)1651 void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1652 {
1653 	const PlatformProperties&	platformProperties	= getPlatformProperties(wsiType);
1654 
1655 	addFunctionCase(testGroup, "create",								"Create surface",											createSurfaceTest,							wsiType);
1656 	addFunctionCase(testGroup, "create_custom_allocator",				"Create surface with custom allocator",						createSurfaceCustomAllocatorTest,			wsiType);
1657 	addFunctionCase(testGroup, "create_simulate_oom",					"Create surface with simulating OOM",						createSurfaceSimulateOOMTest,				wsiType);
1658 	addFunctionCase(testGroup, "query_support",							"Query surface support",									querySurfaceSupportTest,					wsiType);
1659 	addFunctionCase(testGroup, "query_presentation_support",			"Query native presentation support",						queryPresentationSupportTest,				wsiType);
1660 	addFunctionCase(testGroup, "query_capabilities",					"Query surface capabilities",								querySurfaceCapabilitiesTest,				wsiType);
1661 	addFunctionCase(testGroup, "query_capabilities2",					"Query extended surface capabilities",						querySurfaceCapabilities2Test,				wsiType);
1662 	addFunctionCase(testGroup, "query_protected_capabilities",			"Query protected surface capabilities",						querySurfaceProtectedCapabilitiesTest,		wsiType);
1663 	addFunctionCase(testGroup, "query_surface_counters",				"Query and check available surface counters",				querySurfaceCounterTest,					wsiType);
1664 	addFunctionCase(testGroup, "query_formats",							"Query surface formats",									querySurfaceFormatsTest,					wsiType);
1665 	addFunctionCase(testGroup, "query_formats2",						"Query extended surface formats",							querySurfaceFormats2Test,					wsiType);
1666 	addFunctionCase(testGroup, "query_present_modes",					"Query surface present modes",								querySurfacePresentModesTest,				wsiType);
1667 	addFunctionCase(testGroup, "query_present_modes2",					"Query extended surface present modes",						querySurfacePresentModes2Test,				wsiType);
1668 	addFunctionCase(testGroup, "query_devgroup_present_capabilities",	"Query surface present modes capabilities in device groups",queryDevGroupSurfacePresentCapabilitiesTest,wsiType);
1669 	addFunctionCase(testGroup, "query_devgroup_present_modes",			"Query surface present modes for device groups",			queryDevGroupSurfacePresentModesTest,		wsiType);
1670 	addFunctionCase(testGroup, "destroy_null_handle",					"Destroy VK_NULL_HANDLE surface",							destroyNullHandleSurfaceTest,				wsiType);
1671 
1672 	if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
1673 		addFunctionCase(testGroup, "initial_size",	"Create surface with initial window size set",	createSurfaceInitialSizeTest,	wsiType);
1674 
1675 	if ((platformProperties.features & PlatformProperties::FEATURE_RESIZE_WINDOW) != 0)
1676 		addFunctionCase(testGroup, "resize",		"Resize window and surface",					resizeSurfaceTest,				wsiType);
1677 
1678 	addFunctionCase(testGroup, "query_formats_surfaceless", "Query surface formats without surface", querySurfaceFormatsTestSurfaceless, wsiType);
1679 	addFunctionCase(testGroup, "query_present_modes_surfaceless", "Query surface present modes without surface", querySurfacePresentModesTestSurfaceless, wsiType);
1680 	addFunctionCase(testGroup, "query_present_modes2_surfaceless", "Query extended surface present modes without surface", querySurfacePresentModes2TestSurfaceless, wsiType);
1681 	addFunctionCase(testGroup, "query_formats2_surfaceless", "Query extended surface formats without surface", querySurfaceFormats2TestSurfaceless, wsiType);
1682 }
1683 
1684 } // wsi
1685 } // vkt
1686