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